Line | Branch | Exec | Source |
---|---|---|---|
1 | #include <stdlib.h> | ||
2 | #include <string.h> | ||
3 | #include "cmdline.h" | ||
4 | #include "command/args.h" | ||
5 | #include "command/macro.h" | ||
6 | #include "commands.h" | ||
7 | #include "completion.h" | ||
8 | #include "copy.h" | ||
9 | #include "editor.h" | ||
10 | #include "history.h" | ||
11 | #include "options.h" | ||
12 | #include "regexp.h" | ||
13 | #include "search.h" | ||
14 | #include "selection.h" | ||
15 | #include "terminal/osc52.h" | ||
16 | #include "util/arith.h" | ||
17 | #include "util/ascii.h" | ||
18 | #include "util/bsearch.h" | ||
19 | #include "util/debug.h" | ||
20 | #include "util/log.h" | ||
21 | #include "util/utf8.h" | ||
22 | |||
23 | 4 | static void cmdline_delete(CommandLine *c) | |
24 | { | ||
25 | 4 | size_t pos = c->pos; | |
26 |
2/2✓ Branch 0 (2→3) taken 1 times.
✓ Branch 1 (2→4) taken 3 times.
|
4 | if (pos == c->buf.len) { |
27 | 1 | return; | |
28 | } | ||
29 | |||
30 | 3 | u_get_char(c->buf.buffer, c->buf.len, &pos); | |
31 | 3 | string_remove(&c->buf, c->pos, pos - c->pos); | |
32 | } | ||
33 | |||
34 | 13 | void cmdline_clear(CommandLine *c) | |
35 | { | ||
36 | 13 | string_clear(&c->buf); | |
37 | 13 | c->pos = 0; | |
38 | 13 | c->search_pos = NULL; | |
39 | 13 | } | |
40 | |||
41 | 11 | void cmdline_free(CommandLine *c) | |
42 | { | ||
43 | 11 | cmdline_clear(c); | |
44 | 11 | string_free(&c->buf); | |
45 | 11 | free(c->search_text); | |
46 | 11 | reset_completion(c); | |
47 | 11 | } | |
48 | |||
49 | 168 | static void set_text(CommandLine *c, const char *text) | |
50 | { | ||
51 | 168 | size_t text_len = strlen(text); | |
52 | 168 | c->pos = text_len; | |
53 | 168 | string_clear(&c->buf); | |
54 | 168 | string_append_buf(&c->buf, text, text_len); | |
55 | 168 | } | |
56 | |||
57 | 168 | void cmdline_set_text(CommandLine *c, const char *text) | |
58 | { | ||
59 | 168 | c->search_pos = NULL; | |
60 | 168 | set_text(c, text); | |
61 | 168 | } | |
62 | |||
63 | // Reset command completion and history search state (after cursor | ||
64 | // position or buffer is changed) | ||
65 | 20 | static bool cmdline_soft_reset(CommandLine *c) | |
66 | { | ||
67 | 20 | c->search_pos = NULL; | |
68 | 20 | maybe_reset_completion(c); | |
69 | 20 | return true; | |
70 | } | ||
71 | |||
72 | 2 | static bool cmd_bol(EditorState *e, const CommandArgs *a) | |
73 | { | ||
74 | 2 | BUG_ON(a->nr_args); | |
75 | 2 | e->cmdline.pos = 0; | |
76 | 2 | return cmdline_soft_reset(&e->cmdline); | |
77 | } | ||
78 | |||
79 | 1 | static bool cmd_cancel(EditorState *e, const CommandArgs *a) | |
80 | { | ||
81 | 1 | BUG_ON(a->nr_args); | |
82 | 1 | CommandLine *c = &e->cmdline; | |
83 | 1 | cmdline_clear(c); | |
84 | 1 | pop_input_mode(e); | |
85 | 1 | reset_completion(c); | |
86 | 1 | return true; | |
87 | } | ||
88 | |||
89 | ✗ | static bool cmd_clear(EditorState *e, const CommandArgs *a) | |
90 | { | ||
91 | ✗ | BUG_ON(a->nr_args); | |
92 | ✗ | cmdline_clear(&e->cmdline); | |
93 | ✗ | return true; | |
94 | } | ||
95 | |||
96 | ✗ | static bool cmd_copy(EditorState *e, const CommandArgs *a) | |
97 | { | ||
98 | ✗ | bool internal = cmdargs_has_flag(a, 'i') || a->flag_set == 0; | |
99 | ✗ | bool clipboard = cmdargs_has_flag(a, 'b'); | |
100 | ✗ | bool primary = cmdargs_has_flag(a, 'p'); | |
101 | |||
102 | ✗ | String *buf = &e->cmdline.buf; | |
103 | ✗ | size_t len = buf->len; | |
104 | ✗ | if (internal) { | |
105 | ✗ | char *str = string_clone_cstring(buf); | |
106 | ✗ | record_copy(&e->clipboard, str, len, false); | |
107 | } | ||
108 | |||
109 | ✗ | Terminal *term = &e->terminal; | |
110 | ✗ | if ((clipboard || primary) && term->features & TFLAG_OSC52_COPY) { | |
111 | ✗ | const char *str = string_borrow_cstring(buf); | |
112 | ✗ | if (!term_osc52_copy(&term->obuf, str, len, clipboard, primary)) { | |
113 | ✗ | LOG_ERRNO("term_osc52_copy"); | |
114 | // TODO: return false ? | ||
115 | } | ||
116 | } | ||
117 | |||
118 | ✗ | return true; | |
119 | } | ||
120 | |||
121 | 2 | static bool cmd_delete(EditorState *e, const CommandArgs *a) | |
122 | { | ||
123 | 2 | BUG_ON(a->nr_args); | |
124 | 2 | CommandLine *c = &e->cmdline; | |
125 | 2 | cmdline_delete(c); | |
126 | 2 | return cmdline_soft_reset(c); | |
127 | } | ||
128 | |||
129 | 1 | static bool cmd_delete_eol(EditorState *e, const CommandArgs *a) | |
130 | { | ||
131 | 1 | BUG_ON(a->nr_args); | |
132 | 1 | CommandLine *c = &e->cmdline; | |
133 | 1 | c->buf.len = c->pos; | |
134 | 1 | return cmdline_soft_reset(c); | |
135 | } | ||
136 | |||
137 | 1 | static bool cmd_delete_word(EditorState *e, const CommandArgs *a) | |
138 | { | ||
139 | 1 | BUG_ON(a->nr_args); | |
140 | 1 | CommandLine *c = &e->cmdline; | |
141 | 1 | const unsigned char *buf = c->buf.buffer; | |
142 | 1 | const size_t len = c->buf.len; | |
143 | 1 | size_t i = c->pos; | |
144 | |||
145 |
1/2✓ Branch 0 (4→6) taken 1 times.
✗ Branch 1 (4→14) not taken.
|
1 | if (i == len) { |
146 | return true; | ||
147 | } | ||
148 | |||
149 |
3/4✓ Branch 0 (6→7) taken 6 times.
✗ Branch 1 (6→8) not taken.
✓ Branch 2 (7→5) taken 5 times.
✓ Branch 3 (7→8) taken 1 times.
|
6 | while (i < len && is_word_byte(buf[i])) { |
150 | 5 | i++; | |
151 | } | ||
152 | |||
153 |
3/4✓ Branch 0 (10→11) taken 2 times.
✗ Branch 1 (10→12) not taken.
✓ Branch 2 (11→9) taken 1 times.
✓ Branch 3 (11→12) taken 1 times.
|
2 | while (i < len && !is_word_byte(buf[i])) { |
154 | 1 | i++; | |
155 | } | ||
156 | |||
157 | 1 | string_remove(&c->buf, c->pos, i - c->pos); | |
158 | 1 | return cmdline_soft_reset(c); | |
159 | } | ||
160 | |||
161 | 2 | static bool cmd_eol(EditorState *e, const CommandArgs *a) | |
162 | { | ||
163 | 2 | BUG_ON(a->nr_args); | |
164 | 2 | CommandLine *c = &e->cmdline; | |
165 | 2 | c->pos = c->buf.len; | |
166 | 2 | return cmdline_soft_reset(c); | |
167 | } | ||
168 | |||
169 | 2 | static bool cmd_erase(EditorState *e, const CommandArgs *a) | |
170 | { | ||
171 | 2 | BUG_ON(a->nr_args); | |
172 | 2 | CommandLine *c = &e->cmdline; | |
173 |
1/2✓ Branch 0 (4→5) taken 2 times.
✗ Branch 1 (4→7) not taken.
|
2 | if (c->pos > 0) { |
174 | 2 | u_prev_char(c->buf.buffer, &c->pos); | |
175 | 2 | cmdline_delete(c); | |
176 | } | ||
177 | 2 | return cmdline_soft_reset(c); | |
178 | } | ||
179 | |||
180 | 1 | static bool cmd_erase_bol(EditorState *e, const CommandArgs *a) | |
181 | { | ||
182 | 1 | BUG_ON(a->nr_args); | |
183 | 1 | CommandLine *c = &e->cmdline; | |
184 | 1 | string_remove(&c->buf, 0, c->pos); | |
185 | 1 | c->pos = 0; | |
186 | 1 | return cmdline_soft_reset(c); | |
187 | } | ||
188 | |||
189 | 2 | static bool cmd_erase_word(EditorState *e, const CommandArgs *a) | |
190 | { | ||
191 | 2 | BUG_ON(a->nr_args); | |
192 | 2 | CommandLine *c = &e->cmdline; | |
193 | 2 | size_t i = c->pos; | |
194 |
1/2✓ Branch 0 (4→5) taken 2 times.
✗ Branch 1 (4→15) not taken.
|
2 | if (i == 0) { |
195 | return true; | ||
196 | } | ||
197 | |||
198 | // open /path/to/file^W => open /path/to/ | ||
199 | |||
200 | // erase whitespace | ||
201 |
3/4✓ Branch 0 (5→6) taken 3 times.
✗ Branch 1 (5→7) not taken.
✓ Branch 2 (6→5) taken 1 times.
✓ Branch 3 (6→7) taken 2 times.
|
3 | while (i && ascii_isspace(c->buf.buffer[i - 1])) { |
202 | i--; | ||
203 | } | ||
204 | |||
205 | // erase non-word bytes | ||
206 |
2/4✓ Branch 0 (8→9) taken 2 times.
✗ Branch 1 (8→10) not taken.
✗ Branch 2 (9→8) not taken.
✓ Branch 3 (9→10) taken 2 times.
|
2 | while (i && !is_word_byte(c->buf.buffer[i - 1])) { |
207 | i--; | ||
208 | } | ||
209 | |||
210 | // erase word bytes | ||
211 |
3/4✓ Branch 0 (11→12) taken 12 times.
✗ Branch 1 (11→13) not taken.
✓ Branch 2 (12→11) taken 10 times.
✓ Branch 3 (12→13) taken 2 times.
|
12 | while (i && is_word_byte(c->buf.buffer[i - 1])) { |
212 | i--; | ||
213 | } | ||
214 | |||
215 | 2 | string_remove(&c->buf, i, c->pos - i); | |
216 | 2 | c->pos = i; | |
217 | 2 | return cmdline_soft_reset(c); | |
218 | } | ||
219 | |||
220 | ✗ | static bool do_history_prev(const History *hist, CommandLine *c, bool prefix_search) | |
221 | { | ||
222 | ✗ | if (!c->search_pos) { | |
223 | ✗ | free(c->search_text); | |
224 | ✗ | c->search_text = string_clone_cstring(&c->buf); | |
225 | } | ||
226 | |||
227 | ✗ | const char *search_text = prefix_search ? c->search_text : ""; | |
228 | ✗ | if (history_search_forward(hist, &c->search_pos, search_text)) { | |
229 | ✗ | BUG_ON(!c->search_pos); | |
230 | ✗ | set_text(c, c->search_pos->text); | |
231 | } | ||
232 | |||
233 | ✗ | maybe_reset_completion(c); | |
234 | ✗ | return true; | |
235 | } | ||
236 | |||
237 | ✗ | static bool do_history_next(const History *hist, CommandLine *c, bool prefix_search) | |
238 | { | ||
239 | ✗ | if (!c->search_pos) { | |
240 | ✗ | goto out; | |
241 | } | ||
242 | |||
243 | ✗ | const char *search_text = prefix_search ? c->search_text : ""; | |
244 | ✗ | if (history_search_backward(hist, &c->search_pos, search_text)) { | |
245 | ✗ | BUG_ON(!c->search_pos); | |
246 | ✗ | set_text(c, c->search_pos->text); | |
247 | } else { | ||
248 | ✗ | set_text(c, c->search_text); | |
249 | ✗ | c->search_pos = NULL; | |
250 | } | ||
251 | |||
252 | ✗ | out: | |
253 | ✗ | maybe_reset_completion(c); | |
254 | ✗ | return true; | |
255 | } | ||
256 | |||
257 | ✗ | static bool cmd_search_history_next(EditorState *e, const CommandArgs *a) | |
258 | { | ||
259 | ✗ | BUG_ON(a->nr_args); | |
260 | ✗ | bool prefix_search = !cmdargs_has_flag(a, 'S'); | |
261 | ✗ | return do_history_next(&e->search_history, &e->cmdline, prefix_search); | |
262 | } | ||
263 | |||
264 | ✗ | static bool cmd_search_history_prev(EditorState *e, const CommandArgs *a) | |
265 | { | ||
266 | ✗ | BUG_ON(a->nr_args); | |
267 | ✗ | bool prefix_search = !cmdargs_has_flag(a, 'S'); | |
268 | ✗ | return do_history_prev(&e->search_history, &e->cmdline, prefix_search); | |
269 | } | ||
270 | |||
271 | ✗ | static bool cmd_command_history_next(EditorState *e, const CommandArgs *a) | |
272 | { | ||
273 | ✗ | BUG_ON(a->nr_args); | |
274 | ✗ | bool prefix_search = !cmdargs_has_flag(a, 'S'); | |
275 | ✗ | return do_history_next(&e->command_history, &e->cmdline, prefix_search); | |
276 | } | ||
277 | |||
278 | ✗ | static bool cmd_command_history_prev(EditorState *e, const CommandArgs *a) | |
279 | { | ||
280 | ✗ | BUG_ON(a->nr_args); | |
281 | ✗ | bool prefix_search = !cmdargs_has_flag(a, 'S'); | |
282 | ✗ | return do_history_prev(&e->command_history, &e->cmdline, prefix_search); | |
283 | } | ||
284 | |||
285 | 2 | static bool cmd_left(EditorState *e, const CommandArgs *a) | |
286 | { | ||
287 | 2 | BUG_ON(a->nr_args); | |
288 | 2 | CommandLine *c = &e->cmdline; | |
289 |
2/2✓ Branch 0 (4→5) taken 1 times.
✓ Branch 1 (4→6) taken 1 times.
|
2 | if (c->pos) { |
290 | 1 | u_prev_char(c->buf.buffer, &c->pos); | |
291 | } | ||
292 | 2 | return cmdline_soft_reset(c); | |
293 | } | ||
294 | |||
295 | ✗ | static bool cmd_paste(EditorState *e, const CommandArgs *a) | |
296 | { | ||
297 | ✗ | const Clipboard *clip = &e->clipboard; | |
298 | ✗ | const size_t len = clip->len; | |
299 | ✗ | if (len == 0) { | |
300 | return true; | ||
301 | } | ||
302 | |||
303 | ✗ | CommandLine *c = &e->cmdline; | |
304 | ✗ | char newline_replacement = cmdargs_has_flag(a, 'n') ? ';' : ' '; | |
305 | ✗ | string_insert_buf(&c->buf, c->pos, clip->buf, len); | |
306 | ✗ | strn_replace_byte(c->buf.buffer + c->pos, len, '\n', newline_replacement); | |
307 | ✗ | c->pos += cmdargs_has_flag(a, 'm') ? len : 0; | |
308 | ✗ | return cmdline_soft_reset(c); | |
309 | } | ||
310 | |||
311 | 2 | static bool cmd_right(EditorState *e, const CommandArgs *a) | |
312 | { | ||
313 | 2 | BUG_ON(a->nr_args); | |
314 | 2 | CommandLine *c = &e->cmdline; | |
315 |
1/2✓ Branch 0 (4→5) taken 2 times.
✗ Branch 1 (4→6) not taken.
|
2 | if (c->pos < c->buf.len) { |
316 | 2 | u_get_char(c->buf.buffer, c->buf.len, &c->pos); | |
317 | } | ||
318 | 2 | return cmdline_soft_reset(c); | |
319 | } | ||
320 | |||
321 | ✗ | static bool cmd_toggle(EditorState *e, const CommandArgs *a) | |
322 | { | ||
323 | ✗ | const char *option_name = a->args[0]; | |
324 | ✗ | bool global = cmdargs_has_flag(a, 'g'); | |
325 | ✗ | size_t nr_values = a->nr_args - 1; | |
326 | ✗ | if (nr_values == 0) { | |
327 | ✗ | return toggle_option(e, option_name, global, false); | |
328 | } | ||
329 | |||
330 | ✗ | char **values = a->args + 1; | |
331 | ✗ | return toggle_option_values(e, option_name, global, false, values, nr_values); | |
332 | } | ||
333 | |||
334 | 2 | static bool cmd_word_bwd(EditorState *e, const CommandArgs *a) | |
335 | { | ||
336 | 2 | BUG_ON(a->nr_args); | |
337 | 2 | CommandLine *c = &e->cmdline; | |
338 |
2/2✓ Branch 0 (4→5) taken 1 times.
✓ Branch 1 (4→6) taken 1 times.
|
2 | if (c->pos <= 1) { |
339 | 1 | c->pos = 0; | |
340 | 1 | return cmdline_soft_reset(c); | |
341 | } | ||
342 | |||
343 | 1 | const unsigned char *const buf = c->buf.buffer; | |
344 | 1 | size_t i = c->pos - 1; | |
345 | |||
346 |
3/4✓ Branch 0 (8→9) taken 2 times.
✗ Branch 1 (8→10) not taken.
✓ Branch 2 (9→7) taken 1 times.
✓ Branch 3 (9→10) taken 1 times.
|
2 | while (i > 0 && !is_word_byte(buf[i])) { |
347 | 1 | i--; | |
348 | } | ||
349 | |||
350 |
3/4✓ Branch 0 (12→13) taken 6 times.
✗ Branch 1 (12→14) not taken.
✓ Branch 2 (13→11) taken 5 times.
✓ Branch 3 (13→14) taken 1 times.
|
6 | while (i > 0 && is_word_byte(buf[i])) { |
351 | 5 | i--; | |
352 | } | ||
353 | |||
354 |
1/2✓ Branch 0 (14→15) taken 1 times.
✗ Branch 1 (14→16) not taken.
|
1 | if (i > 0) { |
355 | 1 | i++; | |
356 | } | ||
357 | |||
358 | 1 | c->pos = i; | |
359 | 1 | return cmdline_soft_reset(c); | |
360 | } | ||
361 | |||
362 | 1 | static bool cmd_word_fwd(EditorState *e, const CommandArgs *a) | |
363 | { | ||
364 | 1 | BUG_ON(a->nr_args); | |
365 | 1 | CommandLine *c = &e->cmdline; | |
366 | 1 | const unsigned char *buf = c->buf.buffer; | |
367 | 1 | const size_t len = c->buf.len; | |
368 | 1 | size_t i = c->pos; | |
369 | |||
370 |
3/4✓ Branch 0 (6→7) taken 6 times.
✗ Branch 1 (6→8) not taken.
✓ Branch 2 (7→5) taken 5 times.
✓ Branch 3 (7→8) taken 1 times.
|
6 | while (i < len && is_word_byte(buf[i])) { |
371 | 5 | i++; | |
372 | } | ||
373 | |||
374 |
3/4✓ Branch 0 (10→11) taken 1 times.
✓ Branch 1 (10→12) taken 1 times.
✓ Branch 2 (11→9) taken 1 times.
✗ Branch 3 (11→12) not taken.
|
2 | while (i < len && !is_word_byte(buf[i])) { |
375 | 1 | i++; | |
376 | } | ||
377 | |||
378 | 1 | c->pos = i; | |
379 | 1 | return cmdline_soft_reset(c); | |
380 | } | ||
381 | |||
382 | ✗ | static bool cmd_complete_next(EditorState *e, const CommandArgs *a) | |
383 | { | ||
384 | ✗ | BUG_ON(a->nr_args); | |
385 | ✗ | complete_command_next(e); | |
386 | ✗ | return true; | |
387 | } | ||
388 | |||
389 | ✗ | static bool cmd_complete_prev(EditorState *e, const CommandArgs *a) | |
390 | { | ||
391 | ✗ | BUG_ON(a->nr_args); | |
392 | ✗ | complete_command_prev(e); | |
393 | ✗ | return true; | |
394 | } | ||
395 | |||
396 | ✗ | static bool cmd_direction(EditorState *e, const CommandArgs *a) | |
397 | { | ||
398 | ✗ | BUG_ON(a->nr_args); | |
399 | ✗ | toggle_search_direction(&e->search); | |
400 | ✗ | return true; | |
401 | } | ||
402 | |||
403 | ✗ | static bool cmd_command_mode_accept(EditorState *e, const CommandArgs *a) | |
404 | { | ||
405 | ✗ | CommandLine *c = &e->cmdline; | |
406 | ✗ | reset_completion(c); | |
407 | ✗ | pop_input_mode(e); | |
408 | |||
409 | ✗ | const char *str = string_borrow_cstring(&c->buf); | |
410 | ✗ | cmdline_clear(c); | |
411 | ✗ | if (!cmdargs_has_flag(a, 'H') && str[0] != ' ') { | |
412 | // This is done before handle_command() because "command [text]" | ||
413 | // can modify the contents of the command-line | ||
414 | ✗ | history_append(&e->command_history, str); | |
415 | } | ||
416 | |||
417 | ✗ | e->err.command_name = NULL; | |
418 | ✗ | return handle_normal_command(e, str, true); | |
419 | } | ||
420 | |||
421 | ✗ | static bool cmd_search_mode_accept(EditorState *e, const CommandArgs *a) | |
422 | { | ||
423 | ✗ | CommandLine *c = &e->cmdline; | |
424 | ✗ | bool add_to_history = !cmdargs_has_flag(a, 'H'); | |
425 | ✗ | const char *pat = NULL; | |
426 | |||
427 | ✗ | if (c->buf.len > 0) { | |
428 | ✗ | String *s = &c->buf; | |
429 | ✗ | if (cmdargs_has_flag(a, 'e')) { | |
430 | // Escape the regex; to match as plain text | ||
431 | ✗ | char *original = string_clone_cstring(s); | |
432 | ✗ | size_t origlen = string_clear(s); | |
433 | ✗ | size_t bufsize = xmul(2, origlen) + 1; | |
434 | ✗ | char *buf = string_reserve_space(s, bufsize); | |
435 | ✗ | s->len = regexp_escapeb(buf, bufsize, original, origlen); | |
436 | ✗ | BUG_ON(s->len < origlen); | |
437 | ✗ | free(original); | |
438 | } | ||
439 | |||
440 | ✗ | pat = string_borrow_cstring(s); | |
441 | ✗ | search_set_regexp(&e->search, pat); | |
442 | ✗ | if (add_to_history) { | |
443 | ✗ | history_append(&e->search_history, pat); | |
444 | } | ||
445 | } | ||
446 | |||
447 | ✗ | if (e->macro.recording) { | |
448 | ✗ | macro_search_hook(&e->macro, pat, e->search.reverse, add_to_history); | |
449 | } | ||
450 | |||
451 | // Unselect, unless selection mode is active | ||
452 | ✗ | view_set_selection_type(e->view, e->view->select_mode); | |
453 | |||
454 | ✗ | e->err.command_name = NULL; | |
455 | ✗ | bool found = search_next(e->view, &e->search, e->options.case_sensitive_search); | |
456 | ✗ | cmdline_clear(c); | |
457 | ✗ | pop_input_mode(e); | |
458 | ✗ | return found; | |
459 | } | ||
460 | |||
461 | // Note that some of the `Command::flags` entries here aren't actually | ||
462 | // used in the `cmd` handler and are only included to mirror commands | ||
463 | // of the same name in normal mode. This is done as a convenience for | ||
464 | // allowing key binding commands like e.g. `bind -cns C-M-c 'copy -bk'` | ||
465 | // to be used, instead of needing 2 different commands (with and without | ||
466 | // the `-k` flag for normal vs. command/search modes). | ||
467 | |||
468 | #define CMD(name, flags, min, max, func) \ | ||
469 | {name, flags, 0, min, max, func} | ||
470 | |||
471 | static const Command common_cmds[] = { | ||
472 | CMD("bol", "st", 0, 0, cmd_bol), // Ignored flags: s, t | ||
473 | CMD("cancel", "", 0, 0, cmd_cancel), | ||
474 | CMD("clear", "Ii", 0, 0, cmd_clear), // Ignored flags: I, i | ||
475 | CMD("copy", "bikp", 0, 0, cmd_copy), // Ignored flag: k | ||
476 | CMD("delete", "", 0, 0, cmd_delete), | ||
477 | CMD("delete-eol", "n", 0, 0, cmd_delete_eol), // Ignored flag: n | ||
478 | CMD("delete-word", "s", 0, 0, cmd_delete_word), // Ignored flag: s | ||
479 | CMD("eol", "", 0, 0, cmd_eol), | ||
480 | CMD("erase", "", 0, 0, cmd_erase), | ||
481 | CMD("erase-bol", "", 0, 0, cmd_erase_bol), | ||
482 | CMD("erase-word", "s", 0, 0, cmd_erase_word), // Ignored flag: s | ||
483 | CMD("left", "", 0, 0, cmd_left), | ||
484 | CMD("paste", "acmn", 0, 0, cmd_paste), // Ignored flags: a, c | ||
485 | CMD("right", "", 0, 0, cmd_right), | ||
486 | CMD("toggle", "gv", 1, -1, cmd_toggle), // Ignored flag: v | ||
487 | CMD("word-bwd", "s", 0, 0, cmd_word_bwd), // Ignored flag: s | ||
488 | CMD("word-fwd", "s", 0, 0, cmd_word_fwd), // Ignored flag: s | ||
489 | }; | ||
490 | |||
491 | static const Command search_cmds[] = { | ||
492 | CMD("accept", "eH", 0, 0, cmd_search_mode_accept), | ||
493 | CMD("direction", "", 0, 0, cmd_direction), | ||
494 | CMD("history-next", "S", 0, 0, cmd_search_history_next), | ||
495 | CMD("history-prev", "S", 0, 0, cmd_search_history_prev), | ||
496 | }; | ||
497 | |||
498 | static const Command command_cmds[] = { | ||
499 | CMD("accept", "H", 0, 0, cmd_command_mode_accept), | ||
500 | CMD("complete-next", "", 0, 0, cmd_complete_next), | ||
501 | CMD("complete-prev", "", 0, 0, cmd_complete_prev), | ||
502 | CMD("history-next", "S", 0, 0, cmd_command_history_next), | ||
503 | CMD("history-prev", "S", 0, 0, cmd_command_history_prev), | ||
504 | }; | ||
505 | |||
506 | 355 | static const Command *find_cmd_mode_command(const char *name) | |
507 | { | ||
508 | 355 | const Command *cmd = BSEARCH(name, common_cmds, command_cmp); | |
509 |
2/2✓ Branch 0 (3→4) taken 64 times.
✓ Branch 1 (3→5) taken 291 times.
|
355 | return cmd ? cmd : BSEARCH(name, command_cmds, command_cmp); |
510 | } | ||
511 | |||
512 | 342 | static const Command *find_search_mode_command(const char *name) | |
513 | { | ||
514 | 342 | const Command *cmd = BSEARCH(name, common_cmds, command_cmp); | |
515 |
2/2✓ Branch 0 (3→4) taken 63 times.
✓ Branch 1 (3→5) taken 279 times.
|
342 | return cmd ? cmd : BSEARCH(name, search_cmds, command_cmp); |
516 | } | ||
517 | |||
518 | const CommandSet cmd_mode_commands = { | ||
519 | .lookup = find_cmd_mode_command | ||
520 | }; | ||
521 | |||
522 | const CommandSet search_mode_commands = { | ||
523 | .lookup = find_search_mode_command | ||
524 | }; | ||
525 |