Line | Branch | Exec | Source |
---|---|---|---|
1 | #ifndef EDITOR_H | ||
2 | #define EDITOR_H | ||
3 | |||
4 | #include <stdbool.h> | ||
5 | #include <stddef.h> | ||
6 | #include <stdint.h> | ||
7 | #include "buffer.h" | ||
8 | #include "cmdline.h" | ||
9 | #include "command/error.h" | ||
10 | #include "command/macro.h" | ||
11 | #include "command/run.h" | ||
12 | #include "commands.h" | ||
13 | #include "copy.h" | ||
14 | #include "file-history.h" | ||
15 | #include "frame.h" | ||
16 | #include "history.h" | ||
17 | #include "lock.h" | ||
18 | #include "mode.h" | ||
19 | #include "msg.h" | ||
20 | #include "options.h" | ||
21 | #include "regexp.h" | ||
22 | #include "search.h" | ||
23 | #include "syntax/color.h" | ||
24 | #include "syntax/state.h" | ||
25 | #include "tag.h" | ||
26 | #include "terminal/cursor.h" | ||
27 | #include "terminal/terminal.h" | ||
28 | #include "util/debug.h" | ||
29 | #include "util/hashmap.h" | ||
30 | #include "util/hashset.h" | ||
31 | #include "util/macros.h" | ||
32 | #include "util/ptr-array.h" | ||
33 | #include "util/string-view.h" | ||
34 | #include "vars.h" | ||
35 | #include "view.h" | ||
36 | |||
37 | typedef enum { | ||
38 | EDITOR_INITIALIZING = -2, | ||
39 | EDITOR_RUNNING = -1, | ||
40 | // Values 0-125 are exit codes | ||
41 | EDITOR_EXIT_OK = 0, | ||
42 | EDITOR_EXIT_MAX = 125, | ||
43 | } EditorStatus; | ||
44 | |||
45 | typedef enum { | ||
46 | EFLAG_CMD_HIST = 1u << 0, // Save command history on quit | ||
47 | EFLAG_SEARCH_HIST = 1u << 1, // Save search history on quit | ||
48 | EFLAG_FILE_HIST = 1u << 2, // Save file history on quit | ||
49 | EFLAG_ALL_HIST = EFLAG_CMD_HIST | EFLAG_SEARCH_HIST | EFLAG_FILE_HIST, | ||
50 | EFLAG_HEADLESS = 1u << 3, // Running in "headless" mode (no tty interaction) | ||
51 | } EditorFlags; | ||
52 | |||
53 | // Used to track which parts of the screen have changed since the last | ||
54 | // call to update_screen() | ||
55 | typedef enum { | ||
56 | UPDATE_TERM_TITLE = 1u << 0, // update_term_title() | ||
57 | UPDATE_CURSOR_STYLE = 1u << 1, // update_cursor_style() | ||
58 | UPDATE_WINDOW_SEPARATORS = 1u << 2, // update_window_separators() | ||
59 | |||
60 | // TODO: Set this when the buffer contents changes or when the cursor | ||
61 | // position changes in a way that requires a redraw (e.g. a change of line | ||
62 | // affected by `hi currentline`, `set ws-error trailing`, scrolling, etc.), | ||
63 | // then handle it accordingly in update_screen() | ||
64 | UPDATE_CURRENT_BUFFER = 1u << 3, | ||
65 | |||
66 | UPDATE_ALL_WINDOWS = 1u << 4, // update_all_windows() | ||
67 | UPDATE_ALL = (UPDATE_ALL_WINDOWS << 1) - 1, // All of the above | ||
68 | |||
69 | UPDATE_DIALOG = 1u << 30, // show_dialog(); modal dialog for e.g. `quit -p` | ||
70 | } ScreenUpdateFlags; | ||
71 | |||
72 | typedef struct EditorState { | ||
73 | EditorStatus status; | ||
74 | ModeHandler *mode; // Current mode | ||
75 | ModeHandler *prev_mode; // Mode to use after leaving command/search mode | ||
76 | ModeHandler *normal_mode; | ||
77 | ModeHandler *command_mode; | ||
78 | ModeHandler *search_mode; | ||
79 | CommandLine cmdline; | ||
80 | SearchState search; | ||
81 | GlobalOptions options; | ||
82 | StringView home_dir; | ||
83 | const char *user_config_dir; | ||
84 | mode_t new_file_mode; | ||
85 | EditorFlags flags; | ||
86 | ScreenUpdateFlags screen_update; | ||
87 | uint8_t include_recursion_count; | ||
88 | bool child_controls_terminal; | ||
89 | bool session_leader; | ||
90 | Clipboard clipboard; | ||
91 | TagFile tagfile; | ||
92 | HashMap aliases; | ||
93 | HashMap compilers; | ||
94 | HashMap modes; | ||
95 | HashMap syntaxes; | ||
96 | HashSet required_syntax_files; | ||
97 | HashSet required_syntax_builtins; | ||
98 | StyleMap styles; | ||
99 | SyntaxLoadState syn; | ||
100 | MacroRecorder macro; | ||
101 | TermCursorStyle cursor_styles[NR_CURSOR_MODES]; | ||
102 | FileLocksContext locks_ctx; | ||
103 | Frame *root_frame; | ||
104 | struct Window *window; | ||
105 | View *view; | ||
106 | Buffer *buffer; | ||
107 | PointerArray buffers; | ||
108 | PointerArray filetypes; | ||
109 | PointerArray file_options; | ||
110 | PointerArray bookmarks; | ||
111 | MessageArray messages; | ||
112 | FileHistory file_history; | ||
113 | History search_history; | ||
114 | History command_history; | ||
115 | RegexpWordBoundaryTokens regexp_word_tokens; | ||
116 | ErrorBuffer err; | ||
117 | Terminal terminal; | ||
118 | } EditorState; | ||
119 | |||
120 | 2 | static inline void set_input_mode(EditorState *e, ModeHandler *mode) | |
121 | { | ||
122 |
1/2✓ Branch 0 (2→3) taken 2 times.
✗ Branch 1 (2→4) not taken.
|
2 | if (e->mode != mode) { |
123 | 2 | e->mode = mode; | |
124 | 2 | e->screen_update |= UPDATE_CURSOR_STYLE; | |
125 | } | ||
126 | 2 | } | |
127 | |||
128 | 1 | static inline void push_input_mode(EditorState *e, ModeHandler *mode) | |
129 | { | ||
130 |
1/2✓ Branch 0 (2→3) taken 1 times.
✗ Branch 1 (2→4) not taken.
|
1 | if (e->mode->cmds == &normal_commands) { |
131 | // Save the previous mode only when entering command/search mode, so | ||
132 | // that the previously active mode can be returned to on accept/cancel | ||
133 | // (regardless of edge cases like e.g. running `command; command`) | ||
134 | 1 | e->prev_mode = e->mode; | |
135 | } | ||
136 | 1 | set_input_mode(e, mode); | |
137 | 1 | } | |
138 | |||
139 | 1 | static inline void pop_input_mode(EditorState *e) | |
140 | { | ||
141 | 1 | BUG_ON(!e->prev_mode); | |
142 | 1 | set_input_mode(e, e->prev_mode); | |
143 | 1 | } | |
144 | |||
145 | 1512 | static inline CommandRunner cmdrunner(EditorState *e, const CommandSet *cmds) | |
146 | { | ||
147 | 1512 | bool normal = (cmds == &normal_commands); | |
148 | 3024 | return (CommandRunner) { | |
149 | .cmds = cmds, | ||
150 |
2/2✓ Branch 0 (2→3) taken 1131 times.
✓ Branch 1 (2→4) taken 381 times.
|
1512 | .lookup_alias = normal ? find_normal_alias : NULL, |
151 |
2/2✓ Branch 0 (4→5) taken 1131 times.
✓ Branch 1 (4→6) taken 381 times.
|
1512 | .expand_variable = normal ? expand_normal_var : NULL, |
152 | 1512 | .home_dir = &e->home_dir, | |
153 | .e = e, | ||
154 | 1512 | .ebuf = &e->err, | |
155 | .allow_recording = false, | ||
156 | .expand_tilde_slash = true, | ||
157 | }; | ||
158 | } | ||
159 | |||
160 | 381 | static inline CommandRunner normal_mode_cmdrunner(EditorState *e) | |
161 | { | ||
162 | 381 | return cmdrunner(e, &normal_commands); | |
163 | } | ||
164 | |||
165 | EditorState *init_editor_state(EditorFlags flags) RETURNS_NONNULL; | ||
166 | void free_editor_state(EditorState *e) NONNULL_ARGS; | ||
167 | void any_key(Terminal *term, unsigned int esc_timeout) NONNULL_ARGS; | ||
168 | int main_loop(EditorState *e) NONNULL_ARGS; | ||
169 | void ui_first_start(EditorState *e, unsigned int terminal_query_level) NONNULL_ARGS; | ||
170 | void ui_start(EditorState *e) NONNULL_ARGS; | ||
171 | void ui_end(EditorState *e) NONNULL_ARGS; | ||
172 | void ui_resize(EditorState *e) NONNULL_ARGS; | ||
173 | |||
174 | #endif | ||
175 |