From 0c144b821de9d5fe25c5e45d596583a5a7e4f74a Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 17 Jun 2014 16:49:43 -0400 Subject: [PATCH] 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)