8 typedef struct Vis Vis
;
9 typedef struct File File
;
10 typedef struct Win Win
;
14 #include "text-regex.h"
23 #define VIS_HELP_DECL(x) x
24 #define VIS_HELP_USE(x) x
25 #define VIS_HELP(x) (x),
27 #define VIS_HELP_DECL(x)
28 #define VIS_HELP_USE(x) NULL
32 /* simplify utility renames by distribution packagers */
34 #define VIS_OPEN "vis-open"
37 #define VIS_CLIPBOARD "vis-clipboard"
40 /* maximum bytes needed for string representation of a (pseudo) key */
41 #define VIS_KEY_LENGTH_MAX 64
44 * Editor event handlers.
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 void (*term_csi
)(Vis
*, const long *);
63 /** Union used to pass arguments to key action functions. */
71 Filerange (*combine
)(const Filerange
*, const Filerange
*);
75 * Key action handling function.
76 * @param keys Input queue content *after* the binding which invoked this function.
78 * .. note:: An empty string ``""`` indicates that no further input is available.
80 * @return Pointer to first non-consumed key.
82 * .. warning:: Must be in range ``[keys, keys+strlen(keys)]`` or ``NULL`` to
83 * indicate that not enough input was available. In the latter case
84 * the function will be called again once more input has been received.
88 typedef const char *KeyActionFunction(Vis
*, const char *keys
, const Arg
*);
90 /** Key action definition. */
92 const char *name
; /**< Name of a pseudo key ``<name>`` which can be used in mappings. */
93 VIS_HELP_DECL(const char *help
;) /**< One line human readable description, displayed by ``:help``. */
94 KeyActionFunction
*func
; /**< Key action implementation function. */
95 Arg arg
; /**< Options passes as last argument to ``func``. */
99 * A key binding, refers to an action or an alias
101 * .. note:: Either ``action`` or ``alias`` must be ``NULL``.
105 const char *key
; /**< Symbolic key to trigger this binding. */
106 const KeyAction
*action
; /**< Action to invoke when triggering this binding. */
107 const char *alias
; /**< Replaces ``key`` with ``alias`` at the front of the input queue. */
111 * @defgroup vis_lifecycle
114 /** Create a new editor instance using the given user interface and event handlers. */
115 Vis
*vis_new(Ui
*, VisEvent
*);
116 /** Free all resources associated with this editor instance, terminates UI. */
119 * Enter main loop, start processing user input.
120 * @return The editor exit status code.
123 /** Terminate editing session, the given ``status`` will be the return value of `vis_run`. */
124 void vis_exit(Vis
*, int status
);
126 * Emergency exit, print given message, perform minimal UI cleanup and exit process.
128 * .. note:: This function does not return.
131 void vis_die(Vis
*, const char *msg
, ...) __attribute__((noreturn
,format(printf
, 2, 3)));
134 * Temporarily suspend the editor process.
136 * .. note:: This function will generate a ``SIGTSTP`` signal.
139 void vis_suspend(Vis
*);
141 * Resume editor process.
143 * .. note:: This function is usually called in response to a ``SIGCONT`` signal.
146 void vis_resume(Vis
*);
148 * Inform the editor core that a signal occured.
149 * @return Whether the signal was handled.
151 * .. note:: Being designed as a library the editor core does *not* register any
152 * signal handlers on its own.
153 * .. note:: The remaining arguments match the prototype of ``sa_sigaction`` as
154 * specified in `sigaction(2)`.
157 bool vis_signal_handler(Vis
*, int signum
, const siginfo_t
*siginfo
, const void *context
);
159 * Interrupt long running operation.
161 * .. warning:: There is no guarantee that a long running operation is actually
162 * interrupted. It is analogous to cooperative multitasking where
163 * the operation has to voluntarily yield control.
164 * .. note:: It is invoked from `vis_signal_handler` when receiving ``SIGINT``.
167 void vis_interrupt(Vis
*);
168 /** Check whether interruption was requested. */
169 bool vis_interrupt_requested(Vis
*);
175 /** Draw user interface. */
177 /** Completely redraw user interface. */
178 void vis_redraw(Vis
*);
179 /** Blit user interface state to output device. */
180 void vis_update(Vis
*);
183 * @defgroup vis_windows
187 * Create a new window and load the given file.
188 * @param filename If ``NULL`` a unamed, empty buffer is created.
190 * .. note:: If the given file name is already opened in another window,
191 * the underlying File object is shared.
192 * .. warning:: This duplication detection is currently based on normalized,
193 * absolute file names. TODO: compare inodes instead.
196 bool vis_window_new(Vis
*, const char *filename
);
198 * Create a new window associated with a file descriptor.
200 * .. note:: No data is read from `fd`, but write commands without an
201 * explicit filename will instead write to the file descriptor.
204 bool vis_window_new_fd(Vis
*, int fd
);
205 /** Reload the file currently displayed in the window from disk. */
206 bool vis_window_reload(Win
*);
207 /** Check whether closing the window would loose unsaved changes. */
208 bool vis_window_closable(Win
*);
209 /** Close window, redraw user interface. */
210 void vis_window_close(Win
*);
211 /** Split the window, shares the underlying file object. */
212 bool vis_window_split(Win
*);
213 /** Change status message of this window. */
214 void vis_window_status(Win
*, const char *status
);
215 void vis_window_draw(Win
*);
216 void vis_window_invalidate(Win
*);
217 /** Focus next window. */
218 void vis_window_next(Vis
*);
219 /** Focus previous window. */
220 void vis_window_prev(Vis
*);
221 /** Change currently focused window, receiving user input. */
222 void vis_window_focus(Win
*);
223 /** Swap location of two windows. */
224 void vis_window_swap(Win
*, Win
*);
225 /** Query window width. */
226 int vis_window_width_get(const Win
*);
227 /** Query window height. */
228 int vis_window_height_get(const Win
*);
235 * Display a user prompt with a certain title.
237 * .. note:: The prompt is currently implemented as a single line height window.
240 void vis_prompt_show(Vis
*, const char *title
);
243 * Display a single line message.
245 * .. note:: The message will automatically be hidden upon next input.
248 void vis_info_show(Vis
*, const char *msg
, ...) __attribute__((format(printf
, 2, 3)));
249 /** Hide informational message. */
250 void vis_info_hide(Vis
*);
252 /** Display arbitrary long message in a dedicated window. */
253 void vis_message_show(Vis
*, const char *msg
);
254 /** Close message window. */
255 void vis_message_hide(Vis
*);
258 * @defgroup vis_changes
261 void vis_insert(Vis
*, size_t pos
, const char *data
, size_t len
);
262 void vis_delete(Vis
*, size_t pos
, size_t len
);
263 void vis_replace(Vis
*, size_t pos
, const char *data
, size_t len
);
264 /** Perform insertion at all cursor positions. */
265 void vis_insert_key(Vis
*, const char *data
, size_t len
);
267 * Perform character substitution at all cursor positions.
269 * .. note:: Does not replace new line characters.
272 void vis_replace_key(Vis
*, const char *data
, size_t len
);
274 * Insert a tab at all cursor positions.
276 * .. note:: Performs tab expansion according to current settings.
279 void vis_insert_tab(Vis
*);
281 * Inserts a new line character at every cursor position.
283 * .. note:: Performs auto indentation according to current settings.
286 void vis_insert_nl(Vis
*);
289 /** Mode specifiers. */
292 VIS_MODE_OPERATOR_PENDING
,
294 VIS_MODE_VISUAL_LINE
, /**< Sub mode of `VIS_MODE_VISUAL`. */
296 VIS_MODE_REPLACE
, /**< Sub mode of `VIS_MODE_INSERT`. */
301 * @defgroup vis_modes
307 * .. note:: Will first trigger the leave event of the currently active
308 * mode, followed by an enter event of the new mode.
309 * No events are emitted, if the specified mode is already active.
312 void vis_mode_switch(Vis
*, enum VisMode
);
313 /** Get currently active mode. */
314 enum VisMode
vis_mode_get(Vis
*);
315 /** Translate human readable mode name to constant. */
316 enum VisMode
vis_mode_from(Vis
*, const char *name
);
320 * @defgroup vis_keybind
323 KeyBinding
*vis_binding_new(Vis
*);
324 void vis_binding_free(Vis
*, KeyBinding
*);
327 * Set up a key binding.
328 * @param force Whether an existing mapping should be discarded.
329 * @param key The symbolic key to map.
330 * @param binding The binding to map.
332 * .. note:: ``binding->key`` is always ignored in favor of ``key``.
335 bool vis_mode_map(Vis
*, enum VisMode
, bool force
, const char *key
, const KeyBinding
*);
336 /** Analogous to `vis_mode_map`, but window specific. */
337 bool vis_window_mode_map(Win
*, enum VisMode
, bool force
, const char *key
, const KeyBinding
*);
338 /** Unmap a symbolic key in a given mode. */
339 bool vis_mode_unmap(Vis
*, enum VisMode
, const char *key
);
340 /** Analogous to `vis_mode_unmap`, but window specific. */
341 bool vis_window_mode_unmap(Win
*, enum VisMode
, const char *key
);
344 * @defgroup vis_action
348 * Create new key action.
349 * @param name The name to be used as symbolic key when registering.
350 * @param help Optional single line help text.
351 * @param func The function implementing the key action logic.
352 * @param arg Argument passed to function.
354 KeyAction
*vis_action_new(Vis
*, const char *name
, const char *help
, KeyActionFunction
*, Arg
);
355 void vis_action_free(Vis
*, KeyAction
*);
357 * Register key action.
359 * .. note:: Makes the key action available under the pseudo key name specified
360 * in ``keyaction->name``.
363 bool vis_action_register(Vis
*, const KeyAction
*);
367 * @defgroup vis_keymap
371 /** Add a key translation. */
372 bool vis_keymap_add(Vis
*, const char *key
, const char *mapping
);
373 /** Temporarily disable the keymap for the next key press. */
374 void vis_keymap_disable(Vis
*);
377 /** Operator specifiers. */
389 VIS_OP_INVALID
, /* denotes the end of the "real" operators */
390 /* pseudo operators: keep them at the end to save space in array definition */
392 VIS_OP_PUT_AFTER_END
,
394 VIS_OP_PUT_BEFORE_END
,
395 VIS_OP_LAST
, /* has to be last enum member */
399 * @defgroup vis_operators
402 typedef struct OperatorContext OperatorContext
;
405 * An operator performs a certain function on a given text range.
407 * .. note:: The operator must return the new cursor position or ``EPOS`` if
408 * the cursor should be disposed.
409 * .. note:: The last used operator can be repeated using `vis_repeat`.
412 typedef size_t (VisOperatorFunction
)(Vis
*, Text
*, OperatorContext
*);
415 * Register an operator.
416 * @return Operator ID. Negative values indicate an error, positive ones can be
417 * used with `vis_operator`.
419 int vis_operator_register(Vis
*, VisOperatorFunction
*, void *context
);
422 * Set operator to execute.
424 * Has immediate effect if:
425 * - A visual mode is active.
426 * - The same operator was already set (range will be the current line).
428 * Otherwise the operator will be executed on the range determinded by:
429 * - A motion (see `vis_motion`).
430 * - A text object (`vis_textobject`).
432 * The expected varying arguments are:
434 * - `VIS_OP_JOIN` a char pointer referring to the text to insert between lines.
435 * - `VIS_OP_MODESWITCH` an ``enum VisMode`` indicating the mode to switch to.
436 * - `VIS_OP_REPLACE` a char pointer referring to the replacement character.
438 bool vis_operator(Vis
*, enum VisOperator
, ...);
440 /** Repeat last operator, possibly with a new count if one was provided in the meantime. */
441 void vis_repeat(Vis
*);
443 /** Cancel pending operator, reset count, motion, text object, register etc. */
444 void vis_cancel(Vis
*);
447 /** Motion specifiers. */
451 VIS_MOVE_SCREEN_LINE_UP
,
452 VIS_MOVE_SCREEN_LINE_DOWN
,
453 VIS_MOVE_SCREEN_LINE_BEGIN
,
454 VIS_MOVE_SCREEN_LINE_MIDDLE
,
455 VIS_MOVE_SCREEN_LINE_END
,
459 VIS_MOVE_LINE_FINISH
,
460 VIS_MOVE_LINE_LASTCHAR
,
467 VIS_MOVE_LINE_CHAR_PREV
,
468 VIS_MOVE_LINE_CHAR_NEXT
,
469 VIS_MOVE_CODEPOINT_PREV
,
470 VIS_MOVE_CODEPOINT_NEXT
,
472 VIS_MOVE_WORD_START_NEXT
,
473 VIS_MOVE_WORD_END_PREV
,
474 VIS_MOVE_WORD_END_NEXT
,
475 VIS_MOVE_WORD_START_PREV
,
476 VIS_MOVE_LONGWORD_NEXT
,
477 VIS_MOVE_LONGWORD_START_PREV
,
478 VIS_MOVE_LONGWORD_START_NEXT
,
479 VIS_MOVE_LONGWORD_END_PREV
,
480 VIS_MOVE_LONGWORD_END_NEXT
,
481 VIS_MOVE_SENTENCE_PREV
,
482 VIS_MOVE_SENTENCE_NEXT
,
483 VIS_MOVE_PARAGRAPH_PREV
,
484 VIS_MOVE_PARAGRAPH_NEXT
,
485 VIS_MOVE_FUNCTION_START_PREV
,
486 VIS_MOVE_FUNCTION_START_NEXT
,
487 VIS_MOVE_FUNCTION_END_PREV
,
488 VIS_MOVE_FUNCTION_END_NEXT
,
489 VIS_MOVE_BLOCK_START
,
491 VIS_MOVE_PARENTHESIS_START
,
492 VIS_MOVE_PARENTHESIS_END
,
493 VIS_MOVE_BRACKET_MATCH
,
496 VIS_MOVE_TO_LINE_LEFT
,
497 VIS_MOVE_TO_LINE_RIGHT
,
500 VIS_MOVE_TILL_LINE_LEFT
,
501 VIS_MOVE_TILL_LINE_RIGHT
,
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
,
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
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
, ...);
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.
559 * .. note:: Should a motion not be possible, the original position must be returned.
560 * TODO: we might want to change that to ``EPOS``?
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
*, void *context
, VisMotionFunction
*);
574 * @defgroup vis_count
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
);
584 void vis_count_set(Vis
*, int count
);
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.
600 * .. note:: Terminates iteration if the edtior was
601 * `interrupted <vis_interrupt>`_ in the meantime.
604 bool vis_count_iterator_next(VisCountIterator
*);
607 /** Text object specifier. */
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_PARAGRAPH_OUTER
,
616 VIS_TEXTOBJECT_OUTER_SQUARE_BRACKET
,
617 VIS_TEXTOBJECT_INNER_SQUARE_BRACKET
,
618 VIS_TEXTOBJECT_OUTER_CURLY_BRACKET
,
619 VIS_TEXTOBJECT_INNER_CURLY_BRACKET
,
620 VIS_TEXTOBJECT_OUTER_ANGLE_BRACKET
,
621 VIS_TEXTOBJECT_INNER_ANGLE_BRACKET
,
622 VIS_TEXTOBJECT_OUTER_PARENTHESIS
,
623 VIS_TEXTOBJECT_INNER_PARENTHESIS
,
624 VIS_TEXTOBJECT_OUTER_QUOTE
,
625 VIS_TEXTOBJECT_INNER_QUOTE
,
626 VIS_TEXTOBJECT_OUTER_SINGLE_QUOTE
,
627 VIS_TEXTOBJECT_INNER_SINGLE_QUOTE
,
628 VIS_TEXTOBJECT_OUTER_BACKTICK
,
629 VIS_TEXTOBJECT_INNER_BACKTICK
,
630 VIS_TEXTOBJECT_OUTER_LINE
,
631 VIS_TEXTOBJECT_INNER_LINE
,
632 VIS_TEXTOBJECT_INDENTATION
,
633 VIS_TEXTOBJECT_SEARCH_FORWARD
,
634 VIS_TEXTOBJECT_SEARCH_BACKWARD
,
635 VIS_TEXTOBJECT_INVALID
,
639 * @defgroup vis_textobjs
644 * Text objects take a starting position and return a text range.
646 * .. note:: The originating position does not necessarily have to be contained in
647 * the resulting range.
650 typedef Filerange (VisTextObjectFunction
)(Vis
*, Win
*, void *context
, size_t pos
);
653 * Register a new text object.
654 * @return Text object ID. Negative values indicate an error, positive ones can be
655 * used with `vis_textobject`.
657 int vis_textobject_register(Vis
*, int type
, void *data
, VisTextObjectFunction
*);
659 /** Set text object to use. */
660 bool vis_textobject(Vis
*, enum VisTextObject
);
663 /** Mark specifiers. */
667 VIS_MARK_a
, VIS_MARK_b
, VIS_MARK_c
, VIS_MARK_d
, VIS_MARK_e
,
668 VIS_MARK_f
, VIS_MARK_g
, VIS_MARK_h
, VIS_MARK_i
, VIS_MARK_j
,
669 VIS_MARK_k
, VIS_MARK_l
, VIS_MARK_m
, VIS_MARK_n
, VIS_MARK_o
,
670 VIS_MARK_p
, VIS_MARK_q
, VIS_MARK_r
, VIS_MARK_s
, VIS_MARK_t
,
671 VIS_MARK_u
, VIS_MARK_v
, VIS_MARK_w
, VIS_MARK_x
, VIS_MARK_y
,
673 VIS_MARK_INVALID
, /* has to be the last enum member */
678 * @defgroup vis_marks
681 /** Translate between single character mark name and corresponding constant. */
682 enum VisMark
vis_mark_from(Vis
*, char mark
);
683 char vis_mark_to(Vis
*, enum VisMark
);
685 * Specify mark to use.
687 * .. note:: If none is specified `VIS_MARK_DEFAULT` will be used.
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.
703 * .. warning:: The caller must eventually free the Array by calling
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
*);
722 /** Register specifiers. */
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 */
736 VIS_REG_BLACKHOLE
, /* /dev/null register */
737 VIS_REG_CLIPBOARD
, /* system clipboard register */
738 VIS_REG_PRIMARY
, /* system primary clipboard register */
739 VIS_REG_DOT
, /* last inserted text, copy of VIS_MACRO_OPERATOR */
740 VIS_REG_SEARCH
, /* last used search pattern "/ */
741 VIS_REG_COMMAND
, /* last used :-command ": */
742 VIS_REG_SHELL
, /* last used shell command given to either <, >, |, or ! */
743 VIS_REG_NUMBER
, /* cursor number */
744 VIS_REG_a
, VIS_REG_b
, VIS_REG_c
, VIS_REG_d
, VIS_REG_e
,
745 VIS_REG_f
, VIS_REG_g
, VIS_REG_h
, VIS_REG_i
, VIS_REG_j
,
746 VIS_REG_k
, VIS_REG_l
, VIS_REG_m
, VIS_REG_n
, VIS_REG_o
,
747 VIS_REG_p
, VIS_REG_q
, VIS_REG_r
, VIS_REG_s
, VIS_REG_t
,
748 VIS_REG_u
, VIS_REG_v
, VIS_REG_w
, VIS_REG_x
, VIS_REG_y
,
750 VIS_MACRO_OPERATOR
, /* records entered keys after an operator */
751 VIS_REG_PROMPT
, /* internal register which shadows DEFAULT in PROMPT mode */
752 VIS_REG_INVALID
, /* has to be the last 'real' register */
753 VIS_REG_A
, VIS_REG_B
, VIS_REG_C
, VIS_REG_D
, VIS_REG_E
,
754 VIS_REG_F
, VIS_REG_G
, VIS_REG_H
, VIS_REG_I
, VIS_REG_J
,
755 VIS_REG_K
, VIS_REG_L
, VIS_REG_M
, VIS_REG_N
, VIS_REG_O
,
756 VIS_REG_P
, VIS_REG_Q
, VIS_REG_R
, VIS_REG_S
, VIS_REG_T
,
757 VIS_REG_U
, VIS_REG_V
, VIS_REG_W
, VIS_REG_X
, VIS_REG_Y
,
759 VIS_MACRO_LAST_RECORDED
, /* pseudo macro referring to last recorded one */
763 * @defgroup vis_registers
766 /** Translate between single character register name and corresponding constant. */
767 enum VisRegister
vis_register_from(Vis
*, char reg
);
768 char vis_register_to(Vis
*, enum VisRegister
);
770 * Specify register to use.
772 * .. note:: If none is specified `VIS_REG_DEFAULT` will be used.
775 void vis_register(Vis
*, enum VisRegister
);
776 enum VisRegister
vis_register_used(Vis
*);
778 * Get register content.
779 * @return An array of ``TextString`` structs.
781 * .. warning:: The caller must eventually free the array resources using
785 Array
vis_register_get(Vis
*, enum VisRegister
);
787 * Set register content.
788 * @param data The array comprised of ``TextString`` structs.
790 bool vis_register_set(Vis
*, enum VisRegister
, Array
*data
);
793 * @defgroup vis_macros
797 * Start recording a macro.
799 * .. note:: Fails if a recording is already ongoing.
802 bool vis_macro_record(Vis
*, enum VisRegister
);
803 /** Stop recording, fails if there is nothing to stop. */
804 bool vis_macro_record_stop(Vis
*);
805 /** Check whether a recording is currently ongoing. */
806 bool vis_macro_recording(Vis
*);
810 * .. note:: A macro currently being recorded can not be replayed.
813 bool vis_macro_replay(Vis
*, enum VisRegister
);
821 /** Execute a ``:``-command. */
822 bool vis_cmd(Vis
*, const char *cmd
);
824 /** Command handler function. */
825 typedef bool (VisCommandFunction
)(Vis
*, Win
*, void *data
, bool force
,
826 const char *argv
[], Selection
*, Filerange
*);
828 * Register new ``:``-command.
829 * @param name The command name.
830 * @param help Optional single line help text.
831 * @param context User supplied context pointer passed to the handler function.
832 * @param func The function implementing the command logic.
834 * .. note:: Any unique prefix of the command name will invoke the command.
837 bool vis_cmd_register(Vis
*, const char *name
, const char *help
, void *context
, VisCommandFunction
*);
839 /** Unregister ``:``-command. */
840 bool vis_cmd_unregister(Vis
*, const char *name
);
844 * @defgroup vis_options
847 /** Option properties. */
849 VIS_OPTION_TYPE_BOOL
= 1 << 0,
850 VIS_OPTION_TYPE_STRING
= 1 << 1,
851 VIS_OPTION_TYPE_NUMBER
= 1 << 2,
852 VIS_OPTION_VALUE_OPTIONAL
= 1 << 3,
853 VIS_OPTION_NEED_WINDOW
= 1 << 4,
857 * Option handler function.
858 * @param win The window to which option should apply, might be ``NULL``.
859 * @param context User provided context pointer as given to `vis_option_register`.
860 * @param force Whether the option was specified with a bang ``!``.
861 * @param name Name of option which was set.
862 * @param arg The new option value.
864 typedef bool (VisOptionFunction
)(Vis
*, Win
*, void *context
, bool toggle
,
865 enum VisOption
, const char *name
, Arg
*value
);
868 * Register a new ``:set`` option.
869 * @param names A ``NULL`` terminated array of option names.
870 * @param option Option properties.
871 * @param func The function handling the option.
872 * @param context User supplied context pointer passed to the handler function.
873 * @param help Optional single line help text.
875 * .. note:: Fails if any of the given option names is already registered.
878 bool vis_option_register(Vis
*, const char *names
[], enum VisOption
,
879 VisOptionFunction
*, void *context
, const char *help
);
881 * Unregister an existing ``:set`` option.
883 * .. note:: Also unregisters all aliases as given to `vis_option_register`.
886 bool vis_option_unregister(Vis
*, const char *name
);
888 /** Execute any kind (``:``, ``?``, ``/``) of prompt command */
889 bool vis_prompt_cmd(Vis
*, const char *cmd
);
892 * Pipe a given file range to an external process.
894 * If the range is invalid 'interactive' mode is enabled, meaning that
895 * stdin and stderr are passed through the underlying command, stdout
896 * points to vis' stderr.
898 * If ``argv`` contains only one non-NULL element the command is executed
899 * through an intermediate shell (using ``/bin/sh -c argv[0]``) that is
900 * argument expansion is performed by the shell. Otherwise the argument
901 * list will be passed unmodified to ``execvp(argv[0], argv)``.
903 * If the ``read_stdout`` and ``read_stderr`` callbacks are non-NULL they
904 * will be invoked when output from the forked process is available.
907 * .. warning:: The editor core is blocked until this function returns.
910 * @return The exit status of the forked process.
912 int vis_pipe(Vis
*, File
*, Filerange
*, const char *argv
[],
913 void *stdout_context
, ssize_t (*read_stdout
)(void *stdout_context
, char *data
, size_t len
),
914 void *stderr_context
, ssize_t (*read_stderr
)(void *stderr_context
, char *data
, size_t len
));
917 * Pipe a Filerange to an external process, return its exit status and capture
918 * everything that is written to stdout/stderr.
919 * @param argv Argument list, must be ``NULL`` terminated.
920 * @param out Data written to ``stdout``, will be ``NUL`` terminated.
921 * @param err Data written to ``stderr``, will be ``NUL`` terminated.
923 * .. warning:: The pointers stored in ``out`` and ``err`` need to be `free(3)`-ed
927 int vis_pipe_collect(Vis
*, File
*, Filerange
*, const char *argv
[], char **out
, char **err
);
935 * Advance to the start of the next symbolic key.
937 * Given the start of a symbolic key, returns a pointer to the start of the one
938 * immediately following it.
940 const char *vis_keys_next(Vis
*, const char *keys
);
941 /** Convert next symbolic key to an Unicode code point, returns ``-1`` for unknown keys. */
942 long vis_keys_codepoint(Vis
*, const char *keys
);
944 * Convert next symbolic key to a UTF-8 sequence.
945 * @return Whether conversion was successful, if not ``utf8`` is left unmodified.
947 * .. note:: Guarantees that ``utf8`` is NUL terminated on success.
950 bool vis_keys_utf8(Vis
*, const char *keys
, char utf8
[static UTFmax
+1]);
951 /** Process symbolic keys as if they were user originated input. */
952 void vis_keys_feed(Vis
*, const char *keys
);
960 * Get a regex object matching pattern.
961 * @param regex The regex pattern to compile, if ``NULL`` the most recently used
962 * one is substituted.
963 * @return A Regex object or ``NULL`` in case of an error.
965 * .. warning:: The caller must free the regex object using `text_regex_free`.
968 Regex
*vis_regex(Vis
*, const char *pattern
);
971 * Take an undo snapshot to which we can later revert.
973 * .. note:: Does nothing when invoked while replaying a macro.
976 void vis_file_snapshot(Vis
*, File
*);
979 /* TODO: expose proper API to iterate through files etc */
980 Text
*vis_text(Vis
*);
981 View
*vis_view(Vis
*);
982 Win
*vis_window(Vis
*);
984 /* Get value of autoindent */
985 bool vis_get_autoindent(const Vis
*);