1 #ifndef keys_hh_INCLUDED
2 #define keys_hh_INCLUDED
3
4 #include "coord.hh"
5 #include "flags.hh"
6 #include "hash.hh"
7 #include "meta.hh"
8 #include "optional.hh"
9 #include "unicode.hh"
10 #include "vector.hh"
11
12 namespace Kakoune
13 {
14
15 struct Key
16 {
17 enum class MouseButton
18 {
19 Left,
20 Middle,
21 Right
22 };
23 enum class Modifiers : int
24 {
25 None = 0,
26 Control = 1 << 0,
27 Alt = 1 << 1,
28 Shift = 1 << 2,
29
30 MousePress = 1 << 3,
31 MouseRelease = 1 << 4,
32 MousePos = 1 << 5,
33 MouseButtonMask= 0b11 << 6,
34
35 Scroll = 1 << 8,
36 Resize = 1 << 9,
37 MenuSelect = 1 << 10,
38 };
39 enum NamedKey : Codepoint
40 {
41 // use UTF-16 surrogate pairs range
42 Backspace = 0xD800,
43 Delete,
44 Escape,
45 Return,
46 Up,
47 Down,
48 Left,
49 Right,
50 PageUp,
51 PageDown,
52 Home,
53 End,
54 Insert,
55 Tab,
56 F1,
57 F2,
58 F3,
59 F4,
60 F5,
61 F6,
62 F7,
63 F8,
64 F9,
65 F10,
66 F11,
67 F12,
68 FocusIn,
69 FocusOut,
70 Invalid,
71 };
72
73 Modifiers modifiers = {};
74 Codepoint key = {};
75
KeyKakoune::Key76 constexpr Key(Modifiers modifiers, Codepoint key)
77 : modifiers(modifiers), key(key) {}
78
KeyKakoune::Key79 constexpr Key(Codepoint key)
80 : modifiers(Modifiers::None), key(key) {}
81
82 constexpr Key() = default;
83
valKakoune::Key84 constexpr uint64_t val() const { return (uint64_t)modifiers << 32 | key; }
85
operator ==Kakoune::Key86 constexpr bool operator==(Key other) const { return val() == other.val(); }
operator !=Kakoune::Key87 constexpr bool operator!=(Key other) const { return val() != other.val(); }
operator <Kakoune::Key88 constexpr bool operator<(Key other) const { return val() < other.val(); }
89
coordKakoune::Key90 constexpr DisplayCoord coord() const { return {(int)((key & 0xFFFF0000) >> 16), (int)(key & 0x0000FFFF)}; }
mouse_buttonKakoune::Key91 constexpr MouseButton mouse_button() { return MouseButton{((int)modifiers & (int)Modifiers::MouseButtonMask) >> 6}; }
to_modifierKakoune::Key92 static Modifiers to_modifier(MouseButton button) { return Key::Modifiers{((int)button << 6) & (int)Modifiers::MouseButtonMask}; }
93
94 Optional<Codepoint> codepoint() const;
95 };
96
with_bit_ops(Meta::Type<Key::Modifiers>)97 constexpr bool with_bit_ops(Meta::Type<Key::Modifiers>) { return true; }
98
99 using KeyList = Vector<Key, MemoryDomain::Mapping>;
100
101 class String;
102 class StringView;
103
104 KeyList parse_keys(StringView str);
105 String key_to_str(Key key);
106 StringView button_to_str(Key::MouseButton button);
107 Key::MouseButton str_to_button(StringView str);
108
shift(Key key)109 constexpr Key shift(Key key)
110 {
111 return { key.modifiers | Key::Modifiers::Shift, key.key };
112 }
alt(Key key)113 constexpr Key alt(Key key)
114 {
115 return { key.modifiers | Key::Modifiers::Alt, key.key };
116 }
ctrl(Key key)117 constexpr Key ctrl(Key key)
118 {
119 return { key.modifiers | Key::Modifiers::Control, key.key };
120 }
121
encode_coord(DisplayCoord coord)122 constexpr Codepoint encode_coord(DisplayCoord coord) { return (Codepoint)(((int)coord.line << 16) | ((int)coord.column & 0x0000FFFF)); }
123
resize(DisplayCoord dim)124 constexpr Key resize(DisplayCoord dim) { return { Key::Modifiers::Resize, encode_coord(dim) }; }
125
hash_value(const Key & key)126 constexpr size_t hash_value(const Key& key) { return hash_values(key.modifiers, key.key); }
127
128 }
129
130 #endif // keys_hh_INCLUDED
131