aboutsummaryrefslogtreecommitdiff
path: root/vis.h
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-11-07 08:51:26 +0100
committerMarc André Tanner <mat@brain-dump.org>2015-11-07 12:16:34 +0100
commit26b56bc3090e9ad6ffd71f216a53805c5e894807 (patch)
tree48f4d26dd01571df196bd1ee2228c3d72e65581b /vis.h
parentf1002cdc6d70bae0c5f68df1d91cd170189d4789 (diff)
downloadvis-26b56bc3090e9ad6ffd71f216a53805c5e894807.tar.gz
vis-26b56bc3090e9ad6ffd71f216a53805c5e894807.tar.xz
vis: API documentation and cleanup
Diffstat (limited to 'vis.h')
-rw-r--r--vis.h208
1 files changed, 132 insertions, 76 deletions
diff --git a/vis.h b/vis.h
index 8e69806..01c1358 100644
--- a/vis.h
+++ b/vis.h
@@ -4,7 +4,6 @@
#include <signal.h>
#include <stddef.h>
#include <stdbool.h>
-#include <setjmp.h>
typedef struct Vis Vis;
typedef struct File File;
@@ -15,35 +14,41 @@ typedef struct Win Win;
#include "register.h"
#include "syntax.h"
-typedef union {
+typedef union { /* various types of arguments passed to key action functions */
bool b;
int i;
const char *s;
- void (*w)(View*); /* generic window commands */
- void (*f)(Vis*); /* generic editor commands */
+ void (*w)(View*);
+ void (*f)(Vis*);
} Arg;
-typedef struct {
- const char *name;
- const char *help;
+typedef struct { /* a KeyAction can be bound to a key binding */
+ const char *name; /* aliases can refer to this action by means of a pseudo key <name> */
+ const char *help; /* short (one line) human readable description, displayed by :help */
+ /* action handling function, keys refers to the next characters found in the input queue
+ * (an empty string "" indicates an empty queue). The return value of func has to point to
+ * the first non consumed key. Returning NULL indicates that not enough keys were available
+ * to complete the action. In this case the function will be called again when more input
+ * becomes available */
const char* (*func)(Vis*, const char *keys, const Arg*);
- /* returns a pointer to the first not consumed character in keys
- * or NULL if not enough input was available to complete the command */
- const Arg arg;
-
+ const Arg arg; /* additional arguments which will be passed as to func */
} KeyAction;
-typedef struct {
- const char *key;
- KeyAction *action;
- const char *alias;
+typedef struct { /* a key binding either refers to an action or an alias */
+ const char *key; /* symbolic key to trigger this binding */
+ KeyAction *action; /* action to launch upon triggering this binding */
+ const char *alias; /* replaces key with alias in the input queue */
} KeyBinding;
+/* creates a new editor instance using the specified user interface */
Vis *vis_new(Ui*);
+/* frees all resources associated with this editor instance, terminates ui */
void vis_free(Vis*);
-void vis_resize(Vis*);
+/* instructs the user interface to draw to an internal buffer */
void vis_draw(Vis*);
+/* flushes the state of the internal buffer to the output device */
void vis_update(Vis*);
+/* temporarily supsend the editor process, resumes upon receiving SIGCONT */
void vis_suspend(Vis*);
/* load a set of syntax highlighting definitions which will be associated
@@ -61,18 +66,20 @@ void vis_syntax_unload(Vis*);
bool vis_window_new(Vis*, const char *filename);
/* reload the file currently displayed in the window from disk */
bool vis_window_reload(Win*);
+/* close window, redraw user interface */
void vis_window_close(Win*);
/* split the given window. changes to the displayed text will be reflected
* in both windows */
bool vis_window_split(Win*);
+/* change file name associated with this window, affects syntax coloring */
void vis_window_name(Win*, const char *filename);
/* focus the next / previous window */
void vis_window_next(Vis*);
void vis_window_prev(Vis*);
/* display a user prompt with a certain title and default text */
void vis_prompt_show(Vis*, const char *title, const char *text);
-/* TODO: bad abstraction */
-void vis_prompt_enter(Vis*);
+/* execute current prompt content as command, as if the user had pressed <Enter> */
+void vis_prompt_enter(Vis*); /* TODO: bad abstraction */
/* hide the user prompt if it is currently shown */
void vis_prompt_hide(Vis*);
/* return the content of the command prompt in a malloc(3)-ed string
@@ -87,18 +94,29 @@ void vis_info_hide(Vis*);
/* these function operate on the currently focused window but make sure
* that all windows which show the affected region are redrawn too. */
-void vis_insert_key(Vis*, const char *data, size_t len);
-void vis_replace_key(Vis*, const char *data, size_t len);
void vis_insert(Vis*, size_t pos, const char *data, size_t len);
void vis_delete(Vis*, size_t pos, size_t len);
void vis_replace(Vis*, size_t pos, const char *data, size_t len);
+/* these functions perform their operation at the current cursor position(s) */
+void vis_insert_key(Vis*, const char *data, size_t len);
+void vis_replace_key(Vis*, const char *data, size_t len);
+/* inserts a tab (peforms tab expansion based on current editing settings),
+ * at all current cursor positions */
void vis_insert_tab(Vis*);
+/* inserts a new line sequence (depending on the file type this might be \n or
+ * \r\n) at all current cursor positions */
void vis_insert_nl(Vis*);
+/* processes the given command line arguments and starts the main loop, won't
+ * return until editing session is terminated */
int vis_run(Vis*, int argc, char *argv[]);
+/* terminate editing session, given status will be the return value of vis_run */
void vis_exit(Vis*, int status);
+/* emergency exit, print given message, perform minimal ui cleanup and exit process */
void vis_die(Vis*, const char *msg, ...);
+/* user facing modes are: NORMAL, VISUAL, VISUAL_LINE, PROMPT, INSERT, REPLACE.
+ * the others should be considered as implementation details (TODO: do not expose them?) */
enum VisMode {
VIS_MODE_BASIC,
VIS_MODE_MOVE,
@@ -116,18 +134,20 @@ enum VisMode {
};
void vis_mode_switch(Vis*, enum VisMode);
-bool vis_mode_map(Vis*, enum VisMode, const char *name, KeyBinding*);
-bool vis_mode_unmap(Vis*, enum VisMode, const char *name);
+/* in the specified mode: map a given key to a binding (binding->key is ignored),
+ * fails if key is already mapped */
+bool vis_mode_map(Vis*, enum VisMode, const char *key, KeyBinding*);
+/* in the specified mode: unmap a given key, fails if the key is not currently mapped */
+bool vis_mode_unmap(Vis*, enum VisMode, const char *key);
+/* map a NULL-terminated array of key bindings, return value indicates whether *all*
+ * bindings were succesfully performed */
bool vis_mode_bindings(Vis*, enum VisMode, KeyBinding **bindings);
+/* get the current mode's status line indicator */
const char *vis_mode_status(Vis*);
-
+/* associates the special pseudo key <keyaction->name> with the given key action.
+ * after successfull registration the pseudo key can be used key binding aliases */
bool vis_action_register(Vis*, KeyAction*);
-/* TODO: overhaul repeatable infrastructure:
- * - put is not really an operator, but should still be repeatable
- * and respect count
- " - review OP_REPEAT_{REPLACE,INSERT}
- */
enum VisOperator {
OP_DELETE,
OP_CHANGE,
@@ -140,7 +160,7 @@ enum VisOperator {
OP_REPLACE,
OP_CURSOR_SOL,
OP_CASE_SWAP,
- OP_INVALID,
+ OP_INVALID, /* denotes the end of the "real" operators */
/* pseudo operators: keep them at the end to save space in array definition */
OP_CASE_LOWER,
OP_CASE_UPPER,
@@ -150,6 +170,13 @@ enum VisOperator {
OP_PUT_BEFORE_END,
};
+/* set operator to execute, has immediate effect if
+ * - a visual mode is active
+ * - the same operator was already set (range will be the current line)
+ * otherwise waits until a range is determinded i.e.
+ * - a motion is provided (see vis_motion)
+ * - a text object is provided (vis_textobject)
+ */
bool vis_operator(Vis*, enum VisOperator);
enum VisMotion {
@@ -210,7 +237,7 @@ enum VisMotion {
MOVE_JUMPLIST_NEXT,
MOVE_JUMPLIST_PREV,
MOVE_NOP,
- MOVE_INVALID,
+ MOVE_INVALID, /* denotes the end of the "real" motions */
/* pseudo motions: keep them at the end to save space in array definition */
MOVE_TOTILL_REPEAT,
MOVE_TOTILL_REVERSE,
@@ -218,8 +245,25 @@ enum VisMotion {
MOVE_SEARCH_BACKWARD,
};
+/* set motion to perform, the following take an additional argument:
+ *
+ * - MOVE_SEARCH_FORWARD and MOVE_SEARCH_BACKWARD
+ *
+ * expect the search pattern as const char *
+ *
+ * - MOVE_{LEFT,RIGHT}_{TO,TILL}
+ *
+ * expect the character to search for as const char *
+ *
+ * - MOVE_MARK and MOVE_MARK_LINE
+ *
+ * expect a valid enum VisMark
+ */
bool vis_motion(Vis*, enum VisMotion, ...);
+/* a count of zero indicates that so far no special count was given.
+ * operators, motions and text object will always perform their function
+ * as if a minimal count of 1 was given */
int vis_count_get(Vis*);
void vis_count_set(Vis*, int count);
@@ -227,7 +271,7 @@ enum VisMotionType {
VIS_MOTIONTYPE_LINEWISE = 1 << 0,
VIS_MOTIONTYPE_CHARWISE = 1 << 1,
};
-
+/* force certain motion to behave in line or character wise mode */
void vis_motion_type(Vis *vis, enum VisMotionType);
enum VisTextObject {
@@ -261,77 +305,89 @@ enum VisTextObject {
void vis_textobject(Vis*, enum VisTextObject);
+/* macro REPEAT and INVALID should be considered as implementation details (TODO: hide them?) */
enum VisMacro {
- /* XXX: TEMPORARY */
- VIS_MACRO_LAST_RECORDED = 26,
- VIS_MACRO_REPEAT,
- VIS_MACRO_OPERATOR,
- VIS_MACRO_INVALID, /* hast to be the last enum member */
+ VIS_MACRO_a, VIS_MACRO_b, VIS_MACRO_c, VIS_MACRO_d, VIS_MACRO_e,
+ VIS_MACRO_f, VIS_MACRO_g, VIS_MACRO_h, VIS_MACRO_i, VIS_MACRO_j,
+ VIS_MACRO_k, VIS_MACRO_l, VIS_MACRO_m, VIS_MACRO_n, VIS_MACRO_o,
+ VIS_MACRO_p, VIS_MACRO_q, VIS_MACRO_r, VIS_MACRO_s, VIS_MACRO_t,
+ VIS_MACRO_u, VIS_MACRO_v, VIS_MACRO_w, VIS_MACRO_x, VIS_MACRO_y,
+ VIS_MACRO_z,
+ VIS_MACRO_OPERATOR, /* records entered keys after an operator */
+ VIS_MACRO_REPEAT, /* copy of the above macro once the recording is finished */
+ VIS_MACRO_INVALID, /* denotes the end of "real" macros */
+ VIS_MACRO_LAST_RECORDED, /* pseudo macro referring to last recorded one */
};
+/* start a macro recording, fails if a recording is already on going */
bool vis_macro_record(Vis*, enum VisMacro);
+/* stop recording, fails if there is nothing to stop */
bool vis_macro_record_stop(Vis*);
+/* check whether a recording is currently on going */
bool vis_macro_recording(Vis*);
+/* replay a macro. a macro currently being recorded can't be replayed */
bool vis_macro_replay(Vis*, enum VisMacro);
enum VisMark {
- MARK_a,
- MARK_b,
- MARK_c,
- MARK_d,
- MARK_e,
- MARK_f,
- MARK_g,
- MARK_h,
- MARK_i,
- MARK_j,
- MARK_k,
- MARK_l,
- MARK_m,
- MARK_n,
- MARK_o,
- MARK_p,
- MARK_q,
- MARK_r,
- MARK_s,
- MARK_t,
- MARK_u,
- MARK_v,
- MARK_w,
- MARK_x,
- MARK_y,
- MARK_z,
- MARK_SELECTION_START,
- MARK_SELECTION_END,
- VIS_MARK_INVALID,
+ VIS_MARK_a, VIS_MARK_b, VIS_MARK_c, VIS_MARK_d, VIS_MARK_e,
+ VIS_MARK_f, VIS_MARK_g, VIS_MARK_h, VIS_MARK_i, VIS_MARK_j,
+ VIS_MARK_k, VIS_MARK_l, VIS_MARK_m, VIS_MARK_n, VIS_MARK_o,
+ VIS_MARK_p, VIS_MARK_q, VIS_MARK_r, VIS_MARK_s, VIS_MARK_t,
+ VIS_MARK_u, VIS_MARK_v, VIS_MARK_w, VIS_MARK_x, VIS_MARK_y,
+ VIS_MARK_z,
+ MARK_SELECTION_START, /* '< */
+ MARK_SELECTION_END, /* '> */
+ VIS_MARK_INVALID, /* has to be the last enum member */
};
void vis_mark_set(Vis*, enum VisMark mark, size_t pos);
enum VisRegister {
- REG_a, REG_b, REG_c, REG_d, REG_e, REG_f, REG_g, REG_h, REG_i,
- REG_j, REG_k, REG_l, REG_m, REG_n, REG_o, REG_p, REG_q, REG_r,
- REG_s, REG_t, REG_u, REG_v, REG_w, REG_x, REG_y, REG_z,
- REG_DEFAULT,
- VIS_REGISTER_INVALID,
+ VIS_REG_a, VIS_REG_b, VIS_REG_c, VIS_REG_d, VIS_REG_e,
+ VIS_REG_f, VIS_REG_g, VIS_REG_h, VIS_REG_i, VIS_REG_j,
+ VIS_REG_k, VIS_REG_l, VIS_REG_m, VIS_REG_n, VIS_REG_o,
+ VIS_REG_p, VIS_REG_q, VIS_REG_r, VIS_REG_s, VIS_REG_t,
+ VIS_REG_u, VIS_REG_v, VIS_REG_w, VIS_REG_x, VIS_REG_y,
+ VIS_REG_z,
+ VIS_REG_DEFAULT, /* used when no other register is specified */
+ VIS_REG_INVALID, /* has to be the last enum member */
};
+/* set the register to use, if none is given the DEFAULT register is used */
void vis_register_set(Vis*, enum VisRegister);
Register *vis_register_get(Vis*, enum VisRegister);
+/* repeat last operator, possibly with a new count if one was provided in the meantime */
void vis_repeat(Vis*);
+
+/* cancel pending operator, reset count, motion, text object, register etc. */
void vis_cancel(Vis*);
-/* execute a :-command (call without without leading ':') */
+/* execute a :-command (including an optinal range specifier) */
bool vis_cmd(Vis*, const char *cmd);
-const char *vis_key_next(Vis*, const char *keys);
-const char *vis_keys(Vis*, const char *input);
+/* given the start of a key, returns a pointer to the start of the one immediately
+ * following as will be processed by the input system. skips over special keys
+ * such as <Enter> as well as pseudo keys registered via vis_action_register. */
+const char *vis_keys_next(Vis*, const char *keys);
+/* vis operates as a finite state machine (FSM), feeding keys from an input
+ * queue (or a previously recorded macro) to key handling functions (see struct
+ * KeyAction) which consume the input.
+ *
+ * this functions pushes/appends further input to the end of the input queue
+ * and immediately tries to interpret them */
+const char *vis_keys_push(Vis*, const char *input);
+/* inject new input keys at the position indicated by a pointer to a valid, not
+ * yet consumed key from the current input queue. does not try to interpret the
+ * new queue content.
+ *
+ * typically only called from within key handling functions */
bool vis_keys_inject(Vis*, const char *pos, const char *input);
+/* inform vis that a signal occured, the return value indicates whether the signal
+ * was handled by vis */
+bool vis_signal_handler(Vis*, int signum, const siginfo_t *siginfo, const void *context);
-bool vis_signal_handler(Vis*, int signum, const siginfo_t *siginfo,
- const void *context);
-
+/* TODO: expose proper API to iterate through files etc */
Text *vis_text(Vis*);
View *vis_view(Vis*);
Text *vis_file_text(File*);