From 055afafedca4c3294569e2e7cc6343777218b1a7 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 9 Jun 2014 16:50:01 -0400 Subject: [PATCH 1/6] command-prompt: Basic line editing Left/right arrows, Ctrl-A, Ctrl-E --- plugins/command-prompt.cpp | 56 ++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/plugins/command-prompt.cpp b/plugins/command-prompt.cpp index 3cdd83ab3..140cc6f4d 100644 --- a/plugins/command-prompt.cpp +++ b/plugins/command-prompt.cpp @@ -17,6 +17,7 @@ #include "df/ui.h" #include "df/graphic.h" #include "df/enabler.h" + using namespace DFHack; using namespace df::enums; @@ -50,6 +51,7 @@ public: { show_fps=df::global::gps->display_frames; df::global::gps->display_frames=0; + cursor_pos = 0; } ~viewscreen_commandpromptst() { @@ -67,8 +69,10 @@ public: } protected: std::list > responses; + int cursor_pos; bool is_response; bool show_fps; + int frame; void submit(); std::string entry; }; @@ -82,6 +86,9 @@ void prompt_ostream::flush_proxy() } void viewscreen_commandpromptst::render() { + ++frame; + if (frame >= df::global::enabler->gfps) + frame = 0; if (Screen::isDismissed(this)) return; @@ -103,12 +110,22 @@ void viewscreen_commandpromptst::render() { Screen::fillRect(Screen::Pen(' ', 7, 0),0,0,dim.x,0); Screen::paintString(Screen::Pen(' ', 7, 0), 0, 0,"[DFHack]#"); - if(entry.size()gfps / 2) ? "_" : " "; + if(cursor_pos < (dim.x - 10)) + { Screen::paintString(Screen::Pen(' ', 7, 0), 10,0 , entry); + if (entry.size() > dim.x - 10) + Screen::paintTile(Screen::Pen('\032', 7, 0), dim.x - 1, 0); + if (cursor != " ") + Screen::paintString(Screen::Pen(' ', 10, 0), 10 + cursor_pos, 0, cursor); + } else { - Screen::paintTile(Screen::Pen('>', 7, 0), 9, 0); - Screen::paintString(Screen::Pen(' ', 7, 0), 10, 0, entry.substr(entry.size()-dim.x)); + size_t start = cursor_pos - dim.x + 10 + 1; + Screen::paintTile(Screen::Pen('\033', 7, 0), 9, 0); + Screen::paintString(Screen::Pen(' ', 7, 0), 10, 0, entry.substr(start)); + if (cursor != " ") + Screen::paintString(Screen::Pen(' ', 10, 0), dim.x - 1, 0, cursor); } } } @@ -158,14 +175,41 @@ void viewscreen_commandpromptst::feed(std::set *events) auto key = *it; if (key==interface_key::STRING_A000) //delete? { - if(entry.size()) - entry.resize(entry.size()-1); + if(entry.size() && cursor_pos > 0) + { + entry.erase(cursor_pos - 1, 1); + cursor_pos--; + } + if(cursor_pos > entry.size()) + cursor_pos = entry.size(); continue; } if (key >= interface_key::STRING_A000 && key <= interface_key::STRING_A255) { - entry.push_back(char(key - interface_key::STRING_A000)); + entry.insert(cursor_pos, 1, char(key - interface_key::STRING_A000)); + cursor_pos++; + } + // Prevent number keys from moving cursor + else if(events->count(interface_key::CURSOR_RIGHT)) + { + cursor_pos++; + if (cursor_pos > entry.size()) cursor_pos = entry.size(); + break; + } + else if(events->count(interface_key::CURSOR_LEFT)) + { + cursor_pos--; + if (cursor_pos < 0) cursor_pos = 0; + break; + } + else if(events->count(interface_key::CUSTOM_CTRL_A)) + { + cursor_pos = 0; + } + else if(events->count(interface_key::CUSTOM_CTRL_E)) + { + cursor_pos = entry.size(); } } } From aafcd6c43aff79e5939960f7f0d8a0ca47b7796b Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 9 Jun 2014 17:00:26 -0400 Subject: [PATCH 2/6] Fix 4/6 behavior --- plugins/command-prompt.cpp | 41 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/plugins/command-prompt.cpp b/plugins/command-prompt.cpp index 140cc6f4d..c4bbd615d 100644 --- a/plugins/command-prompt.cpp +++ b/plugins/command-prompt.cpp @@ -189,28 +189,27 @@ void viewscreen_commandpromptst::feed(std::set *events) { entry.insert(cursor_pos, 1, char(key - interface_key::STRING_A000)); cursor_pos++; + return; } - // Prevent number keys from moving cursor - else if(events->count(interface_key::CURSOR_RIGHT)) - { - cursor_pos++; - if (cursor_pos > entry.size()) cursor_pos = entry.size(); - break; - } - else if(events->count(interface_key::CURSOR_LEFT)) - { - cursor_pos--; - if (cursor_pos < 0) cursor_pos = 0; - break; - } - else if(events->count(interface_key::CUSTOM_CTRL_A)) - { - cursor_pos = 0; - } - else if(events->count(interface_key::CUSTOM_CTRL_E)) - { - cursor_pos = entry.size(); - } + } + // Prevent number keys from moving cursor + if(events->count(interface_key::CURSOR_RIGHT)) + { + cursor_pos++; + if (cursor_pos > entry.size()) cursor_pos = entry.size(); + } + else if(events->count(interface_key::CURSOR_LEFT)) + { + cursor_pos--; + if (cursor_pos < 0) cursor_pos = 0; + } + else if(events->count(interface_key::CUSTOM_CTRL_A)) + { + cursor_pos = 0; + } + else if(events->count(interface_key::CUSTOM_CTRL_E)) + { + cursor_pos = entry.size(); } } DFHACK_PLUGIN("command-prompt"); From cc07a373f3b48918060da2800e83d4f37eeb34a5 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 9 Jun 2014 19:38:21 -0400 Subject: [PATCH 3/6] Command-prompt history Creates duplicate entries occasionally Also disabled movies --- plugins/command-prompt.cpp | 45 +++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/plugins/command-prompt.cpp b/plugins/command-prompt.cpp index c4bbd615d..345eee603 100644 --- a/plugins/command-prompt.cpp +++ b/plugins/command-prompt.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include "df/interface_key.h" #include "df/ui.h" @@ -25,6 +26,8 @@ using df::global::ui; using df::global::gps; using df::global::enabler; +std::vector command_history; + class viewscreen_commandpromptst; class prompt_ostream:public buffered_color_ostream { @@ -47,11 +50,15 @@ public: void help() { } std::string getFocusString() { return "commandprompt"; } + int8_t movies_okay() { return 0; } viewscreen_commandpromptst(std::string entry):is_response(false),entry(entry) { show_fps=df::global::gps->display_frames; df::global::gps->display_frames=0; cursor_pos = 0; + frame = 0; + history_idx = command_history.size(); + command_history.push_back(""); } ~viewscreen_commandpromptst() { @@ -70,6 +77,7 @@ public: protected: std::list > responses; int cursor_pos; + int history_idx; bool is_response; bool show_fps; int frame; @@ -140,6 +148,8 @@ void viewscreen_commandpromptst::submit() //color_ostream_proxy out(Core::getInstance().getConsole()); prompt_ostream out(this); Core::getInstance().runCommand(out, entry); + command_history.pop_back(); + command_history.push_back(entry); if(out.empty() && responses.empty()) Screen::dismiss(this); else @@ -149,7 +159,7 @@ void viewscreen_commandpromptst::submit() } void viewscreen_commandpromptst::feed(std::set *events) { - + int old_pos = cursor_pos; bool leave_all = events->count(interface_key::LEAVESCREEN_ALL); if (leave_all || events->count(interface_key::LEAVESCREEN)) { @@ -196,12 +206,14 @@ void viewscreen_commandpromptst::feed(std::set *events) if(events->count(interface_key::CURSOR_RIGHT)) { cursor_pos++; - if (cursor_pos > entry.size()) cursor_pos = entry.size(); + if (cursor_pos > entry.size()) + cursor_pos = entry.size(); } else if(events->count(interface_key::CURSOR_LEFT)) { cursor_pos--; - if (cursor_pos < 0) cursor_pos = 0; + if (cursor_pos < 0) + cursor_pos = 0; } else if(events->count(interface_key::CUSTOM_CTRL_A)) { @@ -211,6 +223,32 @@ void viewscreen_commandpromptst::feed(std::set *events) { cursor_pos = entry.size(); } + else if(events->count(interface_key::CURSOR_UP)) + { + if (command_history.back() == "") + { + command_history.pop_back(); + command_history.push_back(entry); + } + history_idx--; + if (history_idx < 0) + history_idx = 0; + entry = command_history[history_idx]; + cursor_pos = entry.size(); + } + else if(events->count(interface_key::CURSOR_DOWN)) + { + if (history_idx < command_history.size() - 1) + { + history_idx++; + if (history_idx >= command_history.size()) + history_idx = command_history.size() - 1; + entry = command_history[history_idx]; + cursor_pos = entry.size(); + } + } + if (old_pos != cursor_pos) + frame = 0; } DFHACK_PLUGIN("command-prompt"); command_result show_prompt(color_ostream &out, std::vector & parameters) @@ -235,6 +273,7 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector Date: Tue, 17 Jun 2014 12:34:57 -0400 Subject: [PATCH 4/6] Remove (broken) command history This reverts commit cc07a373f3b48918060da2800e83d4f37eeb34a5. --- plugins/command-prompt.cpp | 42 ++++---------------------------------- 1 file changed, 4 insertions(+), 38 deletions(-) diff --git a/plugins/command-prompt.cpp b/plugins/command-prompt.cpp index 345eee603..5815af59b 100644 --- a/plugins/command-prompt.cpp +++ b/plugins/command-prompt.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include "df/interface_key.h" #include "df/ui.h" @@ -26,8 +25,6 @@ using df::global::ui; using df::global::gps; using df::global::enabler; -std::vector command_history; - class viewscreen_commandpromptst; class prompt_ostream:public buffered_color_ostream { @@ -48,17 +45,15 @@ public: void render(); void help() { } + int8_t movies_okay() { return 0; } std::string getFocusString() { return "commandprompt"; } - int8_t movies_okay() { return 0; } viewscreen_commandpromptst(std::string entry):is_response(false),entry(entry) { show_fps=df::global::gps->display_frames; df::global::gps->display_frames=0; cursor_pos = 0; frame = 0; - history_idx = command_history.size(); - command_history.push_back(""); } ~viewscreen_commandpromptst() { @@ -77,7 +72,6 @@ public: protected: std::list > responses; int cursor_pos; - int history_idx; bool is_response; bool show_fps; int frame; @@ -148,8 +142,6 @@ void viewscreen_commandpromptst::submit() //color_ostream_proxy out(Core::getInstance().getConsole()); prompt_ostream out(this); Core::getInstance().runCommand(out, entry); - command_history.pop_back(); - command_history.push_back(entry); if(out.empty() && responses.empty()) Screen::dismiss(this); else @@ -173,12 +165,12 @@ void viewscreen_commandpromptst::feed(std::set *events) } return; } - if(events->count(interface_key::SELECT)) + if (events->count(interface_key::SELECT)) { submit(); return; } - if(is_response) + if (is_response) return; for (auto it = events->begin(); it != events->end(); ++it) { @@ -212,8 +204,7 @@ void viewscreen_commandpromptst::feed(std::set *events) else if(events->count(interface_key::CURSOR_LEFT)) { cursor_pos--; - if (cursor_pos < 0) - cursor_pos = 0; + if (cursor_pos < 0) cursor_pos = 0; } else if(events->count(interface_key::CUSTOM_CTRL_A)) { @@ -223,30 +214,6 @@ void viewscreen_commandpromptst::feed(std::set *events) { cursor_pos = entry.size(); } - else if(events->count(interface_key::CURSOR_UP)) - { - if (command_history.back() == "") - { - command_history.pop_back(); - command_history.push_back(entry); - } - history_idx--; - if (history_idx < 0) - history_idx = 0; - entry = command_history[history_idx]; - cursor_pos = entry.size(); - } - else if(events->count(interface_key::CURSOR_DOWN)) - { - if (history_idx < command_history.size() - 1) - { - history_idx++; - if (history_idx >= command_history.size()) - history_idx = command_history.size() - 1; - entry = command_history[history_idx]; - cursor_pos = entry.size(); - } - } if (old_pos != cursor_pos) frame = 0; } @@ -273,7 +240,6 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector Date: Tue, 17 Jun 2014 16:49:43 -0400 Subject: [PATCH 5/6] Reimplement command-prompt history Also add shift-left/right for back/forward one word --- plugins/command-prompt.cpp | 80 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 4 deletions(-) diff --git a/plugins/command-prompt.cpp b/plugins/command-prompt.cpp index 5815af59b..44f55b5e0 100644 --- a/plugins/command-prompt.cpp +++ b/plugins/command-prompt.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include "df/interface_key.h" #include "df/ui.h" @@ -25,6 +26,8 @@ using df::global::ui; using df::global::gps; using df::global::enabler; +std::vector command_history; + class viewscreen_commandpromptst; class prompt_ostream:public buffered_color_ostream { @@ -48,12 +51,14 @@ public: int8_t movies_okay() { return 0; } std::string getFocusString() { return "commandprompt"; } - viewscreen_commandpromptst(std::string entry):is_response(false),entry(entry) + viewscreen_commandpromptst(std::string entry):is_response(false) { show_fps=df::global::gps->display_frames; df::global::gps->display_frames=0; cursor_pos = 0; frame = 0; + history_idx = command_history.size(); + command_history.push_back(entry); } ~viewscreen_commandpromptst() { @@ -69,14 +74,50 @@ public: responses.push_back(std::make_pair(v, part + '\n')); } } + std::string get_entry() + { + return command_history[history_idx]; + } + void set_entry(std::string entry) + { + command_history[history_idx] = entry; + } + void back_word() + { + std::string entry = get_entry(); + if (cursor_pos == 0) + return; + cursor_pos--; + while (cursor_pos > 0 && !isalnum(entry[cursor_pos])) + cursor_pos--; + while (cursor_pos > 0 && isalnum(entry[cursor_pos])) + cursor_pos--; + if (!isalnum(entry[cursor_pos]) && cursor_pos != 0) + cursor_pos++; + } + void forward_word() + { + std::string entry = get_entry(); + int len = entry.size(); + if (cursor_pos == len) + return; + cursor_pos++; + while (cursor_pos <= len && !isalnum(entry[cursor_pos])) + cursor_pos++; + while (cursor_pos <= len && isalnum(entry[cursor_pos])) + cursor_pos++; + if (cursor_pos > len) + cursor_pos = len; + } + protected: std::list > responses; int cursor_pos; + int history_idx; bool is_response; bool show_fps; int frame; void submit(); - std::string entry; }; void prompt_ostream::flush_proxy() { @@ -110,6 +151,7 @@ void viewscreen_commandpromptst::render() } else { + std::string entry = get_entry(); Screen::fillRect(Screen::Pen(' ', 7, 0),0,0,dim.x,0); Screen::paintString(Screen::Pen(' ', 7, 0), 0, 0,"[DFHack]#"); std::string cursor = (frame < df::global::enabler->gfps / 2) ? "_" : " "; @@ -139,9 +181,8 @@ void viewscreen_commandpromptst::submit() Screen::dismiss(this); return; } - //color_ostream_proxy out(Core::getInstance().getConsole()); prompt_ostream out(this); - Core::getInstance().runCommand(out, entry); + Core::getInstance().runCommand(out, get_entry()); if(out.empty() && responses.empty()) Screen::dismiss(this); else @@ -152,6 +193,7 @@ void viewscreen_commandpromptst::submit() void viewscreen_commandpromptst::feed(std::set *events) { int old_pos = cursor_pos; + std::string entry = get_entry(); bool leave_all = events->count(interface_key::LEAVESCREEN_ALL); if (leave_all || events->count(interface_key::LEAVESCREEN)) { @@ -191,6 +233,7 @@ void viewscreen_commandpromptst::feed(std::set *events) { entry.insert(cursor_pos, 1, char(key - interface_key::STRING_A000)); cursor_pos++; + set_entry(entry); return; } } @@ -206,6 +249,14 @@ void viewscreen_commandpromptst::feed(std::set *events) cursor_pos--; if (cursor_pos < 0) cursor_pos = 0; } + else if(events->count(interface_key::CURSOR_RIGHT_FAST)) + { + forward_word(); + } + else if(events->count(interface_key::CURSOR_LEFT_FAST)) + { + back_word(); + } else if(events->count(interface_key::CUSTOM_CTRL_A)) { cursor_pos = 0; @@ -214,8 +265,29 @@ void viewscreen_commandpromptst::feed(std::set *events) { cursor_pos = entry.size(); } + else if(events->count(interface_key::CURSOR_UP)) + { + history_idx--; + if (history_idx < 0) + history_idx = 0; + entry = get_entry(); + cursor_pos = entry.size(); + } + else if(events->count(interface_key::CURSOR_DOWN)) + { + if (history_idx < command_history.size() - 1) + { + history_idx++; + if (history_idx >= command_history.size()) + history_idx = command_history.size() - 1; + entry = get_entry(); + cursor_pos = entry.size(); + } + } + set_entry(entry); if (old_pos != cursor_pos) frame = 0; + } DFHACK_PLUGIN("command-prompt"); command_result show_prompt(color_ostream &out, std::vector & parameters) From cca605d8b4ae0fe8826b7ed30f73f3ceface2b81 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 17 Jun 2014 17:21:30 -0400 Subject: [PATCH 6/6] Prevent blank lines from being stored in history --- plugins/command-prompt.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plugins/command-prompt.cpp b/plugins/command-prompt.cpp index 44f55b5e0..f9a3f80bf 100644 --- a/plugins/command-prompt.cpp +++ b/plugins/command-prompt.cpp @@ -58,6 +58,14 @@ public: cursor_pos = 0; frame = 0; history_idx = command_history.size(); + if (history_idx > 0) + { + if (command_history[history_idx - 1] == "") + { + command_history.pop_back(); + history_idx--; + } + } command_history.push_back(entry); } ~viewscreen_commandpromptst() @@ -205,6 +213,8 @@ void viewscreen_commandpromptst::feed(std::set *events) parent->feed(events); events->clear(); } + //if (command_history.size() && !entry.size()) + // command_history.pop_back(); return; } if (events->count(interface_key::SELECT))