mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 12:05:15 +00:00
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().
This commit is contained in:
parent
e4760e5b42
commit
8b3eb4535d
Notes:
sideshowbarker
2024-07-19 06:06:19 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/8b3eb4535dc Pull-request: https://github.com/SerenityOS/serenity/pull/2400 Reviewed-by: https://github.com/bugaevc
2 changed files with 49 additions and 15 deletions
|
@ -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();
|
||||
|
|
|
@ -57,6 +57,10 @@ struct Configuration {
|
|||
Lazy,
|
||||
Eager,
|
||||
};
|
||||
enum OperationMode {
|
||||
Full,
|
||||
NoEscapeSequences,
|
||||
};
|
||||
|
||||
Configuration()
|
||||
{
|
||||
|
@ -71,9 +75,11 @@ struct Configuration {
|
|||
|
||||
void set(RefreshBehaviour refresh) { refresh_behaviour = refresh; }
|
||||
void set(TokenSplitMechanism split) { split_mechanism = split; }
|
||||
void set(OperationMode mode) { operation_mode = mode; }
|
||||
|
||||
RefreshBehaviour refresh_behaviour { RefreshBehaviour::Lazy };
|
||||
TokenSplitMechanism split_mechanism { TokenSplitMechanism::Spaces };
|
||||
OperationMode operation_mode { OperationMode::Full };
|
||||
};
|
||||
|
||||
class Editor {
|
||||
|
@ -89,21 +95,7 @@ public:
|
|||
|
||||
Result<String, Error> get_line(const String& prompt);
|
||||
|
||||
void initialize()
|
||||
{
|
||||
if (m_initialized)
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
void initialize();
|
||||
|
||||
void add_to_history(const String&);
|
||||
const Vector<String>& history() const { return m_history; }
|
||||
|
|
Loading…
Add table
Reference in a new issue