Skip to content

Commit

Permalink
Shell: Support basic line editing with left/right arrow keys.
Browse files Browse the repository at this point in the history
  • Loading branch information
awesomekling committed May 7, 2019
1 parent 8750f93 commit d53941a
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 6 deletions.
42 changes: 37 additions & 5 deletions Shell/LineEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,21 @@ void LineEditor::clear_line()
fputc(0x8, stdout);
fflush(stdout);
m_buffer.clear();
m_cursor = 0;
}

void LineEditor::append(const String& string)
{
m_buffer.append(string.characters(), string.length());
fputs(string.characters(), stdout);
fflush(stdout);
m_cursor = m_buffer.size();
}

String LineEditor::get_line()
{
m_history_cursor = m_history.size();
m_cursor = 0;
for (;;) {
char keybuf[16];
ssize_t nread = read(0, keybuf, sizeof(keybuf));
Expand Down Expand Up @@ -92,9 +95,19 @@ String LineEditor::get_line()
m_state = InputState::Free;
continue;
case 'D': // left
if (m_cursor > 0) {
--m_cursor;
fputs("\033[D", stdout);
fflush(stdout);
}
m_state = InputState::Free;
continue;
case 'C': // right
if (m_cursor < m_buffer.size()) {
++m_cursor;
fputs("\033[C", stdout);
fflush(stdout);
}
m_state = InputState::Free;
continue;
default:
Expand All @@ -117,10 +130,16 @@ String LineEditor::get_line()
}

if (ch == 8 || ch == g.termios.c_cc[VERASE]) {
if (m_buffer.is_empty())
if (m_cursor == 0)
continue;
m_buffer.take_last();
m_buffer.remove(m_cursor - 1);
--m_cursor;
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);
continue;
}
Expand Down Expand Up @@ -150,13 +169,26 @@ String LineEditor::get_line()
}
putchar(ch);
fflush(stdout);
if (ch != '\n') {
m_buffer.append(ch);
} else {
if (ch == '\n') {
auto string = String::copy(m_buffer);
m_buffer.clear();
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;

}
}
}
2 changes: 1 addition & 1 deletion Shell/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ static int run_command(const String& cmd)

int rc = execvp(argv[0], const_cast<char* const*>(argv.data()));
if (rc < 0) {
perror("execvp");
fprintf(stderr, "execvp(%s): %s\n", argv[0], strerror(errno));
exit(1);
}
ASSERT_NOT_REACHED();
Expand Down

0 comments on commit d53941a

Please sign in to comment.