diff options
author | AnotherTest <ali.mpfard@gmail.com> | 2020-05-26 19:52:01 +0430 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-26 21:09:59 +0200 |
commit | 8b3eb4535dc0cc7ee7fef73315a8537f0cb915d7 (patch) | |
tree | fcc057311be754ab6ce4a65467c82890e84d5645 /Libraries/LibLine/Editor.cpp | |
parent | e4760e5b42776e473fd7d387d140a34551842d2f (diff) | |
download | serenity-8b3eb4535dc0cc7ee7fef73315a8537f0cb915d7.zip |
LibLine: Use LibC's getline() when the terminal claims no support for escape sequences
We just look at $TERM and refuse to emit any escape sequences if it
doesn't start with "xterm".
This could be made much better, at detecting, and at not caling
getline().
Diffstat (limited to 'Libraries/LibLine/Editor.cpp')
-rw-r--r-- | Libraries/LibLine/Editor.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/Libraries/LibLine/Editor.cpp b/Libraries/LibLine/Editor.cpp index bb11476717..2b38e7fa11 100644 --- a/Libraries/LibLine/Editor.cpp +++ b/Libraries/LibLine/Editor.cpp @@ -226,11 +226,53 @@ void Editor::suggest(size_t invariant_offset, size_t static_offset, Span::Mode o m_suggestion_manager.set_suggestion_variants(internal_static_offset, internal_invariant_offset, 0); } +void Editor::initialize() +{ + if (m_initialized) + return; + + struct termios termios; + tcgetattr(0, &termios); + m_default_termios = termios; // grab a copy to restore + + auto* term = getenv("TERM"); + if (StringView { term }.starts_with("xterm")) + m_configuration.set(Configuration::Full); + else + m_configuration.set(Configuration::NoEscapeSequences); + + // Because we use our own line discipline which includes echoing, + // we disable ICANON and ECHO. + if (m_configuration.operation_mode == Configuration::Full) { + termios.c_lflag &= ~(ECHO | ICANON); + tcsetattr(0, TCSANOW, &termios); + } + + m_termios = termios; + m_initialized = true; +} + Result<String, Editor::Error> Editor::get_line(const String& prompt) { initialize(); m_is_editing = true; + if (m_configuration.operation_mode == Configuration::NoEscapeSequences) { + // Do not use escape sequences, instead, use LibC's getline. + size_t size = 0; + char* line = nullptr; + fputs(prompt.characters(), stderr); + size_t line_length = getline(&line, &size, stdin); + restore(); + if (line) { + String result { line, line_length, Chomp }; + free(line); + return result; + } + + return Error::ReadFailure; + } + set_prompt(prompt); reset(); set_origin(); |