From 6f407fff321652592d4d96cc3c9976ef6ed70e0b Mon Sep 17 00:00:00 2001 From: AnotherTest Date: Mon, 30 Mar 2020 22:42:50 +0430 Subject: [PATCH] LibLineEdit + Shell: Handle Termios internally and give a copy if asked This moves the Termios logic inside LibLineEdit and allows users to simply forget about the existence of termios if they so choose to :^) --- Libraries/LibLineEdit/LineEditor.cpp | 12 +++--------- Libraries/LibLineEdit/LineEditor.h | 15 ++++++++++++--- Shell/main.cpp | 11 ++++------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Libraries/LibLineEdit/LineEditor.cpp b/Libraries/LibLineEdit/LineEditor.cpp index e632168b21..574b3dc221 100644 --- a/Libraries/LibLineEdit/LineEditor.cpp +++ b/Libraries/LibLineEdit/LineEditor.cpp @@ -30,9 +30,7 @@ #include #include -LineEditor::LineEditor(struct termios termios) - : m_termios(termios) - , m_initialized(true) +LineEditor::LineEditor() { struct winsize ws; if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) @@ -41,13 +39,9 @@ LineEditor::LineEditor(struct termios termios) m_num_columns = ws.ws_col; } -LineEditor::LineEditor() - : LineEditor(termios {}) -{ -} - LineEditor::~LineEditor() { + tcsetattr(0, TCSANOW, &m_default_termios); } void LineEditor::add_to_history(const String& line) @@ -378,7 +372,7 @@ String LineEditor::get_line(const String& prompt) do_backspace(); continue; } - if (ch == 0xc) { // ^L + if (ch == 0xc) { // ^L printf("\033[3J\033[H\033[2J"); // Clear screen. fputs(prompt.characters(), stdout); for (size_t i = 0; i < m_buffer.size(); ++i) diff --git a/Libraries/LibLineEdit/LineEditor.h b/Libraries/LibLineEdit/LineEditor.h index 437d024e43..8f969658f8 100644 --- a/Libraries/LibLineEdit/LineEditor.h +++ b/Libraries/LibLineEdit/LineEditor.h @@ -50,13 +50,19 @@ struct KeyCallback { class LineEditor { public: - LineEditor(struct termios); LineEditor(); ~LineEditor(); - void initialize(struct termios termios) + void initialize() { ASSERT(!m_initialized); + struct termios termios; + tcgetattr(0, &termios); + m_default_termios = termios; // grab a copy to restore + // Because we use our own line discipline which includes echoing, + // we disable ICANON and ECHO. + termios.c_lflag &= ~(ECHO | ICANON); + tcsetattr(0, TCSANOW, &termios); m_termios = termios; m_initialized = true; } @@ -85,6 +91,9 @@ public: void insert(const char); void cut_mismatching_chars(String& completion, const String& other, size_t start_compare); + const struct termios& termios() const { return m_termios; } + const struct termios& default_termios() const { return m_default_termios; } + private: void vt_save_cursor(); void vt_restore_cursor(); @@ -98,7 +107,7 @@ private: HashMap> m_key_callbacks; // TODO: handle signals internally - struct termios m_termios; + struct termios m_termios, m_default_termios; bool m_was_interrupted = false; bool m_was_resized = false; diff --git a/Shell/main.cpp b/Shell/main.cpp index acdf9df612..83f2a997ba 100644 --- a/Shell/main.cpp +++ b/Shell/main.cpp @@ -1031,14 +1031,11 @@ int main(int argc, char** argv) g.uid = getuid(); tcsetpgrp(0, getpgrp()); - tcgetattr(0, &g.default_termios); - g.termios = g.default_termios; - // Because we use our own line discipline which includes echoing, - // we disable ICANON and ECHO. - g.termios.c_lflag &= ~(ECHO | ICANON); - tcsetattr(0, TCSANOW, &g.termios); - editor.initialize(g.termios); + editor.initialize(); + g.termios = editor.termios(); + g.default_termios = editor.default_termios(); + editor.on_tab_complete_first_token = [&](const String& token) -> Vector { auto match = binary_search(cached_path.data(), cached_path.size(), token, [](const String& token, const String& program) -> int { return strncmp(token.characters(), program.characters(), token.length());