vis: move motion releated functions to corresponding file
[vis.git] / vis-core.h
blobb00ec9013a11cc31111a5bdda165e09142fb7ec8
1 #ifndef VIS_CORE_H
2 #define VIS_CORE_H
4 #include <setjmp.h>
5 #include "vis.h"
6 #include "text.h"
7 #include "text-regex.h"
8 #include "map.h"
9 #include "ring-buffer.h"
11 /* a mode contains a set of key bindings which are currently valid.
13 * each mode can specify one parent mode which is consultated if a given key
14 * is not found in the current mode. hence the modes form a tree which is
15 * searched from the current mode up towards the root mode until a valid binding
16 * is found.
18 * if no binding is found, mode->input(...) is called and the user entered
19 * keys are passed as argument. this is used to change the document content.
21 typedef struct Mode Mode;
22 struct Mode {
23 Mode *parent; /* if no match is found in this mode, search will continue there */
24 Map *bindings;
25 const char *name; /* descriptive, user facing name of the mode */
26 const char *status; /* name displayed in the window status bar */
27 const char *help; /* short description used by :help */
28 bool isuser; /* whether this is a user or internal mode */
29 void (*enter)(Vis*, Mode *old); /* called right before the mode becomes active */
30 void (*leave)(Vis*, Mode *new); /* called right before the mode becomes inactive */
31 void (*input)(Vis*, const char*, size_t); /* called whenever a key is not found in this mode and all its parent modes */
32 void (*idle)(Vis*); /* called whenever a certain idle time i.e. without any user input elapsed */
33 time_t idle_timeout; /* idle time in seconds after which the registered function will be called */
34 bool visual; /* whether text selection is possible in this mode */
37 typedef struct {
38 int count; /* how many times should the command be executed? */
39 Register *reg; /* always non-NULL, set to a default register */
40 Filerange range; /* which part of the file should be affected by the operator */
41 size_t pos; /* at which byte from the start of the file should the operation start? */
42 size_t newpos; /* new position after motion or EPOS if none given */
43 bool linewise; /* should the changes always affect whole lines? */
44 const Arg *arg; /* arbitrary arguments */
45 } OperatorContext;
47 typedef struct {
48 /* operator logic, returns new cursor position, if EPOS is
49 * the cursor is disposed (except if it is the primary one) */
50 size_t (*func)(Vis*, Text*, OperatorContext*);
51 } Operator;
53 typedef struct { /* Motion implementation, takes a cursor postion and returns a new one */
54 /* TODO: merge types / use union to save space */
55 size_t (*cur)(Cursor*);
56 size_t (*txt)(Text*, size_t pos);
57 size_t (*file)(Vis*, File*, size_t pos);
58 size_t (*vis)(Vis*, Text*, size_t pos);
59 size_t (*view)(Vis*, View*);
60 size_t (*win)(Vis*, Win*, size_t pos);
61 enum {
62 LINEWISE = VIS_MOTIONTYPE_LINEWISE, /* should the covered range be extended to whole lines? */
63 CHARWISE = VIS_MOTIONTYPE_CHARWISE, /* scrolls window content until position is visible */
64 INCLUSIVE = 1 << 2, /* should new position be included in operator range? */
65 IDEMPOTENT = 1 << 3, /* does the returned postion remain the same if called multiple times? */
66 JUMP = 1 << 4,
67 } type;
68 } Movement;
70 typedef struct {
71 /* gets a cursor position and returns a file range (or text_range_empty())
72 * representing the text object containing the position. */
73 Filerange (*range)(Text*, size_t pos);
74 enum { /* whether the object should include the delimiting symbols or not */
75 INNER,
76 OUTER,
77 } type;
78 } TextObject;
80 /* a macro is just a sequence of symbolic keys as received from ui->getkey */
81 typedef Buffer Macro;
82 #define macro_release buffer_release
83 #define macro_reset buffer_truncate
84 #define macro_append buffer_append0
86 typedef struct { /** collects all information until an operator is executed */
87 int count;
88 enum VisMotionType type;
89 const Operator *op;
90 const Movement *movement;
91 const TextObject *textobj;
92 const Macro *macro;
93 Register *reg;
94 enum VisMark mark;
95 Arg arg;
96 } Action;
98 struct File { /* shared state among windows displaying the same file */
99 Text *text; /* data structure holding the file content */
100 const char *name; /* file name used when loading/saving */
101 volatile sig_atomic_t truncated; /* whether the underlying memory mapped region became invalid (SIGBUS) */
102 bool is_stdin; /* whether file content was read from stdin */
103 bool internal; /* whether it is an internal file (e.g. used for the prompt) */
104 struct stat stat; /* filesystem information when loaded/saved, used to detect changes outside the editor */
105 int refcount; /* how many windows are displaying this file? (always >= 1) */
106 Mark marks[VIS_MARK_INVALID]; /* marks which are shared across windows */
107 File *next, *prev;
110 typedef struct {
111 time_t state; /* state of the text, used to invalidate change list */
112 size_t index; /* #number of changes */
113 size_t pos; /* where the current change occured */
114 } ChangeList;
116 struct Win {
117 Vis *vis; /* editor instance to which this window belongs to */
118 UiWin *ui; /* ui object handling visual appearance of this window */
119 File *file; /* file being displayed in this window */
120 View *view; /* currently displayed part of underlying text */
121 RingBuffer *jumplist; /* LRU jump management */
122 ChangeList changelist; /* state for iterating through least recently changes */
123 Mode modes[VIS_MODE_INVALID]; /* overlay mods used for per window key bindings */
124 Win *parent; /* window which was active when showing the command prompt */
125 Mode *parent_mode; /* mode which was active when showing the command prompt */
126 Win *prev, *next; /* neighbouring windows */
129 struct Vis {
130 Ui *ui; /* user interface repsonsible for visual appearance */
131 File *files; /* all files currently managed by this editor instance */
132 File *command_file; /* special internal file used to store :-command prompt */
133 File *search_file; /* special internal file used to store /,? search prompt */
134 Win *windows; /* all windows currently managed by this editor instance */
135 Win *win; /* currently active/focused window */
136 Register registers[VIS_REG_INVALID]; /* registers used for yank and put */
137 Macro macros[VIS_MACRO_INVALID]; /* recorded macros */
138 Macro *recording, *last_recording; /* currently (if non NULL) and least recently recorded macro */
139 Macro *macro_operator; /* special macro used to repeat certain operators */
140 Mode *mode_before_prompt; /* user mode which was active before entering prompt */
141 Regex *search_pattern; /* last used search pattern */
142 char search_char[8]; /* last used character to search for via 'f', 'F', 't', 'T' */
143 int last_totill; /* last to/till movement used for ';' and ',' */
144 int tabwidth; /* how many spaces should be used to display a tab */
145 bool expandtab; /* whether typed tabs should be converted to spaces */
146 bool autoindent; /* whether indentation should be copied from previous line on newline */
147 Map *cmds; /* ":"-commands, used for unique prefix queries */
148 Map *options; /* ":set"-options */
149 Buffer input_queue; /* holds pending input keys */
150 Buffer *keys; /* currently active keys buffer (either the input_queue or a macro) */
151 Action action; /* current action which is in progress */
152 Action action_prev; /* last operator action used by the repeat (dot) command */
153 Mode *mode; /* currently active mode, used to search for keybindings */
154 Mode *mode_prev; /* previsouly active user mode */
155 volatile bool running; /* exit main loop once this becomes false */
156 int exit_status; /* exit status when terminating main loop */
157 volatile sig_atomic_t cancel_filter; /* abort external command/filter (SIGINT occured) */
158 volatile sig_atomic_t sigbus; /* one of the memory mapped region became unavailable (SIGBUS) */
159 sigjmp_buf sigbus_jmpbuf; /* used to jump back to a known good state in the mainloop after (SIGBUS) */
160 Map *actions; /* registered editor actions / special keys commands */
161 lua_State *lua; /* lua context used for syntax highligthing */
162 VisEvent *event;
165 /** stuff used by multiple of the vis-* files */
167 /* TODO: make part of Vis struct? enable dynamic modes? */
168 extern Mode vis_modes[VIS_MODE_INVALID];
170 extern Movement moves[VIS_MOVE_INVALID];
172 extern Operator ops[VIS_OP_INVALID];
173 extern TextObject vis_textobjects[VIS_TEXTOBJECT_INVALID];
175 void action_do(Vis *vis, Action *a);
177 void macro_operator_stop(Vis *vis);
178 void macro_operator_record(Vis *vis);
180 void action_reset(Action*);
182 void mode_set(Vis *vis, Mode *new_mode);
183 Mode *mode_get(Vis *vis, enum VisMode mode);
185 void window_selection_save(Win *win);
187 #endif