summaryrefslogtreecommitdiff
path: root/Libraries/LibLine/Editor.cpp
diff options
context:
space:
mode:
authorAnotherTest <ali.mpfard@gmail.com>2020-05-26 19:52:01 +0430
committerAndreas Kling <kling@serenityos.org>2020-05-26 21:09:59 +0200
commit8b3eb4535dc0cc7ee7fef73315a8537f0cb915d7 (patch)
treefcc057311be754ab6ce4a65467c82890e84d5645 /Libraries/LibLine/Editor.cpp
parente4760e5b42776e473fd7d387d140a34551842d2f (diff)
downloadserenity-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.cpp42
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();