7 #include "text-regex.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
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
;
23 Mode
*parent
; /* if no match is found in this mode, search will continue there */
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 */
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 */
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
*);
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
);
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? */
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 */
80 /* a macro is just a sequence of symbolic keys as received from ui->getkey */
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 */
88 enum VisMotionType type
;
90 const Movement
*movement
;
91 const TextObject
*textobj
;
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 struct stat stat
; /* filesystem information when loaded/saved, used to detect changes outside the editor */
104 int refcount
; /* how many windows are displaying this file? (always >= 1) */
105 Mark marks
[VIS_MARK_INVALID
]; /* marks which are shared across windows */
110 time_t state
; /* state of the text, used to invalidate change list */
111 size_t index
; /* #number of changes */
112 size_t pos
; /* where the current change occured */
116 Vis
*vis
; /* editor instance to which this window belongs to */
117 UiWin
*ui
; /* ui object handling visual appearance of this window */
118 File
*file
; /* file being displayed in this window */
119 View
*view
; /* currently displayed part of underlying text */
120 RingBuffer
*jumplist
; /* LRU jump management */
121 ChangeList changelist
; /* state for iterating through least recently changes */
122 Win
*prev
, *next
; /* neighbouring windows */
126 Ui
*ui
; /* user interface repsonsible for visual appearance */
127 File
*files
; /* all files currently managed by this editor instance */
128 Win
*windows
; /* all windows currently managed by this editor instance */
129 Win
*win
; /* currently active/focused window */
130 Register registers
[VIS_REG_INVALID
]; /* registers used for yank and put */
131 Macro macros
[VIS_MACRO_INVALID
]; /* recorded macros */
132 Macro
*recording
, *last_recording
; /* currently (if non NULL) and least recently recorded macro */
133 Macro
*macro_operator
; /* special macro used to repeat certain operators */
134 Win
*prompt
; /* 1-line height window to get user input */
135 Win
*prompt_window
; /* window which was focused before prompt was shown */
136 char prompt_type
; /* command ':' or search '/','?' prompt */
137 Mode
*mode_before_prompt
; /* user mode which was active before entering prompt */
138 Regex
*search_pattern
; /* last used search pattern */
139 char search_char
[8]; /* last used character to search for via 'f', 'F', 't', 'T' */
140 int last_totill
; /* last to/till movement used for ';' and ',' */
141 int tabwidth
; /* how many spaces should be used to display a tab */
142 bool expandtab
; /* whether typed tabs should be converted to spaces */
143 bool autoindent
; /* whether indentation should be copied from previous line on newline */
144 Map
*cmds
; /* ":"-commands, used for unique prefix queries */
145 Map
*options
; /* ":set"-options */
146 Buffer input_queue
; /* holds pending input keys */
147 Buffer
*keys
; /* currently active keys buffer (either the input_queue or a macro) */
148 Action action
; /* current action which is in progress */
149 Action action_prev
; /* last operator action used by the repeat (dot) command */
150 Mode
*mode
; /* currently active mode, used to search for keybindings */
151 Mode
*mode_prev
; /* previsouly active user mode */
152 volatile bool running
; /* exit main loop once this becomes false */
153 int exit_status
; /* exit status when terminating main loop */
154 volatile sig_atomic_t cancel_filter
; /* abort external command/filter (SIGINT occured) */
155 volatile sig_atomic_t sigbus
; /* one of the memory mapped region became unavailable (SIGBUS) */
156 sigjmp_buf sigbus_jmpbuf
; /* used to jump back to a known good state in the mainloop after (SIGBUS) */
157 Map
*actions
; /* registered editor actions / special keys commands */
158 lua_State
*lua
; /* lua context used for syntax highligthing */
162 /** stuff used by multiple of the vis-* files */
164 /* TODO: make part of Vis struct? enable dynamic modes? */
165 extern Mode vis_modes
[VIS_MODE_LAST
];
167 extern Movement moves
[VIS_MOVE_INVALID
];
169 extern Operator ops
[VIS_OP_INVALID
];
171 const char *expandtab(Vis
*vis
);
173 void macro_operator_stop(Vis
*vis
);
174 void macro_operator_record(Vis
*vis
);
176 void action_reset(Action
*);
178 void mode_set(Vis
*vis
, Mode
*new_mode
);
179 Mode
*mode_get(Vis
*vis
, enum VisMode mode
);