dte test coverage


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 50.0% high: ≥ 85.0%
Coverage Exec / Excl / Total
Lines: 60.3% 44 / 0 / 73
Functions: 85.7% 6 / 0 / 7
Branches: 38.2% 13 / 4 / 38

src/mode.c
Line Branch Exec Source
1 #include <stddef.h>
2 #include "mode.h"
3 #include "bind.h"
4 #include "change.h"
5 #include "cmdline.h"
6 #include "command/macro.h"
7 #include "completion.h"
8 #include "editor.h"
9 #include "indent.h"
10 #include "insert.h"
11 #include "terminal/paste.h"
12 #include "util/debug.h"
13 #include "util/unicode.h"
14 #include "util/xmalloc.h"
15 #include "view.h"
16
17 34 ModeHandler *new_mode(HashMap *modes, char *name, const CommandSet *cmds)
18 {
19 34 ModeHandler *mode = xcalloc1(sizeof(*mode));
20 34 mode->name = name;
21 34 mode->cmds = cmds;
22 34 return hashmap_insert(modes, name, mode);
23 }
24
25 static bool insert_paste(EditorState *e, const ModeHandler *handler, bool bracketed)
26 {
27 String str = term_read_paste(&e->terminal.ibuf, bracketed);
28 if (handler->cmds == &normal_commands) {
29 StringView text = strview_from_string(&str);
30 begin_change(CHANGE_MERGE_NONE);
31 insert_text(e->view, text, true);
32 end_change();
33 macro_insert_text_hook(&e->macro, text);
34 } else {
35 CommandLine *c = &e->cmdline;
36 string_replace_byte(&str, '\n', ' ');
37 string_insert_buf(&c->buf, c->pos, str.buffer, str.len);
38 c->pos += str.len;
39 c->search_pos = NULL;
40 }
41 string_free(&str);
42 return true;
43 }
44
45 7 static bool handle_input_single (
46 EditorState *e,
47 const ModeHandler *handler,
48 KeyCode key,
49 ModeHandlerFlags inherited_flags
50 ) {
51 7 bool bracketed_paste = (key == KEYCODE_BRACKETED_PASTE);
52
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 7 times.
7 if (bracketed_paste || key == KEYCODE_DETECTED_PASTE) {
53 return insert_paste(e, handler, bracketed_paste);
54 }
55
56 7 ModeHandlerFlags noinsert_flags = MHF_NO_TEXT_INSERTION | MHF_NO_TEXT_INSERTION_RECURSIVE;
57 7 ModeHandlerFlags flag_union = handler->flags | inherited_flags;
58 7 bool insert_unicode_range = !(flag_union & noinsert_flags);
59
60
1/2
✓ Branch 4 → 5 taken 7 times.
✗ Branch 4 → 25 not taken.
7 if (insert_unicode_range) {
61 7 const CommandSet *cmds = handler->cmds;
62
2/2
✓ Branch 5 → 6 taken 5 times.
✓ Branch 5 → 16 taken 2 times.
7 if (cmds == &normal_commands) {
63 5 View *view = e->view;
64 5 KeyCode shift = key & MOD_SHIFT;
65
1/4
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 12 taken 5 times.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 12 not taken.
5 if ((key & ~shift) == KEY_TAB && view->selection == SELECT_LINES) {
66 // In line selections, Tab/S-Tab behave like indent/indent -r
67 indent_lines(view, shift ? -1 : 1);
68 return true;
69 }
70
1/2
✓ Branch 12 → 13 taken 5 times.
✗ Branch 12 → 25 not taken.
5 if (u_is_unicode(key)) {
71 5 insert_ch(e->view, key);
72 5 macro_insert_char_hook(&e->macro, key);
73 5 return true;
74 }
75 } else {
76 2 BUG_ON(cmds != &cmd_mode_commands && cmds != &search_mode_commands);
77
2/4
✓ Branch 19 → 20 taken 2 times.
✗ Branch 19 → 25 not taken.
✓ Branch 20 → 21 taken 2 times.
✗ Branch 20 → 25 not taken.
2 if (u_is_unicode(key) && (key != KEY_TAB && key != KEY_ENTER)) {
78 2 CommandLine *c = &e->cmdline;
79 2 c->pos += string_insert_codepoint(&c->buf, c->pos, key);
80
1/2
✓ Branch 22 → 23 taken 2 times.
✗ Branch 22 → 24 not taken.
2 if (cmds == &cmd_mode_commands) {
81 2 maybe_reset_completion(c);
82 }
83 2 c->search_pos = NULL;
84 2 return true;
85 }
86 }
87 }
88
89 return handle_binding(e, handler, key);
90 }
91
92 // Recursion is bounded by the depth of fallthrough modes, which is
93 // typically not more than 5 or so
94 // NOLINTNEXTLINE(misc-no-recursion)
95 7 static bool handle_input_recursive (
96 EditorState *e,
97 const ModeHandler *handler,
98 KeyCode key,
99 ModeHandlerFlags inherited_flags
100 ) {
101
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 9 taken 7 times.
7 if (handle_input_single(e, handler, key, inherited_flags)) {
102 return true;
103 }
104
105 const PointerArray *ftmodes = &handler->fallthrough_modes;
106 inherited_flags |= (handler->flags & MHF_NO_TEXT_INSERTION_RECURSIVE);
107
108 for (size_t i = 0, n = ftmodes->count; i < n; i++) {
109 const ModeHandler *h = ftmodes->ptrs[i];
110 if (handle_input_recursive(e, h, key, inherited_flags)) {
111 return true;
112 }
113 }
114
115 return false;
116 }
117
118 3 void string_append_def_mode(String *buf, const ModeHandler *mode)
119 {
120 3 string_append_literal(buf, "def-mode ");
121
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 3 times.
3 if (mode->flags & MHF_NO_TEXT_INSERTION_RECURSIVE) {
122 string_append_literal(buf, "-U ");
123
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 3 times.
3 } else if (mode->flags & MHF_NO_TEXT_INSERTION) {
124 string_append_literal(buf, "-u ");
125 }
126
127 3 string_append_cstring(buf, mode->name);
128
129 3 const PointerArray *ftmodes = &mode->fallthrough_modes;
130
1/2
✗ Branch 12 → 9 not taken.
✓ Branch 12 → 13 taken 3 times.
3 for (size_t i = 0, n = ftmodes->count; i < n; i++) {
131 const ModeHandler *ftmode = ftmodes->ptrs[i];
132 string_append_byte(buf, ' ');
133 string_append_cstring(buf, ftmode->name);
134 }
135 3 }
136
137 7 bool handle_input(EditorState *e, KeyCode key)
138 {
139 7 return handle_input_recursive(e, e->mode, key, 0);
140 }
141
142 2 void collect_modes(const HashMap *modes, PointerArray *a, StringView prefix)
143 {
144 2 collect_hashmap_keys(modes, a, prefix);
145 2 }
146