vis: use strncpy to copy into fixed sized buffer
[vis.git] / vis.h
blob178aae222453029fa62a1f0299bdbb01af949e87
1 #ifndef VIS_H
2 #define VIS_H
4 #include <signal.h>
5 #include <stddef.h>
6 #include <stdbool.h>
8 typedef struct Vis Vis;
9 typedef struct File File;
10 typedef struct Win Win;
12 #include "ui.h"
13 #include "view.h"
14 #include "text-regex.h"
15 #include "libutf.h"
16 #include "array.h"
18 #ifndef CONFIG_HELP
19 #define CONFIG_HELP 1
20 #endif
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
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
40 /* maximum bytes needed for string representation of a (pseudo) key */
41 #define VIS_KEY_LENGTH_MAX 64
43 /**
44 * Editor event handlers.
46 typedef struct {
47 void (*init)(Vis*);
48 void (*start)(Vis*);
49 void (*quit)(Vis*);
50 void (*mode_insert_input)(Vis*, const char *key, size_t len);
51 void (*mode_replace_input)(Vis*, const char *key, size_t len);
52 void (*file_open)(Vis*, File*);
53 bool (*file_save_pre)(Vis*, File*, const char *path);
54 void (*file_save_post)(Vis*, File*, const char *path);
55 void (*file_close)(Vis*, File*);
56 void (*win_open)(Vis*, Win*);
57 void (*win_close)(Vis*, Win*);
58 void (*win_highlight)(Vis*, Win*);
59 void (*win_status)(Vis*, Win*);
60 } VisEvent;
62 /** Union used to pass arguments to key action functions. */
63 typedef union {
64 bool b;
65 int i;
66 const char *s;
67 const void *v;
68 void (*w)(View*);
69 void (*f)(Vis*);
70 Filerange (*combine)(const Filerange*, const Filerange*);
71 } Arg;
73 /**
74 * Key action handling function.
75 * @param keys Input queue content *after* the binding which invoked this function.
76 * @rst
77 * .. note:: An empty string ``""`` indicates that no further input is available.
78 * @endrst
79 * @return Pointer to first non-cosumed key.
80 * @rst
81 * .. warning:: Must be in range ``[keys, keys+strlen(keys)]`` or ``NULL`` to
82 * indicate that not enough input was available. In the latter case
83 * the function will be called again once more input has been received.
84 * @endrst
85 * @ingroup vis_action
87 typedef const char *KeyActionFunction(Vis*, const char *keys, const Arg*);
89 /** Key action definition. */
90 typedef struct {
91 const char *name; /**< Name of a pseudo key ``<name>`` which can be used in mappings. */
92 VIS_HELP_DECL(const char *help;) /**< One line human readable description, displayed by ``:help``. */
93 KeyActionFunction *func; /**< Key action implementation function. */
94 Arg arg; /**< Options passes as last argument to ``func``. */
95 } KeyAction;
97 /**
98 * A key binding, refers to an action or an alias
99 * @rst
100 * .. note:: Either ``action`` or ``alias`` must be ``NULL``.
101 * @endrst
103 typedef struct {
104 const char *key; /**< Symbolic key to trigger this binding. */
105 const KeyAction *action; /**< Action to invoke when triggering this binding. */
106 const char *alias; /**< Replaces ``key`` with ``alias`` at the front of the input queue. */
107 } KeyBinding;
110 * @defgroup vis_lifecycle
111 * @{
113 /** Create a new editor instance using the given user interface and event handlers. */
114 Vis *vis_new(Ui*, VisEvent*);
115 /** Free all resources associated with this editor instance, terminates UI. */
116 void vis_free(Vis*);
118 * Enter main loop, start processing user input.
119 * @return The editor exit status code.
121 int vis_run(Vis*);
122 /** Terminate editing session, the given ``status`` will be the return value of `vis_run`. */
123 void vis_exit(Vis*, int status);
125 * Emergency exit, print given message, perform minimal UI cleanup and exit process.
126 * @rst
127 * .. note:: This function does not return.
128 * @endrst
130 void vis_die(Vis*, const char *msg, ...) __attribute__((noreturn,format(printf, 2, 3)));
133 * Temporarily supsend the editor process.
134 * @rst
135 * .. note:: This function will generate a ``SIGTSTP`` signal.
136 * @endrst
138 void vis_suspend(Vis*);
140 * Resume editor process.
141 * @rst
142 * .. note:: This function is usually called in response to a ``SIGCONT`` signal.
143 * @endrst
145 void vis_resume(Vis*);
147 * Inform the editor core that a signal occured.
148 * @return Whether the signal was handled.
149 * @rst
150 * .. note:: Being designed as a library the editor core does *not* register any
151 * signal handlers on its own.
152 * .. note:: The remaining arguments match the prototype of ``sa_sigaction`` as
153 * specified in `sigaction(2)`.
154 * @endrst
156 bool vis_signal_handler(Vis*, int signum, const siginfo_t *siginfo, const void *context);
158 * Interrupt long running operation.
159 * @rst
160 * .. warning:: There is no guarantee that a long running operation is actually
161 * interrupted. It is analogous to cooperative multitasking where
162 * the operation has to voluntarily yield control.
163 * .. note:: It is invoked from `vis_signal_handler` when receiving ``SIGINT``.
164 * @endrst
166 void vis_interrupt(Vis*);
167 /** Check whether interruption was requested. */
168 bool vis_interrupt_requested(Vis*);
170 * @}
171 * @defgroup vis_draw
172 * @{
174 /** Draw user interface. */
175 void vis_draw(Vis*);
176 /** Completely redraw user interface. */
177 void vis_redraw(Vis*);
178 /** Blit user interface state to output device. */
179 void vis_update(Vis*);
181 * @}
182 * @defgroup vis_windows
183 * @{
186 * Create a new window and load the given file.
187 * @param filename If ``NULL`` a unamed, empty buffer is created.
188 * @rst
189 * .. note:: If the given file name is already opened in another window,
190 * the underlying File object is shared.
191 * .. warning:: This duplication detection is currently based on normalized,
192 * absolute file names. TODO: compare inodes instead.
193 * @endrst
195 bool vis_window_new(Vis*, const char *filename);
197 * Create a new window associated with a file descriptor.
198 * @rst
199 * .. note:: No data is read from `fd`, but write commands without an
200 * explicit filename will instead write to the file descriptor.
201 * @endrst
203 bool vis_window_new_fd(Vis*, int fd);
204 /** Reload the file currently displayed in the window from disk. */
205 bool vis_window_reload(Win*);
206 /** Check whether closing the window would loose unsaved changes. */
207 bool vis_window_closable(Win*);
208 /** Close window, redraw user interface. */
209 void vis_window_close(Win*);
210 /** Split the window, shares the underlying file object. */
211 bool vis_window_split(Win*);
212 /** Change status message of this window. */
213 void vis_window_status(Win*, const char *status);
214 void vis_window_draw(Win*);
215 void vis_window_invalidate(Win*);
216 /** Focus next window. */
217 void vis_window_next(Vis*);
218 /** Focus previous window. */
219 void vis_window_prev(Vis*);
220 /** Change currently focused window, receiving user input. */
221 void vis_window_focus(Win*);
222 /** Swap location of two windows. */
223 void vis_window_swap(Win*, Win*);
224 /** Query window dimension. */
225 int vis_window_width_get(const Win*);
226 /** Query window dimension. */
227 int vis_window_height_get(const Win*);
229 * @}
230 * @defgroup vis_info
231 * @{
234 * Display a user prompt with a certain title.
235 * @rst
236 * .. note:: The prompt is currently implemented as a single line height window.
237 * @endrst
239 void vis_prompt_show(Vis*, const char *title);
242 * Display a single line message.
243 * @rst
244 * .. note:: The message will automatically be hidden upon next input.
245 * @endrst
247 void vis_info_show(Vis*, const char *msg, ...) __attribute__((format(printf, 2, 3)));
248 /** Hide informational message. */
249 void vis_info_hide(Vis*);
251 /** Display arbitrary long message in a dedicated window. */
252 void vis_message_show(Vis*, const char *msg);
253 /** Close message window. */
254 void vis_message_hide(Vis*);
256 * @}
257 * @defgroup vis_changes
258 * @{
260 void vis_insert(Vis*, size_t pos, const char *data, size_t len);
261 void vis_delete(Vis*, size_t pos, size_t len);
262 void vis_replace(Vis*, size_t pos, const char *data, size_t len);
263 /** Perform insertion at all cursor positions. */
264 void vis_insert_key(Vis*, const char *data, size_t len);
266 * Perform character subsitution at all cursor positions.
267 * @rst
268 * .. note:: Does not replace new line characters.
269 * @endrst
271 void vis_replace_key(Vis*, const char *data, size_t len);
273 * Insert a tab at all cursor positions.
274 * @rst
275 * .. note:: Performs tab expansion according to current settings.
276 * @endrst
278 void vis_insert_tab(Vis*);
280 * Inserts a new line character at every cursor position.
281 * @rst
282 * .. note:: Performs auto indentation according to current settings.
283 * @endrst
285 void vis_insert_nl(Vis*);
287 /** @} */
288 /** Mode specifiers. */
289 enum VisMode {
290 VIS_MODE_NORMAL,
291 VIS_MODE_OPERATOR_PENDING,
292 VIS_MODE_VISUAL,
293 VIS_MODE_VISUAL_LINE, /**< Sub mode of `VIS_MODE_VISUAL`. */
294 VIS_MODE_INSERT,
295 VIS_MODE_REPLACE, /**< Sub mode of `VIS_MODE_INSERT`. */
296 VIS_MODE_INVALID,
300 * @defgroup vis_modes
301 * @{
304 * Switch mode.
305 * @rst
306 * .. note:: Will first trigger the leave event of the currently active
307 * mode, followed by an enter event of the new mode.
308 * No events are emitted, if the specified mode is already active.
309 * @endrst
311 void vis_mode_switch(Vis*, enum VisMode);
312 /** Get currently active mode. */
313 enum VisMode vis_mode_get(Vis*);
314 /** Translate human readable mode name to constant. */
315 enum VisMode vis_mode_from(Vis*, const char *name);
318 * @}
319 * @defgroup vis_keybind
320 * @{
322 KeyBinding *vis_binding_new(Vis*);
323 void vis_binding_free(Vis*, KeyBinding*);
326 * Set up a key binding.
327 * @param force Whether an existing mapping should be discarded.
328 * @param key The symbolic key to map.
329 * @param binding The binding to map.
330 * @rst
331 * .. note:: ``binding->key`` is always ignored in favor of ``key``.
332 * @endrst
334 bool vis_mode_map(Vis*, enum VisMode, bool force, const char *key, const KeyBinding*);
335 /** Analogous to `vis_mode_map`, but window specific. */
336 bool vis_window_mode_map(Win*, enum VisMode, bool force, const char *key, const KeyBinding*);
337 /** Unmap a symbolic key in a given mode. */
338 bool vis_mode_unmap(Vis*, enum VisMode, const char *key);
339 /** Analogous to `vis_mode_unmap`, but window specific. */
340 bool vis_window_mode_unmap(Win*, enum VisMode, const char *key);
342 * @}
343 * @defgroup vis_action
344 * @{
347 * Create new key action.
348 * @param name The name to be used as symbolic key when registering.
349 * @param help Optional single line help text.
350 * @param func The function implementing the key action logic.
351 * @param arg Argument passed to function.
353 KeyAction *vis_action_new(Vis*, const char *name, const char *help, KeyActionFunction*, Arg);
354 void vis_action_free(Vis*, KeyAction*);
356 * Register key action.
357 * @rst
358 * .. note:: Makes the key action available under the pseudo key name specified
359 * in ``keyaction->name``.
360 * @endrst
362 bool vis_action_register(Vis*, const KeyAction*);
365 * @}
366 * @defgroup vis_keymap
367 * @{
370 /** Add a key translation. */
371 bool vis_keymap_add(Vis*, const char *key, const char *mapping);
372 /** Temporarily disable the keymap for the next key press. */
373 void vis_keymap_disable(Vis*);
375 /** @} */
376 /** Operator specifiers. */
377 enum VisOperator {
378 VIS_OP_DELETE,
379 VIS_OP_CHANGE,
380 VIS_OP_YANK,
381 VIS_OP_PUT_AFTER,
382 VIS_OP_SHIFT_RIGHT,
383 VIS_OP_SHIFT_LEFT,
384 VIS_OP_JOIN,
385 VIS_OP_MODESWITCH,
386 VIS_OP_REPLACE,
387 VIS_OP_CURSOR_SOL,
388 VIS_OP_CASE_SWAP,
389 VIS_OP_FILTER,
390 VIS_OP_INVALID, /* denotes the end of the "real" operators */
391 /* pseudo operators: keep them at the end to save space in array definition */
392 VIS_OP_CASE_LOWER,
393 VIS_OP_CASE_UPPER,
394 VIS_OP_CURSOR_EOL,
395 VIS_OP_PUT_AFTER_END,
396 VIS_OP_PUT_BEFORE,
397 VIS_OP_PUT_BEFORE_END,
398 VIS_OP_LAST, /* has to be last enum member */
402 * @defgroup vis_operators
403 * @{
405 typedef struct OperatorContext OperatorContext;
408 * An operator performs a certain function on a given text range.
409 * @rst
410 * .. note:: The operator must return the new cursor position or ``EPOS`` if
411 * the cursor should be disposed.
412 * .. note:: The last used operator can be repeated using `vis_repeat`.
413 * @endrst
415 typedef size_t (VisOperatorFunction)(Vis*, Text*, OperatorContext*);
418 * Register an operator.
419 * @return Operator ID. Negative values indicate an error, positive ones can be
420 * used with `vis_operator`.
422 int vis_operator_register(Vis*, VisOperatorFunction*, void *context);
425 * Set operator to execute.
427 * Has immediate effect if:
428 * - A visual mode is active.
429 * - The same operator was already set (range will be the current line).
431 * Otherwise the operator will be executed on the range determinded by:
432 * - A motion (see `vis_motion`).
433 * - A text object (`vis_textobject`).
435 * The expected varying arguments are:
437 * - `VIS_OP_FILTER` a char pointer referring to the command to run.
438 * - `VIS_OP_JOIN` a char pointer referring to the text to insert between lines.
439 * - `VIS_OP_MODESWITCH` an ``enum VisMode`` indicating the mode to switch to.
440 * - `VIS_OP_REPLACE` a char pointer reffering to the replacement character.
442 bool vis_operator(Vis*, enum VisOperator, ...);
444 /** Repeat last operator, possibly with a new count if one was provided in the meantime. */
445 void vis_repeat(Vis*);
447 /** Cancel pending operator, reset count, motion, text object, register etc. */
448 void vis_cancel(Vis*);
450 /** @} */
451 /** Motion specifiers. */
452 enum VisMotion {
453 VIS_MOVE_LINE_DOWN,
454 VIS_MOVE_LINE_UP,
455 VIS_MOVE_SCREEN_LINE_UP,
456 VIS_MOVE_SCREEN_LINE_DOWN,
457 VIS_MOVE_SCREEN_LINE_BEGIN,
458 VIS_MOVE_SCREEN_LINE_MIDDLE,
459 VIS_MOVE_SCREEN_LINE_END,
460 VIS_MOVE_LINE_PREV,
461 VIS_MOVE_LINE_BEGIN,
462 VIS_MOVE_LINE_START,
463 VIS_MOVE_LINE_FINISH,
464 VIS_MOVE_LINE_LASTCHAR,
465 VIS_MOVE_LINE_END,
466 VIS_MOVE_LINE_NEXT,
467 VIS_MOVE_LINE,
468 VIS_MOVE_COLUMN,
469 VIS_MOVE_CHAR_PREV,
470 VIS_MOVE_CHAR_NEXT,
471 VIS_MOVE_LINE_CHAR_PREV,
472 VIS_MOVE_LINE_CHAR_NEXT,
473 VIS_MOVE_CODEPOINT_PREV,
474 VIS_MOVE_CODEPOINT_NEXT,
475 VIS_MOVE_WORD_NEXT,
476 VIS_MOVE_WORD_START_NEXT,
477 VIS_MOVE_WORD_END_PREV,
478 VIS_MOVE_WORD_END_NEXT,
479 VIS_MOVE_WORD_START_PREV,
480 VIS_MOVE_LONGWORD_NEXT,
481 VIS_MOVE_LONGWORD_START_PREV,
482 VIS_MOVE_LONGWORD_START_NEXT,
483 VIS_MOVE_LONGWORD_END_PREV,
484 VIS_MOVE_LONGWORD_END_NEXT,
485 VIS_MOVE_SENTENCE_PREV,
486 VIS_MOVE_SENTENCE_NEXT,
487 VIS_MOVE_PARAGRAPH_PREV,
488 VIS_MOVE_PARAGRAPH_NEXT,
489 VIS_MOVE_FUNCTION_START_PREV,
490 VIS_MOVE_FUNCTION_START_NEXT,
491 VIS_MOVE_FUNCTION_END_PREV,
492 VIS_MOVE_FUNCTION_END_NEXT,
493 VIS_MOVE_BLOCK_START,
494 VIS_MOVE_BLOCK_END,
495 VIS_MOVE_PARENTHESE_START,
496 VIS_MOVE_PARENTHESE_END,
497 VIS_MOVE_BRACKET_MATCH,
498 VIS_MOVE_LEFT_TO,
499 VIS_MOVE_RIGHT_TO,
500 VIS_MOVE_LEFT_TILL,
501 VIS_MOVE_RIGHT_TILL,
502 VIS_MOVE_FILE_BEGIN,
503 VIS_MOVE_FILE_END,
504 VIS_MOVE_SEARCH_WORD_FORWARD,
505 VIS_MOVE_SEARCH_WORD_BACKWARD,
506 VIS_MOVE_SEARCH_REPEAT_FORWARD,
507 VIS_MOVE_SEARCH_REPEAT_BACKWARD,
508 VIS_MOVE_WINDOW_LINE_TOP,
509 VIS_MOVE_WINDOW_LINE_MIDDLE,
510 VIS_MOVE_WINDOW_LINE_BOTTOM,
511 VIS_MOVE_CHANGELIST_NEXT,
512 VIS_MOVE_CHANGELIST_PREV,
513 VIS_MOVE_NOP,
514 VIS_MOVE_PERCENT,
515 VIS_MOVE_BYTE,
516 VIS_MOVE_BYTE_LEFT,
517 VIS_MOVE_BYTE_RIGHT,
518 VIS_MOVE_INVALID, /* denotes the end of the "real" motions */
519 /* pseudo motions: keep them at the end to save space in array definition */
520 VIS_MOVE_TOTILL_REPEAT,
521 VIS_MOVE_TOTILL_REVERSE,
522 VIS_MOVE_SEARCH_FORWARD,
523 VIS_MOVE_SEARCH_BACKWARD,
524 VIS_MOVE_SEARCH_REPEAT,
525 VIS_MOVE_SEARCH_REPEAT_REVERSE,
526 VIS_MOVE_LAST, /* denotes the end of all motions */
530 * @defgroup vis_motions
531 * @{
534 * Set motion to perform.
536 * The following motions take an additional argument:
538 * - `VIS_MOVE_SEARCH_FORWARD` and `VIS_MOVE_SEARCH_BACKWARD`
540 * The search pattern as ``const char *``.
542 * - ``VIS_MOVE_{LEFT,RIGHT}_{TO,TILL}``
544 * The character to search for as ``const char *``.
546 bool vis_motion(Vis*, enum VisMotion, ...);
548 enum VisMotionType {
549 VIS_MOTIONTYPE_LINEWISE = 1 << 0,
550 VIS_MOTIONTYPE_CHARWISE = 1 << 1,
553 /** Force currently specified motion to behave in line or character wise mode. */
554 void vis_motion_type(Vis *vis, enum VisMotionType);
557 * Motions take a starting position and transform it to an end position.
558 * @rst
559 * .. note:: Should a motion not be possible, the original position must be returned.
560 * TODO: we might want to change that to ``EPOS``?
561 * @endrst
563 typedef size_t (VisMotionFunction)(Vis*, Win*, void *context, size_t pos);
566 * Register a motion function.
567 * @return Motion ID. Negative values indicate an error, positive ones can be
568 * used with `vis_motion`.
570 int vis_motion_register(Vis*, enum VisMotionType, void *context, VisMotionFunction*);
573 * @}
574 * @defgroup vis_count
575 * @{
577 /** No count was specified. */
578 #define VIS_COUNT_UNKNOWN (-1)
579 /** Get count, might return `VIS_COUNT_UNKNOWN`. */
580 int vis_count_get(Vis*);
581 /** Get count, if none was specified, return ``def``. */
582 int vis_count_get_default(Vis*, int def);
583 /** Set a count. */
584 void vis_count_set(Vis*, int count);
586 typedef struct {
587 Vis *vis;
588 int iteration;
589 int count;
590 } VisCountIterator;
592 /** Get iterator initialized with current count or ``def`` if not specified. */
593 VisCountIterator vis_count_iterator_get(Vis*, int def);
594 /** Get iterator initialized with a count value. */
595 VisCountIterator vis_count_iterator_init(Vis*, int count);
597 * Increment iterator counter.
598 * @return Whether iteration should continue.
599 * @rst
600 * .. note:: Terminates iteration if the edtior was
601 * `interrupted <vis_interrupt>`_ in the meantime.
602 * @endrst
604 bool vis_count_iterator_next(VisCountIterator*);
606 /** @} */
607 /** Text object specifier. */
608 enum VisTextObject {
609 VIS_TEXTOBJECT_INNER_WORD,
610 VIS_TEXTOBJECT_OUTER_WORD,
611 VIS_TEXTOBJECT_INNER_LONGWORD,
612 VIS_TEXTOBJECT_OUTER_LONGWORD,
613 VIS_TEXTOBJECT_SENTENCE,
614 VIS_TEXTOBJECT_PARAGRAPH,
615 VIS_TEXTOBJECT_OUTER_SQUARE_BRACKET,
616 VIS_TEXTOBJECT_INNER_SQUARE_BRACKET,
617 VIS_TEXTOBJECT_OUTER_CURLY_BRACKET,
618 VIS_TEXTOBJECT_INNER_CURLY_BRACKET,
619 VIS_TEXTOBJECT_OUTER_ANGLE_BRACKET,
620 VIS_TEXTOBJECT_INNER_ANGLE_BRACKET,
621 VIS_TEXTOBJECT_OUTER_PARANTHESE,
622 VIS_TEXTOBJECT_INNER_PARANTHESE,
623 VIS_TEXTOBJECT_OUTER_QUOTE,
624 VIS_TEXTOBJECT_INNER_QUOTE,
625 VIS_TEXTOBJECT_OUTER_SINGLE_QUOTE,
626 VIS_TEXTOBJECT_INNER_SINGLE_QUOTE,
627 VIS_TEXTOBJECT_OUTER_BACKTICK,
628 VIS_TEXTOBJECT_INNER_BACKTICK,
629 VIS_TEXTOBJECT_OUTER_ENTIRE,
630 VIS_TEXTOBJECT_INNER_ENTIRE,
631 VIS_TEXTOBJECT_OUTER_LINE,
632 VIS_TEXTOBJECT_INNER_LINE,
633 VIS_TEXTOBJECT_INDENTATION,
634 VIS_TEXTOBJECT_SEARCH_FORWARD,
635 VIS_TEXTOBJECT_SEARCH_BACKWARD,
636 VIS_TEXTOBJECT_INVALID,
640 * @defgroup vis_textobjs
641 * @{
645 * Text objects take a starting position and return a text range.
646 * @rst
647 * .. note:: The originating position does not necessarily have to be contained in
648 * the resulting range.
649 * @endrst
651 typedef Filerange (VisTextObjectFunction)(Vis*, Win*, void *context, size_t pos);
654 * Register a new text object.
655 * @return Text object ID. Negative values indicate an error, positive ones can be
656 * used with `vis_textobject`.
658 int vis_textobject_register(Vis*, int type, void *data, VisTextObjectFunction*);
660 /** Set text object to use. */
661 bool vis_textobject(Vis*, enum VisTextObject);
663 /** @} */
664 /** Mark specifiers. */
665 enum VisMark {
666 VIS_MARK_DEFAULT,
667 VIS_MARK_SELECTION,
668 VIS_MARK_a, VIS_MARK_b, VIS_MARK_c, VIS_MARK_d, VIS_MARK_e,
669 VIS_MARK_f, VIS_MARK_g, VIS_MARK_h, VIS_MARK_i, VIS_MARK_j,
670 VIS_MARK_k, VIS_MARK_l, VIS_MARK_m, VIS_MARK_n, VIS_MARK_o,
671 VIS_MARK_p, VIS_MARK_q, VIS_MARK_r, VIS_MARK_s, VIS_MARK_t,
672 VIS_MARK_u, VIS_MARK_v, VIS_MARK_w, VIS_MARK_x, VIS_MARK_y,
673 VIS_MARK_z,
674 VIS_MARK_INVALID, /* has to be the last enum member */
678 * @}
679 * @defgroup vis_marks
680 * @{
682 /** Translate single character mark name to corresponding constant. */
683 enum VisMark vis_mark_from(Vis*, char mark);
685 * Specify mark to use.
686 * @rst
687 * .. note:: If none is specified `VIS_MARK_DEFAULT` will be used.
688 * @endrst
690 void vis_mark(Vis*, enum VisMark);
691 enum VisMark vis_mark_used(Vis*);
693 * Store a set of ``Filerange``s in a mark.
695 * @param id The register to use.
696 * @param sel The array containing the file ranges.
698 void vis_mark_set(Win*, enum VisMark id, Array *sel);
700 * Get an array of file ranges stored in the mark.
702 * @rst
703 * .. warning:: The caller must eventually free the Array by calling
704 * ``array_release``.
705 * @endrst
707 Array vis_mark_get(Win*, enum VisMark id);
709 * Normalize an Array of Fileranges.
711 * Removes invalid ranges, merges overlapping ones and sorts
712 * according to the start position.
714 void vis_mark_normalize(Array*);
715 /** Add selections of focused window to jump list. */
716 bool vis_jumplist_save(Vis*);
717 /** Navigate jump list backwards. */
718 bool vis_jumplist_prev(Vis*);
719 /** Navigate jump list forwards. */
720 bool vis_jumplist_next(Vis*);
721 /** @} */
722 /** Register specifiers. */
723 enum VisRegister {
724 VIS_REG_DEFAULT, /* used when no other register is specified */
725 VIS_REG_ZERO, /* yank register */
726 VIS_REG_AMPERSAND, /* last regex match */
727 VIS_REG_1, /* 1-9 last sub-expression matches */
728 VIS_REG_2,
729 VIS_REG_3,
730 VIS_REG_4,
731 VIS_REG_5,
732 VIS_REG_6,
733 VIS_REG_7,
734 VIS_REG_8,
735 VIS_REG_9,
736 VIS_REG_BLACKHOLE, /* /dev/null register */
737 VIS_REG_CLIPBOARD, /* system clipboard register */
738 VIS_REG_DOT, /* last inserted text, copy of VIS_MACRO_OPERATOR */
739 VIS_REG_SEARCH, /* last used search pattern "/ */
740 VIS_REG_COMMAND, /* last used :-command ": */
741 VIS_REG_SHELL, /* last used shell command given to either <, >, |, or ! */
742 VIS_REG_NUMBER, /* cursor number */
743 VIS_REG_a, VIS_REG_b, VIS_REG_c, VIS_REG_d, VIS_REG_e,
744 VIS_REG_f, VIS_REG_g, VIS_REG_h, VIS_REG_i, VIS_REG_j,
745 VIS_REG_k, VIS_REG_l, VIS_REG_m, VIS_REG_n, VIS_REG_o,
746 VIS_REG_p, VIS_REG_q, VIS_REG_r, VIS_REG_s, VIS_REG_t,
747 VIS_REG_u, VIS_REG_v, VIS_REG_w, VIS_REG_x, VIS_REG_y,
748 VIS_REG_z,
749 VIS_MACRO_OPERATOR, /* records entered keys after an operator */
750 VIS_REG_PROMPT, /* internal register which shadows DEFAULT in PROMPT mode */
751 VIS_REG_INVALID, /* has to be the last 'real' register */
752 VIS_REG_A, VIS_REG_B, VIS_REG_C, VIS_REG_D, VIS_REG_E,
753 VIS_REG_F, VIS_REG_G, VIS_REG_H, VIS_REG_I, VIS_REG_J,
754 VIS_REG_K, VIS_REG_L, VIS_REG_M, VIS_REG_N, VIS_REG_O,
755 VIS_REG_P, VIS_REG_Q, VIS_REG_R, VIS_REG_S, VIS_REG_T,
756 VIS_REG_U, VIS_REG_V, VIS_REG_W, VIS_REG_X, VIS_REG_Y,
757 VIS_REG_Z,
758 VIS_MACRO_LAST_RECORDED, /* pseudo macro referring to last recorded one */
762 * @defgroup vis_registers
763 * @{
765 /** Translate single character register name to corresponding constant. */
766 enum VisRegister vis_register_from(Vis*, char reg);
768 * Specify register to use.
769 * @rst
770 * .. note:: If none is specified `VIS_REG_DEFAULT` will be used.
771 * @endrst
773 void vis_register(Vis*, enum VisRegister);
774 enum VisRegister vis_register_used(Vis*);
776 * Get register content.
777 * @return An array of ``TextString`` structs.
778 * @rst
779 * .. warning:: The caller must eventually free the array ressources using
780 * ``array_release``.
781 * @endrst
783 Array vis_register_get(Vis*, enum VisRegister);
785 * Set register content.
786 * @param data The array comprised of ``TextString`` structs.
788 bool vis_register_set(Vis*, enum VisRegister, Array *data);
790 * @}
791 * @defgroup vis_macros
792 * @{
795 * Start recording a macro.
796 * @rst
797 * .. note:: Fails if a recording is already ongoing.
798 * @endrst
800 bool vis_macro_record(Vis*, enum VisRegister);
801 /** Stop recording, fails if there is nothing to stop. */
802 bool vis_macro_record_stop(Vis*);
803 /** Check whether a recording is currently ongoing. */
804 bool vis_macro_recording(Vis*);
806 * Replay a macro.
807 * @rst
808 * .. note:: A macro currently being recorded can not be replayed.
809 * @endrst
811 bool vis_macro_replay(Vis*, enum VisRegister);
814 * @}
815 * @defgroup vis_cmds
816 * @{
819 /** Execute a ``:``-command. */
820 bool vis_cmd(Vis*, const char *cmd);
822 /** Command handler function. */
823 typedef bool (VisCommandFunction)(Vis*, Win*, void *data, bool force,
824 const char *argv[], Selection*, Filerange*);
826 * Register new ``:``-command.
827 * @param name The command name.
828 * @param help Optional single line help text.
829 * @param context User supplied context pointer passed to the handler function.
830 * @param func The function implementing the command logic.
831 * @rst
832 * .. note:: Any unique prefix of the command name will invoke the command.
833 * @endrst
835 bool vis_cmd_register(Vis*, const char *name, const char *help, void *context, VisCommandFunction*);
837 /** Unregister ``:``-command. */
838 bool vis_cmd_unregister(Vis*, const char *name);
841 * @}
842 * @defgroup vis_options
843 * @{
845 /** Option properties. */
846 enum VisOption {
847 VIS_OPTION_TYPE_BOOL = 1 << 0,
848 VIS_OPTION_TYPE_STRING = 1 << 1,
849 VIS_OPTION_TYPE_NUMBER = 1 << 2,
850 VIS_OPTION_VALUE_OPTIONAL = 1 << 3,
851 VIS_OPTION_NEED_WINDOW = 1 << 4,
855 * Option handler function.
856 * @param win The window to which option should apply, might be ``NULL``.
857 * @param context User provided context pointer as given to `vis_option_register`.
858 * @param force Whether the option was specfied with a bang ``!``.
859 * @param name Name of option which was set.
860 * @param arg The new option value.
862 typedef bool (VisOptionFunction)(Vis*, Win*, void *context, bool toggle,
863 enum VisOption, const char *name, Arg *value);
866 * Register a new ``:set`` option.
867 * @param names A ``NULL`` terminated array of option names.
868 * @param option Option properties.
869 * @param func The function handling the option.
870 * @param context User supplied context pointer passed to the handler function.
871 * @param help Optional single line help text.
872 * @rst
873 * .. note:: Fails if any of the given option names is already registered.
874 * @endrst
876 bool vis_option_register(Vis*, const char *names[], enum VisOption,
877 VisOptionFunction*, void *context, const char *help);
879 * Unregister an existing ``:set`` option.
880 * @rst
881 * .. note:: Also unregisters all aliases as given to `vis_option_register`.
882 * @endrst
884 bool vis_option_unregister(Vis*, const char *name);
886 /** Execute any kind (``:``, ``?``, ``/``) of prompt command */
887 bool vis_prompt_cmd(Vis*, const char *cmd);
890 * Pipe a given file range to an external process.
892 * If the range is invalid 'interactive' mode is enabled, meaning that
893 * stdin and stderr are passed through the underlying command, stdout
894 * points to vis' stderr.
896 * If ``argv`` contains only one non-NULL element the command is executed
897 * through an intermediate shell (using ``/bin/sh -c argv[0]``) that is
898 * argument expansion is performed by the shell. Otherwise the argument
899 * list will be passed unmodified to ``execvp(argv[0], argv)``.
901 * If the ``read_stdout`` and ``read_stderr`` callbacks are non-NULL they
902 * will be invoked when output from the forked process is available.
904 * @rst
905 * .. warning:: The editor core is blocked until this function returns.
906 * @endrst
908 * @return The exit status of the forked process.
910 int vis_pipe(Vis*, File*, Filerange*, const char *argv[],
911 void *stdout_context, ssize_t (*read_stdout)(void *stdout_context, char *data, size_t len),
912 void *stderr_context, ssize_t (*read_stderr)(void *stderr_context, char *data, size_t len));
915 * Pipe a Filerange to an external process, return its exit status and capture
916 * everything that is written to stdout/stderr.
917 * @param argv Argument list, must be ``NULL`` terminated.
918 * @param out Data written to ``stdout``, will be ``NUL`` terminated.
919 * @param err Data written to ``stderr``, will be ``NUL`` terminated.
920 * @rst
921 * .. warning:: The pointers stored in ``out`` and ``err`` need to be `free(3)`-ed
922 * by the caller.
923 * @endrst
925 int vis_pipe_collect(Vis*, File*, Filerange*, const char *argv[], char **out, char **err);
928 * @}
929 * @defgroup vis_keys
930 * @{
933 * Advance to the start of the next symbolic key.
935 * Given the start of a symbolic key, returns a pointer to the start of the one
936 * immediately following it.
938 const char *vis_keys_next(Vis*, const char *keys);
939 /** Convert next symbolic key to an Unicode code point, returns ``-1`` for unknown keys. */
940 long vis_keys_codepoint(Vis*, const char *keys);
942 * Convert next symbolic key to a UTF-8 sequence.
943 * @return Whether conversion was successful, if not ``utf8`` is left unmodified.
944 * @rst
945 * .. note:: Guarantees that ``utf8`` is NUL terminated on success.
946 * @endrst
948 bool vis_keys_utf8(Vis*, const char *keys, char utf8[static UTFmax+1]);
949 /** Process symbolic keys as if they were user originated input. */
950 void vis_keys_feed(Vis*, const char *keys);
952 * @}
953 * @defgroup vis_misc
954 * @{
958 * Get a regex object matching pattern.
959 * @param regex The regex pattern to compile, if ``NULL`` the most recently used
960 * one is substituted.
961 * @return A Regex object or ``NULL`` in case of an error.
962 * @rst
963 * .. warning:: The caller must free the regex object using `text_regex_free`.
964 * @endrst
966 Regex *vis_regex(Vis*, const char *pattern);
969 * Take an undo snaphost to which we can later revert to.
970 * @rst
971 * .. note:: Does nothing when invoked while replaying a macro.
972 * @endrst
974 void vis_file_snapshot(Vis*, File*);
975 /** @} */
977 /* TODO: expose proper API to iterate through files etc */
978 Text *vis_text(Vis*);
979 View *vis_view(Vis*);
980 Win *vis_window(Vis*);
982 /* Get value of autoindent */
983 bool vis_get_autoindent(const Vis*);
985 #endif