| 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 << 24, // show_dialog(); modal dialog for e.g. `quit -p` | ||
| 70 | |||
| 71 | UPDATE_SYNTAX_STYLES = 1u << 25, // update_all_syntax_styles(); triggered by cmd_hi() | ||
| 72 | } ScreenUpdateFlags; | ||
| 73 | |||
| 74 | typedef struct EditorState { | ||
| 75 | EditorStatus status; | ||
| 76 | ModeHandler *mode; // Current mode | ||
| 77 | ModeHandler *prev_mode; // Mode to use after leaving command/search mode | ||
| 78 | ModeHandler *normal_mode; | ||
| 79 | ModeHandler *command_mode; | ||
| 80 | ModeHandler *search_mode; | ||
| 81 | CommandLine cmdline; | ||
| 82 | SearchState search; | ||
| 83 | GlobalOptions options; | ||
| 84 | StringView home_dir; // $HOME (interned) | ||
| 85 | const char *user_config_dir; // $DTE_HOME or equivalent (interned) | ||
| 86 | mode_t new_file_mode; | ||
| 87 | EditorFlags flags; | ||
| 88 | ScreenUpdateFlags screen_update; | ||
| 89 | uint8_t include_recursion_count; | ||
| 90 | bool session_leader; | ||
| 91 | Clipboard clipboard; | ||
| 92 | TagFile tagfile; | ||
| 93 | HashMap aliases; | ||
| 94 | HashMap compilers; | ||
| 95 | HashMap modes; | ||
| 96 | HashMap syntaxes; | ||
| 97 | HashSet required_syntax_files; | ||
| 98 | HashSet required_syntax_builtins; | ||
| 99 | StyleMap styles; | ||
| 100 | SyntaxLoader syn; | ||
| 101 | MacroRecorder macro; | ||
| 102 | TermCursorStyle cursor_styles[NR_CURSOR_MODES]; | ||
| 103 | FileLocksContext locks_ctx; | ||
| 104 | Frame *root_frame; | ||
| 105 | struct Window *window; | ||
| 106 | View *view; | ||
| 107 | Buffer *buffer; | ||
| 108 | PointerArray buffers; | ||
| 109 | PointerArray filetypes; | ||
| 110 | PointerArray file_options; | ||
| 111 | PointerArray bookmarks; | ||
| 112 | MessageList messages[3]; | ||
| 113 | FileHistory file_history; | ||
| 114 | History search_history; | ||
| 115 | History command_history; | ||
| 116 | RegexpWordBoundaryTokens regexp_word_tokens; | ||
| 117 | ErrorBuffer err; | ||
| 118 | Terminal terminal; | ||
| 119 | } EditorState; | ||
| 120 | |||
| 121 | 2 | static inline void set_input_mode(EditorState *e, ModeHandler *mode) | |
| 122 | { | ||
| 123 |
1/2✓ Branch 0 (2→3) taken 2 times.
✗ Branch 1 (2→4) not taken.
|
2 | if (e->mode != mode) { |
| 124 | 2 | e->mode = mode; | |
| 125 | 2 | e->screen_update |= UPDATE_CURSOR_STYLE; | |
| 126 | } | ||
| 127 | 2 | } | |
| 128 | |||
| 129 | 1 | static inline void push_input_mode(EditorState *e, ModeHandler *mode) | |
| 130 | { | ||
| 131 |
1/2✓ Branch 0 (2→3) taken 1 times.
✗ Branch 1 (2→4) not taken.
|
1 | if (e->mode->cmds == &normal_commands) { |
| 132 | // Save the previous mode only when entering command/search mode, so | ||
| 133 | // that the previously active mode can be returned to on accept/cancel | ||
| 134 | // (regardless of edge cases like e.g. running `command; command`) | ||
| 135 | 1 | e->prev_mode = e->mode; | |
| 136 | } | ||
| 137 | 1 | set_input_mode(e, mode); | |
| 138 | 1 | } | |
| 139 | |||
| 140 | 1 | static inline void pop_input_mode(EditorState *e) | |
| 141 | { | ||
| 142 | 1 | BUG_ON(!e->prev_mode); | |
| 143 | 1 | set_input_mode(e, e->prev_mode); | |
| 144 | 1 | } | |
| 145 | |||
| 146 | 2111 | static inline CommandRunner cmdrunner(EditorState *e, const CommandSet *cmds) | |
| 147 | { | ||
| 148 | 2111 | bool normal = (cmds == &normal_commands); | |
| 149 | 4222 | return (CommandRunner) { | |
| 150 | .cmds = cmds, | ||
| 151 |
2/2✓ Branch 0 (2→3) taken 1697 times.
✓ Branch 1 (2→4) taken 414 times.
|
2111 | .lookup_alias = normal ? find_normal_alias : NULL, |
| 152 |
2/2✓ Branch 0 (4→5) taken 1697 times.
✓ Branch 1 (4→6) taken 414 times.
|
2111 | .expand_variable = normal ? expand_normal_var : NULL, |
| 153 | 2111 | .home_dir = &e->home_dir, | |
| 154 | .e = e, | ||
| 155 | 2111 | .ebuf = &e->err, | |
| 156 | .flags = CMDRUNNER_EXPAND_TILDE_SLASH, | ||
| 157 | }; | ||
| 158 | } | ||
| 159 | |||
| 160 | 414 | static inline CommandRunner normal_mode_cmdrunner(EditorState *e) | |
| 161 | { | ||
| 162 | 414 | return cmdrunner(e, &normal_commands); | |
| 163 | } | ||
| 164 | |||
| 165 | EditorState *init_editor_state(const char *home, const char *dte_home) RETURNS_NONNULL; | ||
| 166 | void free_editor_state(EditorState *e) NONNULL_ARGS; | ||
| 167 | void clear_all_messages(EditorState *e) NONNULL_ARGS; | ||
| 168 | void any_key(Terminal *term, unsigned int esc_timeout) NONNULL_ARGS; | ||
| 169 | void main_loop(EditorState *e, bool timing) NONNULL_ARGS; | ||
| 170 | void ui_first_start(EditorState *e, unsigned int terminal_query_level) NONNULL_ARGS; | ||
| 171 | void ui_start(EditorState *e) NONNULL_ARGS; | ||
| 172 | void ui_end(Terminal *term, bool final) NONNULL_ARGS; | ||
| 173 | void ui_resize(EditorState *e) NONNULL_ARGS; | ||
| 174 | |||
| 175 | #endif | ||
| 176 |