aboutsummaryrefslogtreecommitdiff
path: root/vis.h
diff options
context:
space:
mode:
Diffstat (limited to 'vis.h')
-rw-r--r--vis.h240
1 files changed, 234 insertions, 6 deletions
diff --git a/vis.h b/vis.h
index 6a3b710..71a0b78 100644
--- a/vis.h
+++ b/vis.h
@@ -1,13 +1,101 @@
#ifndef VIS_H
#define VIS_H
+#include <signal.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <setjmp.h>
+
+typedef struct Vis Vis;
+typedef struct File File;
+typedef struct Win Win;
+
#include "ui.h"
-#include "editor.h"
+#include "view.h"
+#include "register.h"
+#include "macro.h"
+#include "syntax.h"
+#include "ring-buffer.h"
+#include "map.h"
+#include "text-regex.h"
+
+
+typedef union {
+ bool b;
+ int i;
+ const char *s;
+ void (*w)(View*); /* generic window commands */
+ void (*f)(Vis*); /* generic editor commands */
+} Arg;
+
+typedef struct {
+ const char *name;
+ const char *help;
+ 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;
+
+} KeyAction;
+
+typedef struct {
+ const char *key;
+ KeyAction *action;
+ const char *alias;
+} KeyBinding;
+
-typedef Editor Vis;
Vis *vis_new(Ui*);
-#define vis_free editor_free
+void vis_free(Vis*);
+void vis_resize(Vis*);
+void vis_draw(Vis*);
+void vis_update(Vis*);
+void vis_suspend(Vis*);
+
+/* load a set of syntax highlighting definitions which will be associated
+ * to the underlying window based on the file type loaded.
+ *
+ * The parameter `syntaxes' has to point to a NULL terminated array.
+ */
+bool vis_syntax_load(Vis*, Syntax *syntaxes);
+void vis_syntax_unload(Vis*);
+
+/* creates a new window, and loads the given file. if filename is NULL
+ * an unamed / empty buffer is created. If the given file is already opened
+ * in another window, share the underlying text that is changes will be
+ * visible in both windows */
+bool vis_window_new(Vis*, const char *filename);
+/* reload the file currently displayed in the window from disk */
+bool vis_window_reload(Win*);
+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*);
+/* 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);
+/* 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
+ * which the call site has to free. */
+char *vis_prompt_get(Vis*);
+/* replace the current command line content with the one given */
+void vis_prompt_set(Vis*, const char *line);
+
+/* display a message to the user */
+void vis_info_show(Vis*, const char *msg, ...);
+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);
void vis_run(Vis*, int argc, char *argv[]);
void vis_die(Vis*, const char *msg, ...);
@@ -29,6 +117,10 @@ 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);
+
+bool vis_action_register(Vis*, KeyAction*);
enum VisOperator {
OP_DELETE,
@@ -162,15 +254,45 @@ bool vis_macro_record_stop(Vis*);
bool vis_macro_replay(Vis*, enum VisMacro);
enum VisMark {
- /* TODO: temporary */
+ 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,
};
void vis_mark_set(Vis*, enum VisMark mark, size_t pos);
enum VisRegister {
- /* TODO: temporary */
- VIS_REGISTER_INVALID = REG_LAST,
+ 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,
};
void vis_register_set(Vis*, enum VisRegister);
@@ -186,4 +308,110 @@ const char *vis_keys(Vis*, const char *input);
bool vis_signal_handler(Vis*, int signum, const siginfo_t *siginfo,
const void *context);
+/* TODO: temporary */
+typedef struct Operator Operator;
+typedef struct Movement Movement;
+typedef struct TextObject TextObject;
+
+typedef struct { /** collects all information until an operator is executed */
+ int count;
+ enum VisMotionType type;
+ const Operator *op;
+ const Movement *movement;
+ const TextObject *textobj;
+ Register *reg;
+ enum VisMark mark;
+ Arg arg;
+} Action;
+
+/* a mode contains a set of key bindings which are currently valid.
+ *
+ * each mode can specify one parent mode which is consultated if a given key
+ * is not found in the current mode. hence the modes form a tree which is
+ * searched from the current mode up towards the root mode until a valid binding
+ * is found.
+ *
+ * if no binding is found, mode->input(...) is called and the user entered
+ * keys are passed as argument. this is used to change the document content.
+ */
+typedef struct Mode Mode;
+struct Mode {
+ Mode *parent; /* if no match is found in this mode, search will continue there */
+ Map *bindings;
+ KeyBinding *default_bindings;
+ const char *name; /* descriptive, user facing name of the mode */
+ const char *status; /* name displayed in the window status bar */
+ const char *help; /* short description used by :help */
+ bool isuser; /* whether this is a user or internal mode */
+ void (*enter)(Vis*, Mode *old); /* called right before the mode becomes active */
+ void (*leave)(Vis*, Mode *new); /* called right before the mode becomes inactive */
+ void (*input)(Vis*, const char*, size_t); /* called whenever a key is not found in this mode and all its parent modes */
+ void (*idle)(Vis*); /* called whenever a certain idle time i.e. without any user input elapsed */
+ time_t idle_timeout; /* idle time in seconds after which the registered function will be called */
+ bool visual; /* whether text selection is possible in this mode */
+};
+
+struct File {
+ Text *text;
+ const char *name;
+ volatile sig_atomic_t truncated;
+ bool is_stdin;
+ struct stat stat;
+ int refcount;
+ Mark marks[VIS_MARK_INVALID];
+ File *next, *prev;
+};
+
+typedef struct {
+ time_t state; /* state of the text, used to invalidate change list */
+ size_t index; /* #number of changes */
+ size_t pos; /* where the current change occured */
+} ChangeList;
+
+struct Win {
+ Vis *editor; /* editor instance to which this window belongs */
+ UiWin *ui;
+ File *file; /* file being displayed in this window */
+ View *view; /* currently displayed part of underlying text */
+ ViewEvent events;
+ RingBuffer *jumplist; /* LRU jump management */
+ ChangeList changelist; /* state for iterating through least recently changes */
+ Win *prev, *next; /* neighbouring windows */
+};
+
+struct Vis {
+ Ui *ui;
+ File *files;
+ Win *windows; /* list of windows */
+ Win *win; /* currently active window */
+ Syntax *syntaxes; /* NULL terminated array of syntax definitions */
+ Register registers[VIS_REGISTER_INVALID]; /* register used for copy and paste */
+ Macro macros[VIS_MACRO_INVALID]; /* recorded macros */
+ Macro *recording, *last_recording;/* currently and least recently recorded macro */
+ Win *prompt; /* 1-line height window to get user input */
+ Win *prompt_window; /* window which was focused before prompt was shown */
+ char prompt_type; /* command ':' or search '/','?' prompt */
+ Regex *search_pattern; /* last used search pattern */
+ char search_char[8]; /* last used character to search for via 'f', 'F', 't', 'T' */
+ int last_totill; /* last to/till movement used for ';' and ',' */
+ int tabwidth; /* how many spaces should be used to display a tab */
+ bool expandtab; /* whether typed tabs should be converted to spaces */
+ bool autoindent; /* whether indentation should be copied from previous line on newline */
+ Map *cmds; /* ":"-commands, used for unique prefix queries */
+ Map *options; /* ":set"-options */
+ Buffer buffer_repeat; /* holds data to repeat last insertion/replacement */
+ Buffer input_queue; /* holds pending input keys */
+
+ Action action; /* current action which is in progress */
+ Action action_prev; /* last operator action used by the repeat '.' key */
+ Mode *mode; /* currently active mode, used to search for keybindings */
+ Mode *mode_prev; /* previsouly active user mode */
+ Mode *mode_before_prompt; /* user mode which was active before entering prompt */
+ volatile bool running; /* exit main loop once this becomes false */
+ volatile sig_atomic_t cancel_filter; /* abort external command */
+ volatile sig_atomic_t sigbus;
+ sigjmp_buf sigbus_jmpbuf;
+ Map *actions; /* built in special editor keys / commands */
+};
+
#endif