vis
a vi-like editor based on Plan 9's structural regular expressions
git clone https://9o.is/git/vis.git
vis.h
(38619B)
1 #ifndef VIS_H
2 #define VIS_H
3
4 #include <signal.h>
5 #include <stddef.h>
6 #include <stdbool.h>
7
8 typedef struct Vis Vis;
9 typedef struct File File;
10 typedef struct Win Win;
11
12 #include "ui.h"
13 #include "view.h"
14 #include "text-regex.h"
15 #include "libutf.h"
16 #include "array.h"
17
18 #ifndef CONFIG_HELP
19 #define CONFIG_HELP 1
20 #endif
21
22 #if CONFIG_HELP
23 #define VIS_HELP_DECL(x) x
24 #define VIS_HELP_USE(x) x
25 #define VIS_HELP(x) (x),
26 #else
27 #define VIS_HELP_DECL(x)
28 #define VIS_HELP_USE(x) NULL
29 #define VIS_HELP(x)
30 #endif
31
32 /* simplify utility renames by distribution packagers */
33 #ifndef VIS_OPEN
34 #define VIS_OPEN "vis-open"
35 #endif
36 #ifndef VIS_CLIPBOARD
37 #define VIS_CLIPBOARD "vis-clipboard"
38 #endif
39
40 /* maximum bytes needed for string representation of a (pseudo) key */
41 #define VIS_KEY_LENGTH_MAX 64
42
43 /** Union used to pass arguments to key action functions. */
44 typedef union {
45 bool b;
46 int i;
47 const char *s;
48 const void *v;
49 void (*w)(View*);
50 void (*f)(Vis*);
51 } Arg;
52
53 /**
54 * Key action handling function.
55 * @param vis The editor instance.
56 * @param keys Input queue content *after* the binding which invoked this function.
57 * @param arg Arguments for the key action.
58 * @rst
59 * .. note:: An empty string ``""`` indicates that no further input is available.
60 * @endrst
61 * @return Pointer to first non-consumed key.
62 * @rst
63 * .. warning:: Must be in range ``[keys, keys+strlen(keys)]`` or ``NULL`` to
64 * indicate that not enough input was available. In the latter case
65 * the function will be called again once more input has been received.
66 * @endrst
67 * @ingroup vis_action
68 */
69 typedef const char *KeyActionFunction(Vis *vis, const char *keys, const Arg *arg);
70
71 /** Key action definition. */
72 typedef struct {
73 const char *name; /**< Name of a pseudo key ``<name>`` which can be used in mappings. */
74 VIS_HELP_DECL(const char *help;) /**< One line human readable description, displayed by ``:help``. */
75 KeyActionFunction *func; /**< Key action implementation function. */
76 Arg arg; /**< Options passes as last argument to ``func``. */
77 } KeyAction;
78
79 /**
80 * A key binding, refers to an action or an alias
81 * @rst
82 * .. note:: Either ``action`` or ``alias`` must be ``NULL``.
83 * @endrst
84 */
85 typedef struct {
86 const char *key; /**< Symbolic key to trigger this binding. */
87 const KeyAction *action; /**< Action to invoke when triggering this binding. */
88 const char *alias; /**< Replaces ``key`` with ``alias`` at the front of the input queue. */
89 } KeyBinding;
90
91 /*
92 ---
93 ## Core Lifecycle Functions
94 */
95
96 /**
97 * @defgroup vis_lifecycle Vis Lifecycle
98 * @{
99 */
100 /** Create a new editor instance. */
101 Vis *vis_new(void);
102 /** Free all resources associated with this editor instance, terminates UI. */
103 void vis_free(Vis*);
104 /**
105 * Enter main loop, start processing user input.
106 * @param vis The editor instance.
107 * @return The editor exit status code.
108 */
109 int vis_run(Vis*);
110 /**
111 * Terminate editing session, the given ``status`` will be the return value of `vis_run`.
112 * @param vis The editor instance.
113 * @param status The exit status.
114 */
115 void vis_exit(Vis *vis, int status);
116 /**
117 * Emergency exit, print given message, perform minimal UI cleanup and exit process.
118 * @param vis The editor instance.
119 * @param msg The message to print.
120 * @rst
121 * .. note:: This function does not return.
122 * @endrst
123 */
124 void vis_die(Vis *vis, const char *msg, ...) __attribute__((noreturn,format(printf, 2, 3)));
125
126 /**
127 * Inform the editor core that a signal occurred.
128 * @param vis The editor instance.
129 * @param signum The signal number.
130 * @param siginfo Pointer to `siginfo_t` structure.
131 * @param context Pointer to context.
132 * @return Whether the signal was handled.
133 * @rst
134 * .. note:: Being designed as a library the editor core does *not* register any
135 * signal handlers on its own.
136 * .. note:: The remaining arguments match the prototype of ``sa_sigaction`` as
137 * specified in `sigaction(2)`.
138 * @endrst
139 */
140 bool vis_signal_handler(Vis *vis, int signum, const siginfo_t *siginfo, const void *context);
141 /**
142 * Interrupt long running operation.
143 * @param vis The editor instance.
144 * @rst
145 * .. warning:: There is no guarantee that a long running operation is actually
146 * interrupted. It is analogous to cooperative multitasking where
147 * the operation has to voluntarily yield control.
148 * .. note:: It is invoked from `vis_signal_handler` when receiving ``SIGINT``.
149 * @endrst
150 */
151 void vis_interrupt(Vis*);
152 /**
153 * Check whether interruption was requested.
154 * @param vis The editor instance.
155 */
156 bool vis_interrupt_requested(Vis*);
157 /** @} */
158
159 /*
160 ---
161 ## Drawing and Redrawing
162 */
163
164 /**
165 * @defgroup vis_draw Vis Drawing
166 * @{
167 */
168 /**
169 * Draw user interface.
170 * @param vis The editor instance.
171 */
172 void vis_draw(Vis*);
173 /**
174 * Completely redraw user interface.
175 * @param vis The editor instance.
176 */
177 void vis_redraw(Vis*);
178 /** @} */
179
180 /*
181 ---
182 ## Window Management
183 */
184
185 /**
186 * @defgroup vis_windows Vis Windows
187 * @{
188 */
189 /**
190 * Create a new window and load the given file.
191 * @param vis The editor instance.
192 * @param filename If ``NULL`` an unnamed, empty buffer is created.
193 * @rst
194 * .. note:: If the given file name is already opened in another window,
195 * the underlying File object is shared.
196 * @endrst
197 */
198 bool vis_window_new(Vis *vis, const char *filename);
199 /**
200 * Create a new window associated with a file descriptor.
201 * @param vis The editor instance.
202 * @param fd The file descriptor to associate with the window.
203 * @rst
204 * .. note:: No data is read from `fd`, but write commands without an
205 * explicit filename will instead write to the file descriptor.
206 * @endrst
207 */
208 bool vis_window_new_fd(Vis *vis, int fd);
209 /**
210 * Reload the file currently displayed in the window from disk.
211 * @param win The window to reload.
212 */
213 bool vis_window_reload(Win*);
214 /**
215 * Change the file currently displayed in the window.
216 * @param win The window to change.
217 * @param filename The new file to display.
218 */
219 bool vis_window_change_file(Win *win, const char *filename);
220 /**
221 * Check whether closing the window would loose unsaved changes.
222 * @param win The window to check.
223 */
224 bool vis_window_closable(Win*);
225 /**
226 * Close window, redraw user interface.
227 * @param win The window to close.
228 */
229 void vis_window_close(Win*);
230 /**
231 * Split the window, shares the underlying file object.
232 * @param original The window to split.
233 */
234 bool vis_window_split(Win*);
235 /**
236 * Draw a specific window.
237 * @param win The window to draw.
238 */
239 void vis_window_draw(Win*);
240 /**
241 * Invalidate a window, forcing a redraw.
242 * @param win The window to invalidate.
243 */
244 void vis_window_invalidate(Win*);
245 /**
246 * Focus next window.
247 * @param vis The editor instance.
248 */
249 void vis_window_next(Vis*);
250 /**
251 * Focus previous window.
252 * @param vis The editor instance.
253 */
254 void vis_window_prev(Vis*);
255 /**
256 * Change currently focused window, receiving user input.
257 * @param win The window to focus.
258 */
259 void vis_window_focus(Win*);
260 /**
261 * Swap location of two windows.
262 * @param win1 The first window.
263 * @param win2 The second window.
264 */
265 void vis_window_swap(Win *win1, Win *win2);
266 /** @} */
267
268 /*
269 ---
270 ## Information and Messaging
271 */
272
273 /**
274 * @defgroup vis_info Vis Info
275 * @{
276 */
277 /**
278 * Display a user prompt with a certain title.
279 * @param vis The editor instance.
280 * @param title The title of the prompt.
281 * @rst
282 * .. note:: The prompt is currently implemented as a single line height window.
283 * @endrst
284 */
285 void vis_prompt_show(Vis *vis, const char *title);
286
287 /**
288 * Display a single line message.
289 * @param vis The editor instance.
290 * @param msg The message to display.
291 * @rst
292 * .. note:: The message will automatically be hidden upon next input.
293 * @endrst
294 */
295 void vis_info_show(Vis *vis, const char *msg, ...) __attribute__((format(printf, 2, 3)));
296
297 /**
298 * Display arbitrary long message in a dedicated window.
299 * @param vis The editor instance.
300 * @param msg The message to display.
301 */
302 void vis_message_show(Vis *vis, const char *msg);
303 /** @} */
304
305 /*
306 ---
307 ## Text Changes
308 */
309
310 /**
311 * @defgroup vis_changes Vis Changes
312 * @{
313 */
314 /**
315 * Insert data into the file.
316 * @param vis The editor instance.
317 * @param pos The position to insert at.
318 * @param data The data to insert.
319 * @param len The length of the data to insert.
320 */
321 void vis_insert(Vis *vis, size_t pos, const char *data, size_t len);
322 /**
323 * Delete data from the file.
324 * @param vis The editor instance.
325 * @param pos The starting position of the deletion.
326 * @param len The length of the data to delete.
327 */
328 void vis_delete(Vis *vis, size_t pos, size_t len);
329 /**
330 * Replace data in the file.
331 * @param vis The editor instance.
332 * @param pos The position to replace at.
333 * @param data The new data.
334 * @param len The length of the new data.
335 */
336 void vis_replace(Vis *vis, size_t pos, const char *data, size_t len);
337 /**
338 * Perform insertion at all cursor positions.
339 * @param vis The editor instance.
340 * @param data The data to insert.
341 * @param len The length of the data.
342 */
343 void vis_insert_key(Vis *vis, const char *data, size_t len);
344 /**
345 * Perform character substitution at all cursor positions.
346 * @param vis The editor instance.
347 * @param data The character data to substitute.
348 * @param len The length of the data.
349 * @rst
350 * .. note:: Does not replace new line characters.
351 * @endrst
352 */
353 void vis_replace_key(Vis *vis, const char *data, size_t len);
354 /**
355 * Insert a tab at all cursor positions.
356 * @param vis The editor instance.
357 * @rst
358 * .. note:: Performs tab expansion according to current settings.
359 * @endrst
360 */
361 void vis_insert_tab(Vis*);
362 /**
363 * Inserts a new line character at every cursor position.
364 * @param vis The editor instance.
365 * @rst
366 * .. note:: Performs auto indentation according to current settings.
367 * @endrst
368 */
369 void vis_insert_nl(Vis*);
370
371 /** @} */
372
373 /*
374 ---
375 ## Editor Modes
376 */
377
378 /**
379 * @defgroup vis_modes Vis Modes
380 * @{
381 */
382
383 /** Mode specifiers. */
384 enum VisMode {
385 VIS_MODE_NORMAL,
386 VIS_MODE_OPERATOR_PENDING,
387 VIS_MODE_VISUAL,
388 VIS_MODE_VISUAL_LINE, /**< Sub mode of `VIS_MODE_VISUAL`. */
389 VIS_MODE_INSERT,
390 VIS_MODE_REPLACE, /**< Sub mode of `VIS_MODE_INSERT`. */
391 VIS_MODE_INVALID,
392 };
393
394 /**
395 * Switch mode.
396 * @param vis The editor instance.
397 * @param mode The mode to switch to.
398 * @rst
399 * .. note:: Will first trigger the leave event of the currently active
400 * mode, followed by an enter event of the new mode.
401 * No events are emitted, if the specified mode is already active.
402 * @endrst
403 */
404 void vis_mode_switch(Vis *vis, enum VisMode mode);
405 /**
406 * Translate human readable mode name to constant.
407 * @param vis The editor instance.
408 * @param name The name of the mode.
409 */
410 enum VisMode vis_mode_from(Vis *vis, const char *name);
411
412 /** @} */
413
414 /*
415 ---
416 ## Keybinding and Actions
417 */
418
419 /**
420 * @defgroup vis_keybind Vis Keybindings
421 * @{
422 */
423 /**
424 * Create a new key binding.
425 * @param vis The editor instance.
426 */
427 KeyBinding *vis_binding_new(Vis*);
428 /**
429 * Free a key binding.
430 * @param vis The editor instance.
431 * @param binding The key binding to free.
432 */
433 void vis_binding_free(Vis *vis, KeyBinding *binding);
434
435 /**
436 * Set up a key binding.
437 * @param vis The editor instance.
438 * @param mode The mode in which the binding applies.
439 * @param force Whether an existing mapping should be discarded.
440 * @param key The symbolic key to map.
441 * @param binding The binding to map.
442 * @rst
443 * .. note:: ``binding->key`` is always ignored in favor of ``key``.
444 * @endrst
445 */
446 bool vis_mode_map(Vis *vis, enum VisMode mode, bool force, const char *key, const KeyBinding *binding);
447 /**
448 * Analogous to `vis_mode_map`, but window specific.
449 * @param win The window for the mapping.
450 * @param mode The mode in which the binding applies.
451 * @param force Whether an existing mapping should be discarded.
452 * @param key The symbolic key to map.
453 * @param binding The binding to map.
454 */
455 bool vis_window_mode_map(Win *win, enum VisMode mode, bool force, const char *key, const KeyBinding *binding);
456 /**
457 * Unmap a symbolic key in a given mode.
458 * @param vis The editor instance.
459 * @param mode The mode from which to unmap.
460 * @param key The symbolic key to unmap.
461 */
462 bool vis_mode_unmap(Vis *vis, enum VisMode mode, const char *key);
463 /**
464 * Analogous to `vis_mode_unmap`, but window specific.
465 * @param win The window from which to unmap.
466 * @param mode The mode from which to unmap.
467 * @param key The symbolic key to unmap.
468 */
469 bool vis_window_mode_unmap(Win *win, enum VisMode mode, const char *key);
470 /** @} */
471
472 /*
473 ---
474 ## Key Actions
475 */
476
477 /**
478 * @defgroup vis_action Vis Actions
479 * @{
480 */
481 /**
482 * Create new key action.
483 * @param vis The editor instance.
484 * @param name The name to be used as symbolic key when registering.
485 * @param help Optional single line help text.
486 * @param func The function implementing the key action logic.
487 * @param arg Argument passed to function.
488 */
489 KeyAction *vis_action_new(Vis *vis, const char *name, const char *help, KeyActionFunction *func, Arg arg);
490 /**
491 * Free a key action.
492 * @param vis The editor instance.
493 * @param action The key action to free.
494 */
495 void vis_action_free(Vis *vis, KeyAction *action);
496 /**
497 * Register key action.
498 * @param vis The editor instance.
499 * @param keyaction The key action to register.
500 * @rst
501 * .. note:: Makes the key action available under the pseudo key name specified
502 * in ``keyaction->name``.
503 * @endrst
504 */
505 bool vis_action_register(Vis *vis, const KeyAction *keyaction);
506
507 /** @} */
508
509 /*
510 ---
511 ## Keymap
512 */
513
514 /**
515 * @defgroup vis_keymap Vis Keymap
516 * @{
517 */
518
519 /**
520 * Add a key translation.
521 * @param vis The editor instance.
522 * @param key The key to translate.
523 * @param mapping The string to map the key to.
524 */
525 bool vis_keymap_add(Vis *vis, const char *key, const char *mapping);
526 /**
527 * Temporarily disable the keymap for the next key press.
528 * @param vis The editor instance.
529 */
530 void vis_keymap_disable(Vis*);
531
532 /** @} */
533
534 /*
535 ---
536 ## Operators
537 */
538
539 /**
540 * @defgroup vis_operators Vis Operators
541 * @{
542 */
543
544 /** Operator specifiers. */
545 enum VisOperator {
546 VIS_OP_DELETE,
547 VIS_OP_CHANGE,
548 VIS_OP_YANK,
549 VIS_OP_PUT_AFTER,
550 VIS_OP_SHIFT_RIGHT,
551 VIS_OP_SHIFT_LEFT,
552 VIS_OP_JOIN,
553 VIS_OP_MODESWITCH,
554 VIS_OP_REPLACE,
555 VIS_OP_CURSOR_SOL,
556 VIS_OP_INVALID, /* denotes the end of the "real" operators */
557 /* pseudo operators: keep them at the end to save space in array definition */
558 VIS_OP_CURSOR_EOL,
559 VIS_OP_PUT_AFTER_END,
560 VIS_OP_PUT_BEFORE,
561 VIS_OP_PUT_BEFORE_END,
562 VIS_OP_LAST, /* has to be last enum member */
563 };
564
565 typedef struct OperatorContext OperatorContext;
566
567 /**
568 * An operator performs a certain function on a given text range.
569 * @param vis The editor instance.
570 * @param text The text buffer to operate on.
571 * @param context Operator-specific context.
572 * @rst
573 * .. note:: The operator must return the new cursor position or ``EPOS`` if
574 * the cursor should be disposed.
575 * .. note:: The last used operator can be repeated using `vis_repeat`.
576 * @endrst
577 */
578 typedef size_t (VisOperatorFunction)(Vis *vis, Text *text, OperatorContext *context);
579
580 /**
581 * Register an operator.
582 * @param vis The editor instance.
583 * @param func The function implementing the operator logic.
584 * @param context User-supplied context for the operator.
585 * @return Operator ID. Negative values indicate an error, positive ones can be
586 * used with `vis_operator`.
587 */
588 int vis_operator_register(Vis *vis, VisOperatorFunction *func, void *context);
589
590 /**
591 * Set operator to execute.
592 * @param vis The editor instance.
593 * @param op The operator to perform.
594 * @param ... Additional arguments depending on the operator type.
595 *
596 * Has immediate effect if:
597 * - A visual mode is active.
598 * - The same operator was already set (range will be the current line).
599 *
600 * Otherwise the operator will be executed on the range determined by:
601 * - A motion (see `vis_motion`).
602 * - A text object (`vis_textobject`).
603 *
604 * The expected varying arguments are:
605 *
606 * - `VIS_OP_JOIN` a char pointer referring to the text to insert between lines.
607 * - `VIS_OP_MODESWITCH` an ``enum VisMode`` indicating the mode to switch to.
608 * - `VIS_OP_REPLACE` a char pointer referring to the replacement character.
609 */
610 bool vis_operator(Vis *vis, enum VisOperator op, ...);
611
612 /**
613 * Repeat last operator, possibly with a new count if one was provided in the meantime.
614 * @param vis The editor instance.
615 */
616 void vis_repeat(Vis*);
617
618 /**
619 * Cancel pending operator, reset count, motion, text object, register etc.
620 * @param vis The editor instance.
621 */
622 void vis_cancel(Vis*);
623
624 /** @} */
625
626 /*
627 ---
628 ## Motions
629 */
630
631 /**
632 * @defgroup vis_motions Vis Motions
633 * @{
634 */
635
636 /** Motion specifiers. */
637 enum VisMotion {
638 VIS_MOVE_LINE_DOWN,
639 VIS_MOVE_LINE_UP,
640 VIS_MOVE_SCREEN_LINE_UP,
641 VIS_MOVE_SCREEN_LINE_DOWN,
642 VIS_MOVE_SCREEN_LINE_BEGIN,
643 VIS_MOVE_SCREEN_LINE_MIDDLE,
644 VIS_MOVE_SCREEN_LINE_END,
645 VIS_MOVE_LINE_PREV,
646 VIS_MOVE_LINE_BEGIN,
647 VIS_MOVE_LINE_START,
648 VIS_MOVE_LINE_FINISH,
649 VIS_MOVE_LINE_LASTCHAR,
650 VIS_MOVE_LINE_END,
651 VIS_MOVE_LINE_NEXT,
652 VIS_MOVE_LINE,
653 VIS_MOVE_COLUMN,
654 VIS_MOVE_CHAR_PREV,
655 VIS_MOVE_CHAR_NEXT,
656 VIS_MOVE_LINE_CHAR_PREV,
657 VIS_MOVE_LINE_CHAR_NEXT,
658 VIS_MOVE_CODEPOINT_PREV,
659 VIS_MOVE_CODEPOINT_NEXT,
660 VIS_MOVE_WORD_NEXT,
661 VIS_MOVE_WORD_START_NEXT,
662 VIS_MOVE_WORD_END_PREV,
663 VIS_MOVE_WORD_END_NEXT,
664 VIS_MOVE_WORD_START_PREV,
665 VIS_MOVE_LONGWORD_NEXT,
666 VIS_MOVE_LONGWORD_START_PREV,
667 VIS_MOVE_LONGWORD_START_NEXT,
668 VIS_MOVE_LONGWORD_END_PREV,
669 VIS_MOVE_LONGWORD_END_NEXT,
670 VIS_MOVE_SENTENCE_PREV,
671 VIS_MOVE_SENTENCE_NEXT,
672 VIS_MOVE_PARAGRAPH_PREV,
673 VIS_MOVE_PARAGRAPH_NEXT,
674 VIS_MOVE_FUNCTION_START_PREV,
675 VIS_MOVE_FUNCTION_START_NEXT,
676 VIS_MOVE_FUNCTION_END_PREV,
677 VIS_MOVE_FUNCTION_END_NEXT,
678 VIS_MOVE_BLOCK_START,
679 VIS_MOVE_BLOCK_END,
680 VIS_MOVE_PARENTHESIS_START,
681 VIS_MOVE_PARENTHESIS_END,
682 VIS_MOVE_BRACKET_MATCH,
683 VIS_MOVE_TO_LEFT,
684 VIS_MOVE_TO_RIGHT,
685 VIS_MOVE_TO_LINE_LEFT,
686 VIS_MOVE_TO_LINE_RIGHT,
687 VIS_MOVE_TILL_LEFT,
688 VIS_MOVE_TILL_RIGHT,
689 VIS_MOVE_TILL_LINE_LEFT,
690 VIS_MOVE_TILL_LINE_RIGHT,
691 VIS_MOVE_FILE_BEGIN,
692 VIS_MOVE_FILE_END,
693 VIS_MOVE_SEARCH_WORD_FORWARD,
694 VIS_MOVE_SEARCH_WORD_BACKWARD,
695 VIS_MOVE_SEARCH_REPEAT_FORWARD,
696 VIS_MOVE_SEARCH_REPEAT_BACKWARD,
697 VIS_MOVE_WINDOW_LINE_TOP,
698 VIS_MOVE_WINDOW_LINE_MIDDLE,
699 VIS_MOVE_WINDOW_LINE_BOTTOM,
700 VIS_MOVE_CHANGELIST_NEXT,
701 VIS_MOVE_CHANGELIST_PREV,
702 VIS_MOVE_NOP,
703 VIS_MOVE_PERCENT,
704 VIS_MOVE_BYTE,
705 VIS_MOVE_BYTE_LEFT,
706 VIS_MOVE_BYTE_RIGHT,
707 VIS_MOVE_INVALID, /* denotes the end of the "real" motions */
708 /* pseudo motions: keep them at the end to save space in array definition */
709 VIS_MOVE_TOTILL_REPEAT,
710 VIS_MOVE_TOTILL_REVERSE,
711 VIS_MOVE_SEARCH_FORWARD,
712 VIS_MOVE_SEARCH_BACKWARD,
713 VIS_MOVE_SEARCH_REPEAT,
714 VIS_MOVE_SEARCH_REPEAT_REVERSE,
715 VIS_MOVE_LAST, /* denotes the end of all motions */
716 };
717
718 /**
719 * Set motion to perform.
720 * @param vis The editor instance.
721 * @param motion The motion to perform.
722 * @param ... Additional arguments depending on the motion type.
723 *
724 * The following motions take an additional argument:
725 *
726 * - `VIS_MOVE_SEARCH_FORWARD` and `VIS_MOVE_SEARCH_BACKWARD`
727 *
728 * The search pattern as ``const char *``.
729 *
730 * - ``VIS_MOVE_{LEFT,RIGHT}_{TO,TILL}``
731 *
732 * The character to search for as ``const char *``.
733 */
734 bool vis_motion(Vis *vis, enum VisMotion motion, ...);
735
736 enum VisMotionType {
737 VIS_MOTIONTYPE_LINEWISE = 1 << 0,
738 VIS_MOTIONTYPE_CHARWISE = 1 << 1,
739 };
740
741 /**
742 * Force currently specified motion to behave in line or character wise mode.
743 * @param vis The editor instance.
744 * @param type The motion type (line-wise or character-wise).
745 */
746 void vis_motion_type(Vis *vis, enum VisMotionType type);
747
748 /**
749 * Motions take a starting position and transform it to an end position.
750 * @param vis The editor instance.
751 * @param win The window in which the motion is performed.
752 * @param context User-supplied context for the motion.
753 * @param pos The starting position.
754 * @rst
755 * .. note:: Should a motion not be possible, the original position must be returned.
756 * TODO: we might want to change that to ``EPOS``?
757 * @endrst
758 */
759 typedef size_t (VisMotionFunction)(Vis *vis, Win *win, void *context, size_t pos);
760
761 /**
762 * Register a motion function.
763 * @param vis The editor instance.
764 * @param context User-supplied context for the motion.
765 * @param func The function implementing the motion logic.
766 * @return Motion ID. Negative values indicate an error, positive ones can be
767 * used with `vis_motion`.
768 */
769 int vis_motion_register(Vis *vis, void *context, VisMotionFunction *func);
770
771 /** @} */
772
773 /*
774 ---
775 ## Count Iteration
776 */
777
778 /**
779 * @defgroup vis_count Vis Count
780 * @{
781 */
782 /** No count was specified. */
783 #define VIS_COUNT_UNKNOWN (-1)
784 #define VIS_COUNT_DEFAULT(count, def) ((count) == VIS_COUNT_UNKNOWN ? (def) : (count))
785 #define VIS_COUNT_NORMALIZE(count) ((count) < 0 ? VIS_COUNT_UNKNOWN : (count))
786 /**
787 * Set the shell.
788 * @param vis The editor instance.
789 * @param new_shell The new shell to set.
790 */
791 void vis_shell_set(Vis *vis, const char *new_shell);
792
793 typedef struct {
794 Vis *vis;
795 int iteration;
796 int count;
797 } VisCountIterator;
798
799 /**
800 * Get iterator initialized with current count or ``def`` if not specified.
801 * @param vis The editor instance.
802 * @param def The default count if none is specified.
803 */
804 VisCountIterator vis_count_iterator_get(Vis *vis, int def);
805 /**
806 * Get iterator initialized with a count value.
807 * @param vis The editor instance.
808 * @param count The count value to initialize with.
809 */
810 VisCountIterator vis_count_iterator_init(Vis *vis, int count);
811 /**
812 * Increment iterator counter.
813 * @param iter Pointer to the iterator.
814 * @return Whether iteration should continue.
815 * @rst
816 * .. note:: Terminates iteration if the editor was
817 * `interrupted <vis_interrupt>`_ in the meantime.
818 * @endrst
819 */
820 bool vis_count_iterator_next(VisCountIterator *iter);
821
822 /** @} */
823
824 /*
825 ---
826 ## Text Objects
827 */
828
829 /**
830 * @defgroup vis_textobjs Vis Text Objects
831 * @{
832 */
833
834 /** Text object specifier. */
835 enum VisTextObject {
836 VIS_TEXTOBJECT_INNER_WORD,
837 VIS_TEXTOBJECT_OUTER_WORD,
838 VIS_TEXTOBJECT_INNER_LONGWORD,
839 VIS_TEXTOBJECT_OUTER_LONGWORD,
840 VIS_TEXTOBJECT_SENTENCE,
841 VIS_TEXTOBJECT_PARAGRAPH,
842 VIS_TEXTOBJECT_PARAGRAPH_OUTER,
843 VIS_TEXTOBJECT_OUTER_SQUARE_BRACKET,
844 VIS_TEXTOBJECT_INNER_SQUARE_BRACKET,
845 VIS_TEXTOBJECT_OUTER_CURLY_BRACKET,
846 VIS_TEXTOBJECT_INNER_CURLY_BRACKET,
847 VIS_TEXTOBJECT_OUTER_ANGLE_BRACKET,
848 VIS_TEXTOBJECT_INNER_ANGLE_BRACKET,
849 VIS_TEXTOBJECT_OUTER_PARENTHESIS,
850 VIS_TEXTOBJECT_INNER_PARENTHESIS,
851 VIS_TEXTOBJECT_OUTER_QUOTE,
852 VIS_TEXTOBJECT_INNER_QUOTE,
853 VIS_TEXTOBJECT_OUTER_SINGLE_QUOTE,
854 VIS_TEXTOBJECT_INNER_SINGLE_QUOTE,
855 VIS_TEXTOBJECT_OUTER_BACKTICK,
856 VIS_TEXTOBJECT_INNER_BACKTICK,
857 VIS_TEXTOBJECT_OUTER_LINE,
858 VIS_TEXTOBJECT_INNER_LINE,
859 VIS_TEXTOBJECT_INDENTATION,
860 VIS_TEXTOBJECT_SEARCH_FORWARD,
861 VIS_TEXTOBJECT_SEARCH_BACKWARD,
862 VIS_TEXTOBJECT_INVALID,
863 };
864
865 /**
866 * Text objects take a starting position and return a text range.
867 * @param vis The editor instance.
868 * @param win The window in which the text object is applied.
869 * @param context User-supplied context for the text object.
870 * @param pos The starting position.
871 * @rst
872 * .. note:: The originating position does not necessarily have to be contained in
873 * the resulting range.
874 * @endrst
875 */
876 typedef Filerange (VisTextObjectFunction)(Vis *vis, Win *win, void *context, size_t pos);
877
878 /**
879 * Register a new text object.
880 * @param vis The editor instance.
881 * @param type The type of the text object.
882 * @param data User-supplied data for the text object.
883 * @param func The function implementing the text object logic.
884 * @return Text object ID. Negative values indicate an error, positive ones can be
885 * used with `vis_textobject`.
886 */
887 int vis_textobject_register(Vis *vis, int type, void *data, VisTextObjectFunction *func);
888
889 /**
890 * Set text object to use.
891 * @param vis The editor instance.
892 * @param textobj The text object to set.
893 */
894 bool vis_textobject(Vis *vis, enum VisTextObject textobj);
895
896 /** @} */
897
898 /*
899 ---
900 ## Marks
901 */
902
903 /**
904 * @defgroup vis_marks Vis Marks
905 * @{
906 */
907
908 /** Mark specifiers. */
909 enum VisMark {
910 VIS_MARK_DEFAULT,
911 VIS_MARK_SELECTION,
912 VIS_MARK_a, VIS_MARK_b, VIS_MARK_c, VIS_MARK_d, VIS_MARK_e,
913 VIS_MARK_f, VIS_MARK_g, VIS_MARK_h, VIS_MARK_i, VIS_MARK_j,
914 VIS_MARK_k, VIS_MARK_l, VIS_MARK_m, VIS_MARK_n, VIS_MARK_o,
915 VIS_MARK_p, VIS_MARK_q, VIS_MARK_r, VIS_MARK_s, VIS_MARK_t,
916 VIS_MARK_u, VIS_MARK_v, VIS_MARK_w, VIS_MARK_x, VIS_MARK_y,
917 VIS_MARK_z,
918 VIS_MARK_INVALID, /* has to be the last enum member */
919 };
920
921 /**
922 * Translate between single character mark name and corresponding constant.
923 * @param vis The editor instance.
924 * @param mark The character representing the mark.
925 */
926 enum VisMark vis_mark_from(Vis *vis, char mark);
927 /**
928 * Translate between mark constant and single character mark name.
929 * @param vis The editor instance.
930 * @param mark The mark constant.
931 */
932 char vis_mark_to(Vis *vis, enum VisMark mark);
933 /**
934 * Specify mark to use.
935 * @param vis The editor instance.
936 * @param mark The mark to use.
937 * @rst
938 * .. note:: If none is specified `VIS_MARK_DEFAULT` will be used.
939 * @endrst
940 */
941 void vis_mark(Vis *vis, enum VisMark mark);
942 /**
943 * Get the currently used mark.
944 * @param vis The editor instance.
945 */
946 enum VisMark vis_mark_used(Vis*);
947 /**
948 * Store a set of ``Filerange``s in a mark.
949 *
950 * @param win The window whose selections to store.
951 * @param id The mark ID to use.
952 * @param sel The array containing the file ranges.
953 */
954 void vis_mark_set(Win *win, enum VisMark id, Array *sel);
955 /**
956 * Get an array of file ranges stored in the mark.
957 * @param win The window whose mark to retrieve.
958 * @param id The mark ID to retrieve.
959 * @return An array of file ranges.
960 * @rst
961 * .. warning:: The caller must eventually free the Array by calling
962 * ``array_release``.
963 * @endrst
964 */
965 Array vis_mark_get(Win *win, enum VisMark id);
966 /**
967 * Normalize an Array of Fileranges.
968 * @param array The array of file ranges to normalize.
969 *
970 * Removes invalid ranges, merges overlapping ones and sorts
971 * according to the start position.
972 */
973 void vis_mark_normalize(Array *array);
974 /**
975 * Add selections of focused window to jump list.
976 * @param vis The editor instance.
977 */
978 bool vis_jumplist_save(Vis*);
979 /**
980 * Navigate jump list backwards.
981 * @param vis The editor instance.
982 */
983 bool vis_jumplist_prev(Vis*);
984 /**
985 * Navigate jump list forwards.
986 * @param vis The editor instance.
987 */
988 bool vis_jumplist_next(Vis*);
989 /** @} */
990
991 /*
992 ---
993 ## Registers
994 */
995
996 /**
997 * @defgroup vis_registers Vis Registers
998 * @{
999 */
1000
1001 /** Register specifiers. */
1002 enum VisRegister {
1003 VIS_REG_DEFAULT, /* used when no other register is specified */
1004 VIS_REG_ZERO, /* yank register */
1005 VIS_REG_AMPERSAND, /* last regex match */
1006 VIS_REG_1, /* 1-9 last sub-expression matches */
1007 VIS_REG_2,
1008 VIS_REG_3,
1009 VIS_REG_4,
1010 VIS_REG_5,
1011 VIS_REG_6,
1012 VIS_REG_7,
1013 VIS_REG_8,
1014 VIS_REG_9,
1015 VIS_REG_BLACKHOLE, /* /dev/null register */
1016 VIS_REG_CLIPBOARD, /* system clipboard register */
1017 VIS_REG_PRIMARY, /* system primary clipboard register */
1018 VIS_REG_DOT, /* last inserted text, copy of VIS_MACRO_OPERATOR */
1019 VIS_REG_SEARCH, /* last used search pattern "/ */
1020 VIS_REG_COMMAND, /* last used :-command ": */
1021 VIS_REG_SHELL, /* last used shell command given to either <, >, |, or ! */
1022 VIS_REG_NUMBER, /* cursor number */
1023 VIS_REG_a, VIS_REG_b, VIS_REG_c, VIS_REG_d, VIS_REG_e,
1024 VIS_REG_f, VIS_REG_g, VIS_REG_h, VIS_REG_i, VIS_REG_j,
1025 VIS_REG_k, VIS_REG_l, VIS_REG_m, VIS_REG_n, VIS_REG_o,
1026 VIS_REG_p, VIS_REG_q, VIS_REG_r, VIS_REG_s, VIS_REG_t,
1027 VIS_REG_u, VIS_REG_v, VIS_REG_w, VIS_REG_x, VIS_REG_y,
1028 VIS_REG_z,
1029 VIS_MACRO_OPERATOR, /* records entered keys after an operator */
1030 VIS_REG_PROMPT, /* internal register which shadows DEFAULT in PROMPT mode */
1031 VIS_REG_INVALID, /* has to be the last 'real' register */
1032 VIS_REG_A, VIS_REG_B, VIS_REG_C, VIS_REG_D, VIS_REG_E,
1033 VIS_REG_F, VIS_REG_G, VIS_REG_H, VIS_REG_I, VIS_REG_J,
1034 VIS_REG_K, VIS_REG_L, VIS_REG_M, VIS_REG_N, VIS_REG_O,
1035 VIS_REG_P, VIS_REG_Q, VIS_REG_R, VIS_REG_S, VIS_REG_T,
1036 VIS_REG_U, VIS_REG_V, VIS_REG_W, VIS_REG_X, VIS_REG_Y,
1037 VIS_REG_Z,
1038 VIS_MACRO_LAST_RECORDED, /* pseudo macro referring to last recorded one */
1039 };
1040
1041 /**
1042 * Translate between single character register name and corresponding constant.
1043 * @param vis The editor instance.
1044 * @param reg The character representing the register.
1045 */
1046 enum VisRegister vis_register_from(Vis *vis, char reg);
1047 /**
1048 * Translate between register constant and single character register name.
1049 * @param vis The editor instance.
1050 * @param reg The register constant.
1051 */
1052 char vis_register_to(Vis *vis, enum VisRegister reg);
1053 /**
1054 * Specify register to use.
1055 * @param vis The editor instance.
1056 * @param reg The register to use.
1057 * @rst
1058 * .. note:: If none is specified `VIS_REG_DEFAULT` will be used.
1059 * @endrst
1060 */
1061 void vis_register(Vis *vis, enum VisRegister reg);
1062 /**
1063 * Get the currently used register.
1064 * @param vis The editor instance.
1065 */
1066 enum VisRegister vis_register_used(Vis*);
1067 /**
1068 * Get register content.
1069 * @param vis The editor instance.
1070 * @param id The register ID to retrieve.
1071 * @return An array of ``TextString`` structs.
1072 * @rst
1073 * .. warning:: The caller must eventually free the array resources using
1074 * ``array_release``.
1075 * @endrst
1076 */
1077 Array vis_register_get(Vis *vis, enum VisRegister id);
1078 /**
1079 * Set register content.
1080 * @param vis The editor instance.
1081 * @param id The register ID to set.
1082 * @param data The array comprised of ``TextString`` structs.
1083 */
1084 bool vis_register_set(Vis *vis, enum VisRegister id, Array *data);
1085 /** @} */
1086
1087 /*
1088 ---
1089 ## Macros
1090 */
1091
1092 /**
1093 * @defgroup vis_macros Vis Macros
1094 * @{
1095 */
1096 /**
1097 * Start recording a macro.
1098 * @param vis The editor instance.
1099 * @param reg The register to record the macro into.
1100 * @rst
1101 * .. note:: Fails if a recording is already ongoing.
1102 * @endrst
1103 */
1104 bool vis_macro_record(Vis *vis, enum VisRegister reg);
1105 /**
1106 * Stop recording, fails if there is nothing to stop.
1107 * @param vis The editor instance.
1108 */
1109 bool vis_macro_record_stop(Vis*);
1110 /**
1111 * Check whether a recording is currently ongoing.
1112 * @param vis The editor instance.
1113 */
1114 bool vis_macro_recording(Vis*);
1115 /**
1116 * Replay a macro.
1117 * @param vis The editor instance.
1118 * @param reg The register containing the macro to replay.
1119 * @rst
1120 * .. note:: A macro currently being recorded can not be replayed.
1121 * @endrst
1122 */
1123 bool vis_macro_replay(Vis *vis, enum VisRegister reg);
1124
1125 /** @} */
1126
1127 /*
1128 ---
1129 ## Commands
1130 */
1131
1132 /**
1133 * @defgroup vis_cmds Vis Commands
1134 * @{
1135 */
1136
1137 /**
1138 * Execute a ``:``-command.
1139 * @param vis The editor instance.
1140 * @param cmd The command string to execute.
1141 */
1142 bool vis_cmd(Vis *vis, const char *cmd);
1143
1144 /** Command handler function. */
1145 typedef bool (VisCommandFunction)(Vis*, Win*, void *data, bool force,
1146 const char *argv[], Selection*, Filerange*);
1147 /**
1148 * Register new ``:``-command.
1149 * @param vis The editor instance.
1150 * @param name The command name.
1151 * @param help Optional single line help text.
1152 * @param context User supplied context pointer passed to the handler function.
1153 * @param func The function implementing the command logic.
1154 * @rst
1155 * .. note:: Any unique prefix of the command name will invoke the command.
1156 * @endrst
1157 */
1158 bool vis_cmd_register(Vis *vis, const char *name, const char *help, void *context, VisCommandFunction *func);
1159
1160 /**
1161 * Unregister ``:``-command.
1162 * @param vis The editor instance.
1163 * @param name The name of the command to unregister.
1164 */
1165 bool vis_cmd_unregister(Vis *vis, const char *name);
1166
1167 /** @} */
1168
1169 /*
1170 ---
1171 ## Options
1172 */
1173
1174 /**
1175 * @defgroup vis_options Vis Options
1176 * @{
1177 */
1178 /** Option properties. */
1179 enum VisOption {
1180 VIS_OPTION_TYPE_BOOL = 1 << 0,
1181 VIS_OPTION_TYPE_STRING = 1 << 1,
1182 VIS_OPTION_TYPE_NUMBER = 1 << 2,
1183 VIS_OPTION_VALUE_OPTIONAL = 1 << 3,
1184 VIS_OPTION_NEED_WINDOW = 1 << 4,
1185 VIS_OPTION_DEPRECATED = 1 << 5,
1186 };
1187
1188 /**
1189 * Option handler function.
1190 * @param vis The editor instance.
1191 * @param win The window to which option should apply, might be ``NULL``.
1192 * @param context User provided context pointer as given to `vis_option_register`.
1193 * @param force Whether the option was specified with a bang ``!``.
1194 * @param option_flags The applicable option flags.
1195 * @param name Name of option which was set.
1196 * @param value The new option value.
1197 */
1198 typedef bool (VisOptionFunction)(Vis *vis, Win *win, void *context, bool force,
1199 enum VisOption option_flags, const char *name, Arg *value);
1200
1201 /**
1202 * Register a new ``:set`` option.
1203 * @param vis The editor instance.
1204 * @param names A ``NULL`` terminated array of option names.
1205 * @param option_flags The applicable option flags.
1206 * @param func The function handling the option.
1207 * @param context User supplied context pointer passed to the handler function.
1208 * @param help Optional single line help text.
1209 * @rst
1210 * .. note:: Fails if any of the given option names is already registered.
1211 * @endrst
1212 */
1213 bool vis_option_register(Vis *vis, const char *names[], enum VisOption option_flags,
1214 VisOptionFunction *func, void *context, const char *help);
1215 /**
1216 * Unregister an existing ``:set`` option.
1217 * @param vis The editor instance.
1218 * @param name The name of the option to unregister.
1219 * @rst
1220 * .. note:: Also unregisters all aliases as given to `vis_option_register`.
1221 * @endrst
1222 */
1223 bool vis_option_unregister(Vis *vis, const char *name);
1224
1225 /**
1226 * Execute any kind (``:``, ``?``, ``/``) of prompt command
1227 * @param vis The editor instance.
1228 * @param cmd The command string.
1229 */
1230 bool vis_prompt_cmd(Vis *vis, const char *cmd);
1231
1232 /**
1233 * Pipe a given file range to an external process.
1234 * @param vis The editor instance.
1235 * @param file The file to pipe.
1236 * @param range The file range to pipe.
1237 * @param argv Argument list, must be ``NULL`` terminated.
1238 * @param stdout_context Context for stdout callback.
1239 * @param read_stdout Callback for stdout data.
1240 * @param stderr_context Context for stderr callback.
1241 * @param read_stderr Callback for stderr data.
1242 * @param fullscreen Whether the external process is a fullscreen program (e.g. curses based)
1243 *
1244 * If the range is invalid 'interactive' mode is enabled, meaning that
1245 * stdin and stderr are passed through the underlying command, stdout
1246 * points to vis' stderr.
1247 *
1248 * If ``argv`` contains only one non-NULL element the command is executed
1249 * through an intermediate shell (using ``/bin/sh -c argv[0]``) that is
1250 * argument expansion is performed by the shell. Otherwise the argument
1251 * list will be passed unmodified to ``execvp(argv[0], argv)``.
1252 *
1253 * If the ``read_stdout`` and ``read_stderr`` callbacks are non-NULL they
1254 * will be invoked when output from the forked process is available.
1255 *
1256 * If ``fullscreen`` is set to ``true`` the external process is assumed to
1257 * be a fullscreen program (e.g. curses based) and the ui context is
1258 * restored accordingly.
1259 *
1260 * @rst
1261 * .. warning:: The editor core is blocked until this function returns.
1262 * @endrst
1263 *
1264 * @return The exit status of the forked process.
1265 */
1266 int vis_pipe(Vis *vis, File *file, Filerange *range, const char *argv[],
1267 void *stdout_context, ssize_t (*read_stdout)(void *stdout_context, char *data, size_t len),
1268 void *stderr_context, ssize_t (*read_stderr)(void *stderr_context, char *data, size_t len),
1269 bool fullscreen);
1270
1271 /**
1272 * Pipe a Filerange to an external process, return its exit status and capture
1273 * everything that is written to stdout/stderr.
1274 * @param vis The editor instance.
1275 * @param file The file to pipe.
1276 * @param range The file range to pipe.
1277 * @param argv Argument list, must be ``NULL`` terminated.
1278 * @param out Data written to ``stdout``, will be ``NUL`` terminated.
1279 * @param err Data written to ``stderr``, will be ``NUL`` terminated.
1280 * @param fullscreen Whether the external process is a fullscreen program (e.g. curses based)
1281 * @rst
1282 * .. warning:: The pointers stored in ``out`` and ``err`` need to be `free(3)`-ed
1283 * by the caller.
1284 * @endrst
1285 */
1286 int vis_pipe_collect(Vis *vis, File *file, Filerange *range, const char *argv[], char **out, char **err, bool fullscreen);
1287
1288 /**
1289 * Pipe a buffer to an external process, return its exit status and capture
1290 * everything that is written to stdout/stderr.
1291 * @param vis The editor instance.
1292 * @param buf The buffer to pipe.
1293 * @param argv Argument list, must be ``NULL`` terminated.
1294 * @param out Data written to ``stdout``, will be ``NUL`` terminated.
1295 * @param err Data written to ``stderr``, will be ``NUL`` terminated.
1296 * @param fullscreen Whether the external process is a fullscreen program (e.g. curses based)
1297 * @rst
1298 * .. warning:: The pointers stored in ``out`` and ``err`` need to be `free(3)`-ed
1299 * by the caller.
1300 * @endrst
1301 */
1302 int vis_pipe_buf_collect(Vis *vis, const char *buf, const char *argv[], char **out, char **err, bool fullscreen);
1303
1304 /** @} */
1305
1306 /*
1307 ---
1308 ## Keys
1309 */
1310
1311 /**
1312 * @defgroup vis_keys Vis Keys
1313 * @{
1314 */
1315 /**
1316 * Advance to the start of the next symbolic key.
1317 * @param vis The editor instance.
1318 * @param keys The current symbolic key string.
1319 *
1320 * Given the start of a symbolic key, returns a pointer to the start of the one
1321 * immediately following it.
1322 */
1323 const char *vis_keys_next(Vis *vis, const char *keys);
1324 /**
1325 * Convert next symbolic key to an Unicode code point, returns ``-1`` for unknown keys.
1326 * @param vis The editor instance.
1327 * @param keys The symbolic key string.
1328 */
1329 long vis_keys_codepoint(Vis *vis, const char *keys);
1330 /**
1331 * Convert next symbolic key to a UTF-8 sequence.
1332 * @param vis The editor instance.
1333 * @param keys The symbolic key string.
1334 * @param utf8 Buffer to store the UTF-8 sequence.
1335 * @return Whether conversion was successful, if not ``utf8`` is left unmodified.
1336 * @rst
1337 * .. note:: Guarantees that ``utf8`` is NUL terminated on success.
1338 * @endrst
1339 */
1340 bool vis_keys_utf8(Vis *vis, const char *keys, char utf8[static UTFmax+1]);
1341 /**
1342 * Process symbolic keys as if they were user originated input.
1343 * @param vis The editor instance.
1344 * @param keys The symbolic key string to feed.
1345 */
1346 void vis_keys_feed(Vis *vis, const char *keys);
1347 /** @} */
1348
1349 /*
1350 ---
1351 ## Miscellaneous
1352 */
1353
1354 /**
1355 * @defgroup vis_misc Vis Miscellaneous
1356 * @{
1357 */
1358
1359 /**
1360 * Get a regex object matching pattern.
1361 * @param vis The editor instance.
1362 * @param pattern The regex pattern to compile, if ``NULL`` the most recently used
1363 * one is substituted.
1364 * @return A Regex object or ``NULL`` in case of an error.
1365 * @rst
1366 * .. warning:: The caller must free the regex object using `text_regex_free`.
1367 * @endrst
1368 */
1369 Regex *vis_regex(Vis *vis, const char *pattern);
1370
1371 /**
1372 * Take an undo snapshot to which we can later revert.
1373 * @param vis The editor instance.
1374 * @param file The file for which to take a snapshot.
1375 * @rst
1376 * .. note:: Does nothing when invoked while replaying a macro.
1377 * @endrst
1378 */
1379 void vis_file_snapshot(Vis *vis, File *file);
1380 /** @} */
1381
1382 /* TODO: expose proper API to iterate through files etc */
1383 Text *vis_text(Vis*);
1384 View *vis_view(Vis*);
1385
1386 #endif