diff --git a/library/Console-darwin.cpp b/library/Console-darwin.cpp index 86cd657a1..f36973d5c 100644 --- a/library/Console-darwin.cpp +++ b/library/Console-darwin.cpp @@ -305,6 +305,33 @@ namespace DFHack } /// beep. maybe? //void beep (void); + void back_word() + { + if (raw_cursor == 0) + return; + raw_cursor--; + while (raw_cursor > 0 && !isalnum(raw_buffer[raw_cursor])) + raw_cursor--; + while (raw_cursor > 0 && isalnum(raw_buffer[raw_cursor])) + raw_cursor--; + if (!isalnum(raw_buffer[raw_cursor]) && raw_cursor != 0) + raw_cursor++; + prompt_refresh(); + } + void forward_word() + { + int len = raw_buffer.size(); + if (raw_cursor == len) + return; + raw_cursor++; + while (raw_cursor <= len && !isalnum(raw_buffer[raw_cursor])) + raw_cursor++; + while (raw_cursor <= len && isalnum(raw_buffer[raw_cursor])) + raw_cursor++; + if (raw_cursor > len) + raw_cursor = len; + prompt_refresh(); + } /// A simple line edit (raw mode) int lineedit(const std::string& prompt, std::string& output, recursive_mutex * lock, CommandHistory & ch) { @@ -478,14 +505,27 @@ namespace DFHack break; case 27: // escape sequence lock->unlock(); - if(!read_char(seq[0]) || !read_char(seq[1])) + if (!read_char(seq[0])) { lock->lock(); return -2; } lock->lock(); - if(seq[0] == '[') + if (seq[0] == 'b') { + back_word(); + } + else if (seq[0] == 'f') + { + forward_word(); + } + else if(seq[0] == '[') + { + if (!read_char(seq[1])) + { + lock->lock(); + return -2; + } if (seq[1] == 'D') { left_arrow: @@ -545,6 +585,7 @@ namespace DFHack else if (seq[1] > '0' && seq[1] < '7') { // extended escape + unsigned char seq3[3]; lock->unlock(); if(!read_char(seq2)) { @@ -561,6 +602,24 @@ namespace DFHack prompt_refresh(); } } + if (!read_char(seq3[0]) || !read_char(seq3[1])) + { + lock->lock(); + return -2; + } + if (seq2 == ';') + { + // Format: esc [ n ; n DIRECTION + // Ignore first character (second "n") + if (seq3[1] == 'C') + { + forward_word(); + } + else if (seq3[1] == 'D') + { + back_word(); + } + } } } break; diff --git a/library/Console-linux.cpp b/library/Console-linux.cpp index f32fa1c2a..d4005af3c 100644 --- a/library/Console-linux.cpp +++ b/library/Console-linux.cpp @@ -307,6 +307,33 @@ namespace DFHack } /// beep. maybe? //void beep (void); + void back_word() + { + if (raw_cursor == 0) + return; + raw_cursor--; + while (raw_cursor > 0 && !isalnum(raw_buffer[raw_cursor])) + raw_cursor--; + while (raw_cursor > 0 && isalnum(raw_buffer[raw_cursor])) + raw_cursor--; + if (!isalnum(raw_buffer[raw_cursor]) && raw_cursor != 0) + raw_cursor++; + prompt_refresh(); + } + void forward_word() + { + int len = raw_buffer.size(); + if (raw_cursor == len) + return; + raw_cursor++; + while (raw_cursor <= len && !isalnum(raw_buffer[raw_cursor])) + raw_cursor++; + while (raw_cursor <= len && isalnum(raw_buffer[raw_cursor])) + raw_cursor++; + if (raw_cursor > len) + raw_cursor = len; + prompt_refresh(); + } /// A simple line edit (raw mode) int lineedit(const std::string& prompt, std::string& output, recursive_mutex * lock, CommandHistory & ch) { @@ -480,14 +507,27 @@ namespace DFHack break; case 27: // escape sequence lock->unlock(); - if(!read_char(seq[0]) || !read_char(seq[1])) + if (!read_char(seq[0])) { lock->lock(); return -2; } lock->lock(); - if(seq[0] == '[') + if (seq[0] == 'b') { + back_word(); + } + else if (seq[0] == 'f') + { + forward_word(); + } + else if(seq[0] == '[') + { + if (!read_char(seq[1])) + { + lock->lock(); + return -2; + } if (seq[1] == 'D') { left_arrow: @@ -547,6 +587,7 @@ namespace DFHack else if (seq[1] > '0' && seq[1] < '7') { // extended escape + unsigned char seq3[3]; lock->unlock(); if(!read_char(seq2)) { @@ -563,6 +604,24 @@ namespace DFHack prompt_refresh(); } } + if (!read_char(seq3[0]) || !read_char(seq3[1])) + { + lock->lock(); + return -2; + } + if (seq2 == ';') + { + // Format: esc [ n ; n DIRECTION + // Ignore first character (second "n") + if (seq3[1] == 'C') + { + forward_word(); + } + else if (seq3[1] == 'D') + { + back_word(); + } + } } } break;