make C-s and C-q available in key mappings
[vis/gkirilov.git] / vis-core.h
blob00b90d835b2e4c3c317eec692538c234cddcf776
1 #ifndef VIS_CORE_H
2 #define VIS_CORE_H
4 #include <setjmp.h>
5 #include "vis.h"
6 #include "sam.h"
7 #include "vis-lua.h"
8 #include "text.h"
9 #include "text-util.h"
10 #include "map.h"
11 #include "array.h"
12 #include "buffer.h"
13 #include "util.h"
15 /* a mode contains a set of key bindings which are currently valid.
17 * each mode can specify one parent mode which is consulted if a given key
18 * is not found in the current mode. hence the modes form a tree which is
19 * searched from the current mode up towards the root mode until a valid binding
20 * is found.
22 * if no binding is found, mode->input(...) is called and the user entered
23 * keys are passed as argument. this is used to change the document content.
25 typedef struct Mode Mode;
26 struct Mode {
27 enum VisMode id;
28 Mode *parent; /* if no match is found in this mode, search will continue there */
29 Map *bindings;
30 const char *name; /* descriptive, user facing name of the mode */
31 const char *status; /* name displayed in the window status bar */
32 const char *help; /* short description used by :help */
33 void (*enter)(Vis*, Mode *old); /* called right before the mode becomes active */
34 void (*leave)(Vis*, Mode *new); /* called right before the mode becomes inactive */
35 void (*input)(Vis*, const char*, size_t); /* called whenever a key is not found in this mode and all its parent modes */
36 void (*idle)(Vis*); /* called whenever a certain idle time i.e. without any user input elapsed */
37 time_t idle_timeout; /* idle time in seconds after which the registered function will be called */
38 bool visual; /* whether text selection is possible in this mode */
41 typedef struct {
42 Array values;
43 bool linewise; /* place register content on a new line when inserting? */
44 bool append;
45 enum {
46 REGISTER_NORMAL,
47 REGISTER_NUMBER,
48 REGISTER_BLACKHOLE,
49 REGISTER_CLIPBOARD,
50 } type;
51 } Register;
53 struct OperatorContext {
54 int count; /* how many times should the command be executed? */
55 Register *reg; /* always non-NULL, set to a default register */
56 size_t reg_slot; /* register slot to use */
57 Filerange range; /* which part of the file should be affected by the operator */
58 size_t pos; /* at which byte from the start of the file should the operation start? */
59 size_t newpos; /* new position after motion or EPOS if none given */
60 bool linewise; /* should the changes always affect whole lines? */
61 const Arg *arg; /* arbitrary arguments */
62 void *context; /* used by user-registered operators */
65 typedef struct {
66 /* operator logic, returns new cursor position, if EPOS
67 * the cursor is disposed (except if it is the primary one) */
68 VisOperatorFunction *func;
69 void *context;
70 } Operator;
72 typedef struct { /* Motion implementation, takes a cursor position and returns a new one */
73 /* TODO: merge types / use union to save space */
74 size_t (*cur)(Selection*);
75 size_t (*txt)(Text*, size_t pos);
76 size_t (*file)(Vis*, File*, Selection*);
77 size_t (*vis)(Vis*, Text*, size_t pos);
78 size_t (*view)(Vis*, View*);
79 size_t (*win)(Vis*, Win*, size_t pos);
80 size_t (*user)(Vis*, Win*, void*, size_t pos);
81 enum {
82 LINEWISE = VIS_MOTIONTYPE_LINEWISE, /* should the covered range be extended to whole lines? */
83 CHARWISE = VIS_MOTIONTYPE_CHARWISE, /* scrolls window content until position is visible */
84 INCLUSIVE = 1 << 2, /* should new position be included in operator range? */
85 LINEWISE_INCLUSIVE = 1 << 3, /* inclusive, but only if motion is linewise? */
86 IDEMPOTENT = 1 << 4, /* does the returned position remain the same if called multiple times? */
87 JUMP = 1 << 5, /* should the resulting position of the motion be recorded in the jump list? */
88 COUNT_EXACT = 1 << 6, /* fail (keep initial position) if count can not be satisfied exactly */
89 } type;
90 void *data;
91 } Movement;
93 typedef struct {
94 /* gets a cursor position and returns a file range (or text_range_empty())
95 * representing the text object containing the position. */
96 Filerange (*txt)(Text*, size_t pos);
97 Filerange (*vis)(Vis*, Text*, size_t pos);
98 Filerange (*user)(Vis*, Win*, void *data, size_t pos);
99 enum {
100 TEXTOBJECT_DELIMITED_INNER = 1 << 0, /* single byte delimited, inner variant */
101 TEXTOBJECT_DELIMITED_OUTER = 1 << 1, /* single byte delimited, outer variant */
102 TEXTOBJECT_NON_CONTIGUOUS = 1 << 2, /* multiple applications yield a split range */
103 TEXTOBJECT_EXTEND_FORWARD = 1 << 3, /* multiple applications extend towards the end of file (default) */
104 TEXTOBJECT_EXTEND_BACKWARD = 1 << 4, /* multiple applications extend towards the begin of file */
105 TEXTOBJECT_LINEWISE = 1 << 5,
106 } type;
107 void *data;
108 } TextObject;
110 /* a macro is just a sequence of symbolic keys as received from ui->getkey */
111 typedef Buffer Macro;
112 #define macro_init buffer_init
113 #define macro_release buffer_release
114 #define macro_reset buffer_clear
115 #define macro_append buffer_append0
117 typedef struct { /** collects all information until an operator is executed */
118 int count;
119 enum VisMode mode;
120 enum VisMotionType type;
121 const Operator *op;
122 const Movement *movement;
123 const TextObject *textobj;
124 const Macro *macro;
125 Register *reg;
126 enum VisMark mark;
127 Arg arg;
128 } Action;
130 typedef struct Change Change;
131 typedef struct {
132 Change *changes; /* all changes in monotonically increasing file position */
133 Change *latest; /* most recent change */
134 enum SamError error; /* non-zero in case something went wrong */
135 } Transcript;
137 typedef struct {
138 Array prev;
139 Array next;
140 size_t max;
141 } MarkList;
143 struct File { /* shared state among windows displaying the same file */
144 Text *text; /* data structure holding the file content */
145 const char *name; /* file name used when loading/saving */
146 volatile sig_atomic_t truncated; /* whether the underlying memory mapped region became invalid (SIGBUS) */
147 int fd; /* output file descriptor associated with this file or -1 if loaded by file name */
148 bool internal; /* whether it is an internal file (e.g. used for the prompt) */
149 struct stat stat; /* filesystem information when loaded/saved, used to detect changes outside the editor */
150 int refcount; /* how many windows are displaying this file? (always >= 1) */
151 Array marks[VIS_MARK_INVALID]; /* marks which are shared across windows */
152 enum TextSaveMethod save_method; /* whether the file is saved using rename(2) or overwritten */
153 Transcript transcript; /* keeps track of changes performed by sam commands */
154 File *next, *prev;
157 struct Win {
158 Vis *vis; /* editor instance to which this window belongs */
159 UiWin *ui; /* ui object handling visual appearance of this window */
160 File *file; /* file being displayed in this window */
161 View *view; /* currently displayed part of underlying text */
162 bool expandtab; /* whether typed tabs should be converted to spaces in this window*/
163 MarkList jumplist; /* LRU jump management */
164 Array saved_selections; /* register used to store selections */
165 Mode modes[VIS_MODE_INVALID]; /* overlay mods used for per window key bindings */
166 Win *parent; /* window which was active when showing the command prompt */
167 Mode *parent_mode; /* mode which was active when showing the command prompt */
168 Win *prev, *next; /* neighbouring windows */
171 struct Vis {
172 Ui *ui; /* user interface responsible for visual appearance */
173 File *files; /* all files currently managed by this editor instance */
174 File *command_file; /* special internal file used to store :-command prompt */
175 File *search_file; /* special internal file used to store /,? search prompt */
176 File *error_file; /* special internal file used to store lua error messages */
177 Win *windows; /* all windows currently managed by this editor instance */
178 Win *win; /* currently active/focused window */
179 Win *message_window; /* special window to display multi line messages */
180 Register registers[VIS_REG_INVALID]; /* registers used for text manipulations yank/put etc. and macros */
181 Macro *recording, *last_recording; /* currently (if non NULL) and least recently recorded macro */
182 const Macro *replaying; /* macro currently being replayed */
183 Macro *macro_operator; /* special macro used to repeat certain operators */
184 Mode *mode_before_prompt; /* user mode which was active before entering prompt */
185 char search_char[8]; /* last used character to search for via 'f', 'F', 't', 'T' */
186 int last_totill; /* last to/till movement used for ';' and ',' */
187 Regex *last_search; /* last regex used in '/' or '?' */
188 int search_direction; /* used for `n` and `N` */
189 bool autoindent; /* whether indentation should be copied from previous line on newline */
190 bool change_colors; /* whether to adjust 256 color palette for true colors */
191 bool smartcase; /* case-insensitive search, unless the pattern contains upper case characters */
192 bool literal; /* literal string search */
193 char *shell; /* shell used to launch external commands */
194 Map *cmds; /* ":"-commands, used for unique prefix queries */
195 Map *usercmds; /* user registered ":"-commands */
196 Map *options; /* ":set"-options */
197 Map *keymap; /* key translation before any bindings are matched */
198 bool keymap_disabled; /* ignore key map for next key press, gets automatically re-enabled */
199 char key[VIS_KEY_LENGTH_MAX]; /* last pressed key as reported from the UI */
200 char key_current[VIS_KEY_LENGTH_MAX];/* current key being processed by the input queue */
201 char key_prev[VIS_KEY_LENGTH_MAX]; /* previous key which was processed by the input queue */
202 Buffer input_queue; /* holds pending input keys */
203 Action action; /* current action which is in progress */
204 Action action_prev; /* last operator action used by the repeat (dot) command */
205 Mode *mode; /* currently active mode, used to search for keybindings */
206 Mode *mode_prev; /* previously active user mode */
207 bool initialized; /* whether UI and Lua integration has been initialized */
208 int nesting_level; /* parsing state to hold keep track of { } nesting level */
209 volatile bool running; /* exit main loop once this becomes false */
210 int exit_status; /* exit status when terminating main loop */
211 volatile sig_atomic_t interrupted; /* abort command (SIGINT occurred) */
212 volatile sig_atomic_t sigbus; /* one of the memory mapped regions became unavailable (SIGBUS) */
213 volatile sig_atomic_t need_resize; /* need to resize UI (SIGWINCH occurred) */
214 volatile sig_atomic_t resume; /* need to resume UI (SIGCONT occurred) */
215 volatile sig_atomic_t terminate; /* need to terminate we were being killed by SIGTERM */
216 sigjmp_buf sigbus_jmpbuf; /* used to jump back to a known good state in the mainloop after (SIGBUS) */
217 Map *actions; /* registered editor actions / special keys commands */
218 Array actions_user; /* dynamically allocated editor actions */
219 lua_State *lua; /* lua context used for syntax highlighting */
220 enum TextLoadMethod load_method; /* how existing files should be loaded */
221 VisEvent *event;
222 Array operators;
223 Array motions;
224 Array textobjects;
225 Array bindings;
228 enum VisEvents {
229 VIS_EVENT_INIT,
230 VIS_EVENT_START,
231 VIS_EVENT_QUIT,
232 VIS_EVENT_FILE_OPEN,
233 VIS_EVENT_FILE_SAVE_PRE,
234 VIS_EVENT_FILE_SAVE_POST,
235 VIS_EVENT_FILE_CLOSE,
236 VIS_EVENT_WIN_OPEN,
237 VIS_EVENT_WIN_CLOSE,
238 VIS_EVENT_WIN_HIGHLIGHT,
239 VIS_EVENT_WIN_STATUS,
240 VIS_EVENT_TERM_CSI,
241 VIS_EVENT_UI_DRAW,
244 bool vis_event_emit(Vis*, enum VisEvents, ...);
246 typedef struct {
247 char name;
248 VIS_HELP_DECL(const char *help;)
249 } MarkDef;
251 typedef MarkDef RegisterDef;
253 /** stuff used by several of the vis-* files */
255 extern Mode vis_modes[VIS_MODE_INVALID];
256 extern const Movement vis_motions[VIS_MOVE_INVALID];
257 extern const Operator vis_operators[VIS_OP_INVALID];
258 extern const TextObject vis_textobjects[VIS_TEXTOBJECT_INVALID];
259 extern const MarkDef vis_marks[VIS_MARK_a];
260 extern const RegisterDef vis_registers[VIS_REG_a];
262 void macro_operator_stop(Vis *vis);
263 void macro_operator_record(Vis *vis);
265 void vis_do(Vis *vis);
266 void action_reset(Action*);
267 size_t vis_text_insert_nl(Vis*, Text*, size_t pos);
269 Mode *mode_get(Vis*, enum VisMode);
270 void mode_set(Vis *vis, Mode *new_mode);
271 Macro *macro_get(Vis *vis, enum VisRegister);
273 void window_selection_save(Win *win);
274 Win *window_new_file(Vis*, File*, enum UiOption);
276 char *absolute_path(const char *path);
278 const char *file_name_get(File*);
279 void file_name_set(File*, const char *name);
281 bool register_init(Register*);
282 void register_release(Register*);
284 void mark_init(Array*);
285 void mark_release(Array*);
287 void marklist_init(MarkList*, size_t max);
288 void marklist_release(MarkList*);
290 const char *register_get(Vis*, Register*, size_t *len);
291 const char *register_slot_get(Vis*, Register*, size_t slot, size_t *len);
293 bool register_put0(Vis*, Register*, const char *data);
294 bool register_put(Vis*, Register*, const char *data, size_t len);
295 bool register_slot_put(Vis*, Register*, size_t slot, const char *data, size_t len);
297 bool register_put_range(Vis*, Register*, Text*, Filerange*);
298 bool register_slot_put_range(Vis*, Register*, size_t slot, Text*, Filerange*);
300 size_t vis_register_count(Vis*, Register*);
301 bool register_resize(Register*, size_t count);
303 #endif