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:
parent
54d400c685
commit
f9b0490383
1 changed files with 41 additions and 3 deletions
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue