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