mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-23 17:52:26 -05:00
LibLine: Check if operating on a TTY before using TTY features
This makes the line editor behave well when input is passed in from pipes as well.
This commit is contained in:
parent
a7ea7b3a66
commit
70eb7aa627
Notes:
sideshowbarker
2024-07-19 04:15:58 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/70eb7aa6277 Pull-request: https://github.com/SerenityOS/serenity/pull/2995 Issue: https://github.com/SerenityOS/serenity/issues/2989 Reviewed-by: https://github.com/awesomekling
2 changed files with 36 additions and 13 deletions
|
@ -250,11 +250,18 @@ void Editor::initialize()
|
|||
if (m_was_resized)
|
||||
get_terminal_size();
|
||||
|
||||
auto* term = getenv("TERM");
|
||||
if (StringView { term }.starts_with("xterm"))
|
||||
m_configuration.set(Configuration::Full);
|
||||
else
|
||||
m_configuration.set(Configuration::NoEscapeSequences);
|
||||
if (m_configuration.operation_mode == Configuration::Unset) {
|
||||
auto istty = isatty(STDIN_FILENO) && isatty(STDOUT_FILENO);
|
||||
if (!istty) {
|
||||
m_configuration.set(Configuration::NonInteractive);
|
||||
} else {
|
||||
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.
|
||||
|
@ -272,15 +279,26 @@ auto Editor::get_line(const String& prompt) -> Result<String, Editor::Error>
|
|||
initialize();
|
||||
m_is_editing = true;
|
||||
|
||||
if (m_configuration.operation_mode == Configuration::NoEscapeSequences) {
|
||||
if (m_configuration.operation_mode == Configuration::NoEscapeSequences || m_configuration.operation_mode == Configuration::NonInteractive) {
|
||||
// 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);
|
||||
// Show the prompt only on interactive mode (NoEscapeSequences in this case).
|
||||
if (m_configuration.operation_mode != Configuration::NonInteractive)
|
||||
fputs(prompt.characters(), stderr);
|
||||
auto line_length = getline(&line, &size, stdin);
|
||||
// getline() returns -1 and sets errno=0 on EOF.
|
||||
if (line_length == -1) {
|
||||
if (line)
|
||||
free(line);
|
||||
if (errno == 0)
|
||||
return Error::Eof;
|
||||
|
||||
return Error::ReadFailure;
|
||||
}
|
||||
restore();
|
||||
if (line) {
|
||||
String result { line, line_length, Chomp };
|
||||
String result { line, (size_t)line_length, Chomp };
|
||||
free(line);
|
||||
return result;
|
||||
}
|
||||
|
@ -429,7 +447,10 @@ void Editor::handle_read_event()
|
|||
Utf8View input_view { StringView { m_incomplete_data.data(), valid_bytes } };
|
||||
size_t consumed_code_pointss = 0;
|
||||
|
||||
enum Amount { Character, Word };
|
||||
enum Amount {
|
||||
Character,
|
||||
Word,
|
||||
};
|
||||
auto do_cursor_left = [&](Amount amount) {
|
||||
if (m_cursor > 0) {
|
||||
if (amount == Word) {
|
||||
|
@ -565,12 +586,12 @@ void Editor::handle_read_event()
|
|||
ctrl_held = false;
|
||||
continue;
|
||||
case 'D': // left
|
||||
do_cursor_left(ctrl_held ? Word : Character);
|
||||
do_cursor_left(ctrl_held ? Word : Character);
|
||||
m_state = InputState::Free;
|
||||
ctrl_held = false;
|
||||
continue;
|
||||
case 'C': // right
|
||||
do_cursor_right(ctrl_held ? Word : Character);
|
||||
do_cursor_right(ctrl_held ? Word : Character);
|
||||
m_state = InputState::Free;
|
||||
ctrl_held = false;
|
||||
continue;
|
||||
|
|
|
@ -61,8 +61,10 @@ struct Configuration {
|
|||
Eager,
|
||||
};
|
||||
enum OperationMode {
|
||||
Unset,
|
||||
Full,
|
||||
NoEscapeSequences,
|
||||
NonInteractive,
|
||||
};
|
||||
|
||||
Configuration()
|
||||
|
@ -82,7 +84,7 @@ struct Configuration {
|
|||
|
||||
RefreshBehaviour refresh_behaviour { RefreshBehaviour::Lazy };
|
||||
TokenSplitMechanism split_mechanism { TokenSplitMechanism::Spaces };
|
||||
OperationMode operation_mode { OperationMode::Full };
|
||||
OperationMode operation_mode { OperationMode::Unset };
|
||||
};
|
||||
|
||||
class Editor : public Core::Object {
|
||||
|
|
Loading…
Add table
Reference in a new issue