mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:07:34 +00:00
LibLine: Make (almost) all key actions configurable
This moves all internal functions to a new file, and defines the old keybinds with register_key_input_callback().
This commit is contained in:
parent
d0aab41628
commit
32839d40e3
4 changed files with 653 additions and 464 deletions
|
@ -34,6 +34,7 @@
|
|||
#include <AK/QuickSort.h>
|
||||
#include <AK/Result.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/Traits.h>
|
||||
#include <AK/Utf32View.h>
|
||||
#include <AK/Utf8View.h>
|
||||
#include <AK/Vector.h>
|
||||
|
@ -84,6 +85,70 @@ struct Configuration {
|
|||
OperationMode operation_mode { OperationMode::Unset };
|
||||
};
|
||||
|
||||
struct Key {
|
||||
enum Modifier : int {
|
||||
None = 0,
|
||||
Alt = 1,
|
||||
};
|
||||
|
||||
int modifiers { None };
|
||||
unsigned key { 0 };
|
||||
|
||||
Key(unsigned c)
|
||||
: modifiers(None)
|
||||
, key(c) {};
|
||||
|
||||
Key(unsigned c, int modifiers)
|
||||
: modifiers(modifiers)
|
||||
, key(c)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(const Key& other) const
|
||||
{
|
||||
return other.key == key && other.modifiers == modifiers;
|
||||
}
|
||||
};
|
||||
|
||||
struct KeyBinding {
|
||||
Key key;
|
||||
enum class Kind {
|
||||
InternalFunction,
|
||||
Insertion,
|
||||
} kind { Kind::InternalFunction };
|
||||
String binding;
|
||||
};
|
||||
|
||||
#define ENUMERATE_EDITOR_INTERNAL_FUNCTIONS(M) \
|
||||
M(clear_screen) \
|
||||
M(cursor_left_character) \
|
||||
M(cursor_left_word) \
|
||||
M(cursor_right_character) \
|
||||
M(cursor_right_word) \
|
||||
M(enter_search) \
|
||||
M(erase_character_backwards) \
|
||||
M(erase_character_forwards) \
|
||||
M(erase_to_beginning) \
|
||||
M(erase_to_end) \
|
||||
M(erase_word_backwards) \
|
||||
M(finish_edit) \
|
||||
M(go_end) \
|
||||
M(go_home) \
|
||||
M(kill_line) \
|
||||
M(search_backwards) \
|
||||
M(search_forwards) \
|
||||
M(transpose_characters) \
|
||||
M(transpose_words) \
|
||||
M(insert_last_words) \
|
||||
M(erase_alnum_word_backwards) \
|
||||
M(erase_alnum_word_forwards) \
|
||||
M(capitalize_word) \
|
||||
M(lowercase_word) \
|
||||
M(uppercase_word)
|
||||
|
||||
#define EDITOR_INTERNAL_FUNCTION(name) \
|
||||
[](auto& editor) { editor.name(); return false; }
|
||||
|
||||
class Editor : public Core::Object {
|
||||
C_OBJECT(Editor);
|
||||
|
||||
|
@ -103,7 +168,9 @@ public:
|
|||
void add_to_history(const String&);
|
||||
const Vector<String>& history() const { return m_history; }
|
||||
|
||||
void register_character_input_callback(char ch, Function<bool(Editor&)> callback);
|
||||
void register_key_input_callback(const KeyBinding&);
|
||||
void register_key_input_callback(Key, Function<bool(Editor&)> callback);
|
||||
|
||||
StringMetrics actual_rendered_string_metrics(const StringView&) const;
|
||||
StringMetrics actual_rendered_string_metrics(const Utf32View&) const;
|
||||
|
||||
|
@ -111,6 +178,20 @@ public:
|
|||
Function<void()> on_interrupt_handled;
|
||||
Function<void(Editor&)> on_display_refresh;
|
||||
|
||||
static Function<bool(Editor&)> find_internal_function(const StringView& name);
|
||||
enum class CaseChangeOp {
|
||||
Lowercase,
|
||||
Uppercase,
|
||||
Capital,
|
||||
};
|
||||
void case_change_word(CaseChangeOp);
|
||||
#define __ENUMERATE_EDITOR_INTERNAL_FUNCTION(name) \
|
||||
void name();
|
||||
|
||||
ENUMERATE_EDITOR_INTERNAL_FUNCTIONS(__ENUMERATE_EDITOR_INTERNAL_FUNCTION)
|
||||
|
||||
#undef __ENUMERATE_EDITOR_INTERNAL_FUNCTION
|
||||
|
||||
// FIXME: we will have to kindly ask our instantiators to set our signal handlers,
|
||||
// since we can not do this cleanly ourselves. (signal() limitation: cannot give member functions)
|
||||
void interrupted()
|
||||
|
@ -182,6 +263,8 @@ public:
|
|||
private:
|
||||
explicit Editor(Configuration configuration = Configuration::from_config());
|
||||
|
||||
void set_default_keybinds();
|
||||
|
||||
enum VTState {
|
||||
Free = 1,
|
||||
Escape = 3,
|
||||
|
@ -364,7 +447,7 @@ private:
|
|||
};
|
||||
TabDirection m_tab_direction { TabDirection::Forward };
|
||||
|
||||
HashMap<char, NonnullOwnPtr<KeyCallback>> m_key_callbacks;
|
||||
HashMap<Key, NonnullOwnPtr<KeyCallback>> m_key_callbacks;
|
||||
|
||||
// TODO: handle signals internally.
|
||||
struct termios m_termios {
|
||||
|
@ -404,3 +487,13 @@ private:
|
|||
};
|
||||
|
||||
}
|
||||
|
||||
namespace AK {
|
||||
|
||||
template<>
|
||||
struct Traits<Line::Key> : public GenericTraits<Line::Key> {
|
||||
static constexpr bool is_trivial() { return true; }
|
||||
static unsigned hash(Line::Key k) { return pair_int_hash(k.key, k.modifiers); }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue