diff --git a/Libraries/LibLine/Editor.cpp b/Libraries/LibLine/Editor.cpp index 0e4b8203ea1..f5d26d15d7b 100644 --- a/Libraries/LibLine/Editor.cpp +++ b/Libraries/LibLine/Editor.cpp @@ -25,6 +25,7 @@ */ #include "Editor.h" +#include #include #include #include @@ -71,6 +72,52 @@ Configuration Configuration::from_config(const StringView& libname) else configuration.set(Configuration::OperationMode::Unset); + // Read keybinds. + + for (auto& binding_key : config_file->keys("keybinds")) { + GenericLexer key_lexer(binding_key); + auto has_ctrl = false; + auto alt = false; + unsigned key = 0; + + while (!key && !key_lexer.is_eof()) { + if (key_lexer.next_is("alt+")) { + alt = key_lexer.consume_specific("alt+"); + continue; + } + if (key_lexer.next_is("^[")) { + alt = key_lexer.consume_specific("^["); + continue; + } + if (key_lexer.next_is("^")) { + has_ctrl = key_lexer.consume_specific("^"); + continue; + } + if (key_lexer.next_is("ctrl+")) { + has_ctrl = key_lexer.consume_specific("ctrl+"); + continue; + } + // FIXME: Support utf? + key = key_lexer.consume(); + } + + if (has_ctrl) + key = ctrl(key); + + auto value = config_file->read_entry("keybinds", binding_key); + if (value.starts_with("internal:")) { + configuration.set(KeyBinding { + Key { key, alt ? Key::Alt : Key::None }, + KeyBinding::Kind::InternalFunction, + value.substring(9, value.length() - 9) }); + } else { + configuration.set(KeyBinding { + Key { key, alt ? Key::Alt : Key::None }, + KeyBinding::Kind::Insertion, + value }); + } + } + return configuration; } @@ -118,6 +165,9 @@ Editor::Editor(Configuration configuration) m_suggestion_display = make(m_num_lines, m_num_columns); set_default_keybinds(); + + for (auto& keybind : m_configuration.keybindings) + register_key_input_callback(keybind); } Editor::~Editor() diff --git a/Libraries/LibLine/Editor.h b/Libraries/LibLine/Editor.h index a23a5cc5e0d..42c6f5dcff1 100644 --- a/Libraries/LibLine/Editor.h +++ b/Libraries/LibLine/Editor.h @@ -53,38 +53,6 @@ namespace Line { -struct Configuration { - enum RefreshBehaviour { - Lazy, - Eager, - }; - enum OperationMode { - Unset, - Full, - NoEscapeSequences, - NonInteractive, - }; - - Configuration() - { - } - - template - Configuration(Arg arg, Rest... rest) - : Configuration(rest...) - { - set(arg); - } - - void set(RefreshBehaviour refresh) { refresh_behaviour = refresh; } - void set(OperationMode mode) { operation_mode = mode; } - - static Configuration from_config(const StringView& libname = "line"); - - RefreshBehaviour refresh_behaviour { RefreshBehaviour::Lazy }; - OperationMode operation_mode { OperationMode::Unset }; -}; - struct Key { enum Modifier : int { None = 0, @@ -119,6 +87,40 @@ struct KeyBinding { String binding; }; +struct Configuration { + enum RefreshBehaviour { + Lazy, + Eager, + }; + enum OperationMode { + Unset, + Full, + NoEscapeSequences, + NonInteractive, + }; + + Configuration() + { + } + + template + Configuration(Arg arg, Rest... rest) + : Configuration(rest...) + { + set(arg); + } + + void set(RefreshBehaviour refresh) { refresh_behaviour = refresh; } + void set(OperationMode mode) { operation_mode = mode; } + void set(const KeyBinding& binding) { keybindings.append(binding); } + + static Configuration from_config(const StringView& libname = "line"); + + RefreshBehaviour refresh_behaviour { RefreshBehaviour::Lazy }; + OperationMode operation_mode { OperationMode::Unset }; + Vector keybindings; +}; + #define ENUMERATE_EDITOR_INTERNAL_FUNCTIONS(M) \ M(clear_screen) \ M(cursor_left_character) \