diff options
author | AnotherTest <ali.mpfard@gmail.com> | 2020-04-20 22:05:03 +0430 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-04-20 20:23:26 +0200 |
commit | f9b0490383bc1bb20b3c739b62810ac03e21ac99 (patch) | |
tree | 3410e0e682baafe9702c10514b733ef6ee26882a /Libraries/LibLine/Editor.cpp | |
parent | 54d400c685c59a327b66ce9c74796106ab3704de (diff) | |
download | serenity-f9b0490383bc1bb20b3c739b62810ac03e21ac99.zip |
LibLine: Handle ctrl-{left,right}_arrow by jumping between words
Words are delimited by spaces.
Perhaps this should be a configurable behaviour?
Diffstat (limited to 'Libraries/LibLine/Editor.cpp')
-rw-r--r-- | Libraries/LibLine/Editor.cpp | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/Libraries/LibLine/Editor.cpp b/Libraries/LibLine/Editor.cpp index 59aedab999..e5ac5fec78 100644 --- a/Libraries/LibLine/Editor.cpp +++ b/Libraries/LibLine/Editor.cpp @@ -181,6 +181,7 @@ String Editor::get_line(const String& prompt) m_next_suggestion_index = m_suggestions.size(); m_next_suggestion_index--; }; + auto ctrl_held = false; for (ssize_t i = 0; i < nread; ++i) { char ch = keybuf[i]; if (ch == 0) @@ -197,6 +198,9 @@ String Editor::get_line(const String& prompt) } case InputState::ExpectFinal: switch (ch) { + case 'O': // mod_ctrl + ctrl_held = true; + continue; case 'A': // up { m_searching_backwards = true; @@ -209,6 +213,7 @@ String Editor::get_line(const String& prompt) } m_inline_search_cursor = inline_search_cursor; m_state = InputState::Free; + ctrl_held = false; continue; } case 'B': // down @@ -231,38 +236,69 @@ String Editor::get_line(const String& prompt) } m_inline_search_cursor = inline_search_cursor; m_state = InputState::Free; + ctrl_held = false; continue; } case 'D': // left if (m_cursor > 0) { - --m_cursor; + if (ctrl_held) { + auto skipped_at_least_one_character = false; + for (;;) { + if (m_cursor == 0) + break; + if (skipped_at_least_one_character && isspace(m_buffer[m_cursor - 1])) // stop *after* a space, but only if it changes the position + break; + skipped_at_least_one_character = true; + --m_cursor; + } + } else { + --m_cursor; + } } m_inline_search_cursor = m_cursor; m_state = InputState::Free; + ctrl_held = false; continue; case 'C': // right if (m_cursor < m_buffer.size()) { - ++m_cursor; + if (ctrl_held) { + // temporarily put a space at the end of our buffer + // this greatly simplifies the logic below + m_buffer.append(' '); + for (;;) { + if (m_cursor >= m_buffer.size()) + break; + if (isspace(m_buffer[++m_cursor])) + break; + } + m_buffer.take_last(); + } else { + ++m_cursor; + } } m_inline_search_cursor = m_cursor; m_search_offset = 0; m_state = InputState::Free; + ctrl_held = false; continue; case 'H': m_cursor = 0; m_inline_search_cursor = m_cursor; m_search_offset = 0; m_state = InputState::Free; + ctrl_held = false; continue; case 'F': m_cursor = m_buffer.size(); m_state = InputState::Free; m_inline_search_cursor = m_cursor; m_search_offset = 0; + ctrl_held = false; continue; case 'Z': // shift+tab reverse_tab = true; m_state = InputState::Free; + ctrl_held = false; break; case '3': if (m_cursor == m_buffer.size()) { @@ -274,10 +310,12 @@ String Editor::get_line(const String& prompt) m_refresh_needed = true; m_search_offset = 0; m_state = InputState::ExpectTerminator; + ctrl_held = false; continue; default: - dbgprintf("Shell: Unhandled final: %02x (%c)\n", ch, ch); + dbgprintf("Shell: Unhandled final: %02x (%c)\r\n", ch, ch); m_state = InputState::Free; + ctrl_held = false; continue; } break; |