mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 22:07:34 +00:00
Shell: Support basic line editing with left/right arrow keys.
This commit is contained in:
parent
8750f93201
commit
d53941a466
2 changed files with 38 additions and 6 deletions
|
@ -25,6 +25,7 @@ void LineEditor::clear_line()
|
||||||
fputc(0x8, stdout);
|
fputc(0x8, stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
m_buffer.clear();
|
m_buffer.clear();
|
||||||
|
m_cursor = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LineEditor::append(const String& string)
|
void LineEditor::append(const String& string)
|
||||||
|
@ -32,11 +33,13 @@ void LineEditor::append(const String& string)
|
||||||
m_buffer.append(string.characters(), string.length());
|
m_buffer.append(string.characters(), string.length());
|
||||||
fputs(string.characters(), stdout);
|
fputs(string.characters(), stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
m_cursor = m_buffer.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
String LineEditor::get_line()
|
String LineEditor::get_line()
|
||||||
{
|
{
|
||||||
m_history_cursor = m_history.size();
|
m_history_cursor = m_history.size();
|
||||||
|
m_cursor = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char keybuf[16];
|
char keybuf[16];
|
||||||
ssize_t nread = read(0, keybuf, sizeof(keybuf));
|
ssize_t nread = read(0, keybuf, sizeof(keybuf));
|
||||||
|
@ -92,9 +95,19 @@ String LineEditor::get_line()
|
||||||
m_state = InputState::Free;
|
m_state = InputState::Free;
|
||||||
continue;
|
continue;
|
||||||
case 'D': // left
|
case 'D': // left
|
||||||
|
if (m_cursor > 0) {
|
||||||
|
--m_cursor;
|
||||||
|
fputs("\033[D", stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
m_state = InputState::Free;
|
m_state = InputState::Free;
|
||||||
continue;
|
continue;
|
||||||
case 'C': // right
|
case 'C': // right
|
||||||
|
if (m_cursor < m_buffer.size()) {
|
||||||
|
++m_cursor;
|
||||||
|
fputs("\033[C", stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
m_state = InputState::Free;
|
m_state = InputState::Free;
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
|
@ -117,10 +130,16 @@ String LineEditor::get_line()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch == 8 || ch == g.termios.c_cc[VERASE]) {
|
if (ch == 8 || ch == g.termios.c_cc[VERASE]) {
|
||||||
if (m_buffer.is_empty())
|
if (m_cursor == 0)
|
||||||
continue;
|
continue;
|
||||||
m_buffer.take_last();
|
m_buffer.remove(m_cursor - 1);
|
||||||
|
--m_cursor;
|
||||||
putchar(8);
|
putchar(8);
|
||||||
|
fputs("\033[s", stdout);
|
||||||
|
fputs("\033[K", stdout);
|
||||||
|
for (int i = m_cursor; i < m_buffer.size(); ++i)
|
||||||
|
fputc(m_buffer[i], stdout);
|
||||||
|
fputs("\033[u", stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -150,13 +169,26 @@ String LineEditor::get_line()
|
||||||
}
|
}
|
||||||
putchar(ch);
|
putchar(ch);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
if (ch != '\n') {
|
if (ch == '\n') {
|
||||||
m_buffer.append(ch);
|
|
||||||
} else {
|
|
||||||
auto string = String::copy(m_buffer);
|
auto string = String::copy(m_buffer);
|
||||||
m_buffer.clear();
|
m_buffer.clear();
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_cursor == m_buffer.size()) {
|
||||||
|
m_buffer.append(ch);
|
||||||
|
++m_cursor;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
fputs("\033[s", stdout);
|
||||||
|
fputs("\033[K", stdout);
|
||||||
|
for (int i = m_cursor; i < m_buffer.size(); ++i)
|
||||||
|
fputc(m_buffer[i], stdout);
|
||||||
|
fputs("\033[u", stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
m_buffer.insert(m_cursor, move(ch));
|
||||||
|
++m_cursor;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -295,7 +295,7 @@ static int run_command(const String& cmd)
|
||||||
|
|
||||||
int rc = execvp(argv[0], const_cast<char* const*>(argv.data()));
|
int rc = execvp(argv[0], const_cast<char* const*>(argv.data()));
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
perror("execvp");
|
fprintf(stderr, "execvp(%s): %s\n", argv[0], strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue