-
Notifications
You must be signed in to change notification settings - Fork 710
/
input_handler.hh
217 lines (177 loc) · 5.72 KB
/
input_handler.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#ifndef input_handler_hh_INCLUDED
#define input_handler_hh_INCLUDED
#include "completion.hh"
#include "array.hh"
#include "context.hh"
#include "env_vars.hh"
#include "enum.hh"
#include "face.hh"
#include "normal.hh"
#include "optional.hh"
#include "keys.hh"
#include "string.hh"
#include "utils.hh"
#include "safe_ptr.hh"
#include "display_buffer.hh"
#include "event_manager.hh"
namespace Kakoune
{
enum class PromptEvent
{
Change,
Abort,
Validate
};
using PromptCallback = std::function<void (StringView, PromptEvent, Context&)>;
enum class PromptFlags
{
None = 0,
Password = 1 << 0,
DropHistoryEntriesWithBlankPrefix = 1 << 1,
Search = 1 << 2,
};
constexpr bool with_bit_ops(Meta::Type<PromptFlags>) { return true; }
using KeyCallback = std::function<void (Key, Context&)>;
class InputMode;
enum class KeymapMode : char;
enum class CursorMode;
using PromptCompleter = std::function<Completions (const Context&, CompletionFlags,
StringView, ByteCount)>;
enum class InsertMode : unsigned
{
Insert,
Append,
Replace,
InsertAtLineBegin,
AppendAtLineEnd,
OpenLineBelow,
OpenLineAbove
};
struct ModeInfo
{
DisplayLine display_line;
Optional<NormalParams> normal_params;
};
class InputHandler : public SafeCountable
{
public:
InputHandler(SelectionList selections,
Context::Flags flags = Context::Flags::None,
String name = "");
~InputHandler();
// switch to insert mode
void insert(InsertMode mode, int count);
// repeat last insert mode key sequence
void repeat_last_insert();
// insert a string without affecting the mode stack
void paste(StringView content);
// enter prompt mode, callback is called on each change,
// abort or validation with corresponding PromptEvent value
// returns to normal mode after validation if callback does
// not change the mode itself
void prompt(StringView prompt, String initstr, String emptystr,
Face prompt_face, PromptFlags flags, char history_register,
PromptCompleter completer, PromptCallback callback);
void set_prompt_face(Face prompt_face);
bool history_enabled() const;
// execute callback on next keypress and returns to normal mode
// if callback does not change the mode itself
void on_next_key(StringView mode_name, KeymapMode mode, KeyCallback callback,
Timer::Callback idle_callback = Timer::Callback{});
// process the given key
void handle_key(Key key, bool synthesized);
void refresh_ifn();
void start_recording(char reg);
bool is_recording() const;
void stop_recording();
char recording_reg() const { return m_recording_reg; }
void reset_normal_mode();
Context& context() { return m_context; }
const Context& context() const { return m_context; }
ModeInfo mode_info() const;
std::pair<CursorMode, DisplayCoord> get_cursor_info() const;
// Force an input handler into normal mode temporarily
struct ScopedForceNormal
{
ScopedForceNormal(InputHandler& handler, NormalParams params);
~ScopedForceNormal();
private:
InputHandler& m_handler;
InputMode* m_mode;
};
private:
Context m_context;
friend class InputMode;
Vector<RefPtr<InputMode>, MemoryDomain::Client> m_mode_stack;
InputMode& current_mode() const { return *m_mode_stack.back(); }
void push_mode(InputMode* new_mode);
void pop_mode(InputMode* current_mode);
void record_key(Key key);
void drop_last_recorded_key();
struct Insertion{
NestedBool recording;
InsertMode mode;
Vector<Key> keys;
bool disable_hooks;
int count;
} m_last_insert = { {}, InsertMode::Insert, {}, false, 1 };
int m_handle_key_level = 0;
char m_recording_reg = 0;
Vector<Key> m_recorded_keys;
int m_recording_level = -1;
};
enum class AutoInfo
{
None = 0,
Command = 1 << 0,
OnKey = 1 << 1,
Normal = 1 << 2
};
constexpr bool with_bit_ops(Meta::Type<AutoInfo>) { return true; }
constexpr auto enum_desc(Meta::Type<AutoInfo>)
{
return make_array<EnumDesc<AutoInfo>>({
{ AutoInfo::Command, "command"},
{ AutoInfo::OnKey, "onkey"},
{ AutoInfo::Normal, "normal" }
});
}
enum class AutoComplete
{
None = 0,
Insert = 0b01,
Prompt = 0b10
};
constexpr bool with_bit_ops(Meta::Type<AutoComplete>) { return true; }
constexpr auto enum_desc(Meta::Type<AutoComplete>)
{
return make_array<EnumDesc<AutoComplete>>({
{ AutoComplete::Insert, "insert"},
{ AutoComplete::Prompt, "prompt" }
});
}
bool should_show_info(AutoInfo mask, const Context& context);
bool show_auto_info_ifn(StringView title, StringView info, AutoInfo mask, const Context& context);
void hide_auto_info_ifn(const Context& context, bool hide);
template<typename Cmd>
void on_next_key_with_autoinfo(const Context& context, StringView mode_name,
KeymapMode keymap_mode, Cmd cmd,
String title, String info)
{
context.input_handler().on_next_key(mode_name,
keymap_mode, [cmd](Key key, Context& context) mutable {
bool hide = should_show_info(AutoInfo::OnKey, context);
hide_auto_info_ifn(context, hide);
cmd(key, context);
}, [&context, title=std::move(title), info=std::move(info)](Timer&) {
show_auto_info_ifn(title, info, AutoInfo::OnKey, context);
});
}
enum class OnHiddenCursor {
PreserveSelections,
MoveCursor,
MoveCursorAndAnchor,
};
void scroll_window(Context& context, LineCount offset, OnHiddenCursor on_hidden_cursor);
}
#endif // input_handler_hh_INCLUDED