1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 02:47:34 +00:00

LibLine: Handle ctrl-{left,right}_arrow by jumping between words

Words are delimited by spaces.
Perhaps this should be a configurable behaviour?
This commit is contained in:
AnotherTest 2020-04-20 22:05:03 +04:30 committed by Andreas Kling
parent 54d400c685
commit f9b0490383

View file

@ -181,6 +181,7 @@ String Editor::get_line(const String& prompt)
m_next_suggestion_index = m_suggestions.size(); m_next_suggestion_index = m_suggestions.size();
m_next_suggestion_index--; m_next_suggestion_index--;
}; };
auto ctrl_held = false;
for (ssize_t i = 0; i < nread; ++i) { for (ssize_t i = 0; i < nread; ++i) {
char ch = keybuf[i]; char ch = keybuf[i];
if (ch == 0) if (ch == 0)
@ -197,6 +198,9 @@ String Editor::get_line(const String& prompt)
} }
case InputState::ExpectFinal: case InputState::ExpectFinal:
switch (ch) { switch (ch) {
case 'O': // mod_ctrl
ctrl_held = true;
continue;
case 'A': // up case 'A': // up
{ {
m_searching_backwards = true; m_searching_backwards = true;
@ -209,6 +213,7 @@ String Editor::get_line(const String& prompt)
} }
m_inline_search_cursor = inline_search_cursor; m_inline_search_cursor = inline_search_cursor;
m_state = InputState::Free; m_state = InputState::Free;
ctrl_held = false;
continue; continue;
} }
case 'B': // down case 'B': // down
@ -231,38 +236,69 @@ String Editor::get_line(const String& prompt)
} }
m_inline_search_cursor = inline_search_cursor; m_inline_search_cursor = inline_search_cursor;
m_state = InputState::Free; m_state = InputState::Free;
ctrl_held = false;
continue; continue;
} }
case 'D': // left case 'D': // left
if (m_cursor > 0) { 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_inline_search_cursor = m_cursor;
m_state = InputState::Free; m_state = InputState::Free;
ctrl_held = false;
continue; continue;
case 'C': // right case 'C': // right
if (m_cursor < m_buffer.size()) { 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_inline_search_cursor = m_cursor;
m_search_offset = 0; m_search_offset = 0;
m_state = InputState::Free; m_state = InputState::Free;
ctrl_held = false;
continue; continue;
case 'H': case 'H':
m_cursor = 0; m_cursor = 0;
m_inline_search_cursor = m_cursor; m_inline_search_cursor = m_cursor;
m_search_offset = 0; m_search_offset = 0;
m_state = InputState::Free; m_state = InputState::Free;
ctrl_held = false;
continue; continue;
case 'F': case 'F':
m_cursor = m_buffer.size(); m_cursor = m_buffer.size();
m_state = InputState::Free; m_state = InputState::Free;
m_inline_search_cursor = m_cursor; m_inline_search_cursor = m_cursor;
m_search_offset = 0; m_search_offset = 0;
ctrl_held = false;
continue; continue;
case 'Z': // shift+tab case 'Z': // shift+tab
reverse_tab = true; reverse_tab = true;
m_state = InputState::Free; m_state = InputState::Free;
ctrl_held = false;
break; break;
case '3': case '3':
if (m_cursor == m_buffer.size()) { if (m_cursor == m_buffer.size()) {
@ -274,10 +310,12 @@ String Editor::get_line(const String& prompt)
m_refresh_needed = true; m_refresh_needed = true;
m_search_offset = 0; m_search_offset = 0;
m_state = InputState::ExpectTerminator; m_state = InputState::ExpectTerminator;
ctrl_held = false;
continue; continue;
default: default:
dbgprintf("Shell: Unhandled final: %02x (%c)\n", ch, ch); dbgprintf("Shell: Unhandled final: %02x (%c)\r\n", ch, ch);
m_state = InputState::Free; m_state = InputState::Free;
ctrl_held = false;
continue; continue;
} }
break; break;