aboutsummaryrefslogtreecommitdiff
path: root/vis.c
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-04-11 11:58:24 +0200
committerMarc André Tanner <mat@brain-dump.org>2015-04-11 11:58:24 +0200
commitc56e523ce74dd48d8c18f4dce3e8881310613015 (patch)
tree2db2a7dedbedebbbf24c1fb4c152c9fe1a3594be /vis.c
parentbe1fb4cc4edf9cc861831961cac1d0400a87db36 (diff)
downloadvis-c56e523ce74dd48d8c18f4dce3e8881310613015.tar.gz
vis-c56e523ce74dd48d8c18f4dce3e8881310613015.tar.xz
Move structs to editor.h remove global action{,_prev}
Diffstat (limited to 'vis.c')
-rw-r--r--vis.c215
1 files changed, 52 insertions, 163 deletions
diff --git a/vis.c b/vis.c
index 014448e..5fd0a3b 100644
--- a/vis.c
+++ b/vis.c
@@ -38,115 +38,6 @@
#include "util.h"
#include "map.h"
-typedef union {
- bool b;
- int i;
- const char *s;
- void (*w)(Win*); /* generic window commands */
- void (*f)(Editor*); /* generic editor commands */
-} Arg;
-
-typedef struct {
- char str[6]; /* UTF8 character or terminal escape code */
- int code; /* curses KEY_* constant */
-} Key;
-
-#define MAX_KEYS 2
-typedef Key KeyCombo[MAX_KEYS];
-
-typedef struct {
- KeyCombo key;
- void (*func)(const Arg *arg);
- const Arg arg;
-} KeyBinding;
-
-typedef struct Mode Mode;
-struct Mode {
- Mode *parent; /* if no match is found in this mode, search will continue there */
- KeyBinding *bindings; /* NULL terminated array of keybindings for this mode */
- const char *name; /* descriptive, user facing name of the mode */
- bool isuser; /* whether this is a user or internal mode */
- bool common_prefix; /* whether the first key in this mode is always the same */
- void (*enter)(Mode *old); /* called right before the mode becomes active */
- void (*leave)(Mode *new); /* called right before the mode becomes inactive */
- bool (*unknown)(KeyCombo); /* called whenever a key combination is not found in this mode,
- the return value determines whether parent modes will be searched */
- void (*input)(const char*, size_t); /* called whenever a key is not found in this mode and all its parent modes */
- void (*idle)(void); /* 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 */
-};
-
-typedef struct {
- char *name; /* is used to match against argv[0] to enable this config */
- Mode *mode; /* default mode in which the editor should start in */
- bool (*keypress)(Key*); /* called before any other keybindings are checked,
- * return value decides whether key should be ignored */
-} Config;
-
-typedef struct {
- int count; /* how many times should the command be executed? */
- Register *reg; /* always non-NULL, set to a default register */
- Filerange range; /* which part of the file should be affected by the operator */
- size_t pos; /* at which byte from the start of the file should the operation start? */
- bool linewise; /* should the changes always affect whole lines? */
- const Arg *arg; /* arbitrary arguments */
-} OperatorContext;
-
-typedef struct {
- void (*func)(OperatorContext*); /* function implementing the operator logic */
-} Operator;
-
-typedef struct {
- size_t (*cmd)(const Arg*); /* a custom movement based on user input from vis.c */
- size_t (*win)(Win*); /* a movement based on current window content from window.h */
- size_t (*txt)(Text*, size_t pos); /* a movement form text-motions.h */
- enum {
- LINEWISE = 1 << 0,
- CHARWISE = 1 << 1,
- INCLUSIVE = 1 << 2,
- EXCLUSIVE = 1 << 3,
- IDEMPOTENT = 1 << 4,
- JUMP = 1 << 5,
- } type;
- int count;
-} Movement;
-
-typedef struct {
- Filerange (*range)(Text*, size_t pos); /* a text object from text-objects.h */
- enum {
- INNER,
- OUTER,
- } type;
-} TextObject;
-
-typedef struct { /** collects all information until an operator is executed */
- int count;
- bool linewise;
- const Operator *op;
- const Movement *movement;
- const TextObject *textobj;
- Register *reg;
- int mark;
- Key key;
- Arg arg;
-} Action;
-
-enum CmdOpt { /* option flags for command definitions */
- CMD_OPT_NONE, /* no option (default value) */
- CMD_OPT_FORCE, /* whether the command can be forced by appending '!' */
- CMD_OPT_ARGS, /* whether the command line should be parsed in to space
- * separated arguments to placed into argv, otherwise argv[1]
- * will contain the remaining command line unmodified */
-};
-
-typedef struct { /* command definitions for the ':'-prompt */
- const char *name[3]; /* name and optional alias for the command */
- /* command logic called with a NULL terminated array of arguments.
- * argv[0] will be the command name */
- bool (*cmd)(Filerange*, enum CmdOpt opt, const char *argv[]);
- enum CmdOpt opt; /* command option flags */
-} Command;
/** global variables */
static volatile bool running = true; /* exit main loop once this becomes false */
@@ -154,8 +45,6 @@ static Editor *vis; /* global editor instance, keeps track of all window
static Mode *mode; /* currently active mode, used to search for keybindings */
static Mode *mode_prev; /* previsouly active user mode */
static Mode *mode_before_prompt; /* user mode which was active before entering prompt */
-static Action action; /* current action which is in progress */
-static Action action_prev; /* last operator action used by the repeat '.' key */
/** operators */
static void op_change(OperatorContext *c);
@@ -757,7 +646,7 @@ static void mark_set(const Arg *arg) {
}
static size_t mark_goto(const Arg *arg) {
- return text_mark_get(vis->win->text->data, vis->win->text->marks[action.mark]);
+ return text_mark_get(vis->win->text->data, vis->win->text->marks[vis->action.mark]);
}
static size_t mark_line_goto(const Arg *arg) {
@@ -766,7 +655,7 @@ static size_t mark_line_goto(const Arg *arg) {
static size_t to(const Arg *arg) {
return text_find_char_next(vis->win->text->data, window_cursor_get(vis->win->win) + 1,
- action.key.str, strlen(action.key.str));
+ vis->action.key.str, strlen(vis->action.key.str));
}
static size_t till(const Arg *arg) {
@@ -775,7 +664,7 @@ static size_t till(const Arg *arg) {
static size_t to_left(const Arg *arg) {
return text_find_char_prev(vis->win->text->data, window_cursor_get(vis->win->win) - 1,
- action.key.str, strlen(action.key.str));
+ vis->action.key.str, strlen(vis->action.key.str));
}
static size_t till_left(const Arg *arg) {
@@ -783,16 +672,16 @@ static size_t till_left(const Arg *arg) {
}
static size_t line(const Arg *arg) {
- return text_pos_by_lineno(vis->win->text->data, action.count);
+ return text_pos_by_lineno(vis->win->text->data, vis->action.count);
}
static size_t column(const Arg *arg) {
size_t pos = window_cursor_get(vis->win->win);
- return text_line_offset(vis->win->text->data, pos, action.count);
+ return text_line_offset(vis->win->text->data, pos, vis->action.count);
}
static size_t window_lines_top(const Arg *arg) {
- return window_screenline_goto(vis->win->win, action.count);
+ return window_screenline_goto(vis->win->win, vis->action.count);
}
static size_t window_lines_middle(const Arg *arg) {
@@ -802,7 +691,7 @@ static size_t window_lines_middle(const Arg *arg) {
static size_t window_lines_bottom(const Arg *arg) {
int h = window_height_get(vis->win->win);
- return window_screenline_goto(vis->win->win, h-action.count);
+ return window_screenline_goto(vis->win->win, h - vis->action.count);
}
/** key bindings functions of type: void (*func)(const Arg*) */
@@ -866,8 +755,8 @@ static void suspend(const Arg *arg) {
}
static void repeat(const Arg *arg) {
- action = action_prev;
- action_do(&action);
+ vis->action = vis->action_prev;
+ action_do(&vis->action);
}
static void replace(const Arg *arg) {
@@ -875,8 +764,8 @@ static void replace(const Arg *arg) {
if (!k.str[0])
return;
size_t pos = window_cursor_get(vis->win->win);
- action_reset(&action_prev);
- action_prev.op = &ops[OP_REPEAT_REPLACE];
+ action_reset(&vis->action_prev);
+ vis->action_prev.op = &ops[OP_REPEAT_REPLACE];
buffer_put(&vis->buffer_repeat, k.str, strlen(k.str));
editor_delete_key(vis);
editor_insert_key(vis, k.str, strlen(k.str));
@@ -885,11 +774,11 @@ static void replace(const Arg *arg) {
}
static void count(const Arg *arg) {
- action.count = action.count * 10 + arg->i;
+ vis->action.count = vis->action.count * 10 + arg->i;
}
static void gotoline(const Arg *arg) {
- if (action.count)
+ if (vis->action.count)
movement(&(const Arg){ .i = MOVE_LINE });
else if (arg->i < 0)
movement(&(const Arg){ .i = MOVE_FILE_BEGIN });
@@ -898,27 +787,27 @@ static void gotoline(const Arg *arg) {
}
static void linewise(const Arg *arg) {
- action.linewise = arg->b;
+ vis->action.linewise = arg->b;
}
static void operator(const Arg *arg) {
Operator *op = &ops[arg->i];
if (mode->visual) {
- action.op = op;
- action_do(&action);
+ vis->action.op = op;
+ action_do(&vis->action);
return;
}
/* switch to operator mode inorder to make operator options and
* text-object available */
switchmode(&(const Arg){ .i = VIS_MODE_OPERATOR });
- if (action.op == op) {
+ if (vis->action.op == op) {
/* hacky way to handle double operators i.e. things like
* dd, yy etc where the second char isn't a movement */
- action.linewise = true;
- action.textobj = moves_linewise[MOVE_SCREEN_LINE_DOWN];
- action_do(&action);
+ vis->action.linewise = true;
+ vis->action.textobj = moves_linewise[MOVE_SCREEN_LINE_DOWN];
+ action_do(&vis->action);
} else {
- action.op = op;
+ vis->action.op = op;
}
}
@@ -928,40 +817,40 @@ static void operator_twice(const Arg *arg) {
}
static void changecase(const Arg *arg) {
- action.arg = *arg;
+ vis->action.arg = *arg;
operator(&(const Arg){ .i = OP_CASE_CHANGE });
}
static void movement_key(const Arg *arg) {
Key k = getkey();
if (!k.str[0]) {
- action_reset(&action);
+ action_reset(&vis->action);
return;
}
- action.key = k;
- action.movement = &moves[arg->i];
- action_do(&action);
+ vis->action.key = k;
+ vis->action.movement = &moves[arg->i];
+ action_do(&vis->action);
}
static void movement(const Arg *arg) {
- if (action.linewise && arg->i < LENGTH(moves_linewise))
- action.textobj = moves_linewise[arg->i];
+ if (vis->action.linewise && arg->i < LENGTH(moves_linewise))
+ vis->action.textobj = moves_linewise[arg->i];
else
- action.movement = &moves[arg->i];
+ vis->action.movement = &moves[arg->i];
- if (action.op == &ops[OP_CHANGE]) {
- if (action.movement == &moves[MOVE_WORD_START_NEXT])
- action.movement = &moves[MOVE_WORD_END_NEXT];
- else if (action.movement == &moves[MOVE_LONGWORD_START_NEXT])
- action.movement = &moves[MOVE_LONGWORD_END_NEXT];
+ if (vis->action.op == &ops[OP_CHANGE]) {
+ if (vis->action.movement == &moves[MOVE_WORD_START_NEXT])
+ vis->action.movement = &moves[MOVE_WORD_END_NEXT];
+ else if (vis->action.movement == &moves[MOVE_LONGWORD_START_NEXT])
+ vis->action.movement = &moves[MOVE_LONGWORD_END_NEXT];
}
- action_do(&action);
+ action_do(&vis->action);
}
static void textobj(const Arg *arg) {
- action.textobj = &textobjs[arg->i];
- action_do(&action);
+ vis->action.textobj = &textobjs[arg->i];
+ action_do(&vis->action);
}
static void selection_end(const Arg *arg) {
@@ -979,19 +868,19 @@ static void selection_end(const Arg *arg) {
}
static void reg(const Arg *arg) {
- action.reg = &vis->registers[arg->i];
+ vis->action.reg = &vis->registers[arg->i];
}
static void mark(const Arg *arg) {
- action.mark = arg->i;
- action.movement = &moves[MOVE_MARK];
- action_do(&action);
+ vis->action.mark = arg->i;
+ vis->action.movement = &moves[MOVE_MARK];
+ action_do(&vis->action);
}
static void mark_line(const Arg *arg) {
- action.mark = arg->i;
- action.movement = &moves[MOVE_MARK_LINE];
- action_do(&action);
+ vis->action.mark = arg->i;
+ vis->action.movement = &moves[MOVE_MARK_LINE];
+ action_do(&vis->action);
}
static void undo(const Arg *arg) {
@@ -1013,7 +902,7 @@ static void redo(const Arg *arg) {
}
static void zero(const Arg *arg) {
- if (action.count == 0)
+ if (vis->action.count == 0)
movement(&(const Arg){ .i = MOVE_LINE_BEGIN });
else
count(&(const Arg){ .i = 0 });
@@ -1111,8 +1000,8 @@ static int argi2lines(const Arg *arg) {
case +PAGE_HALF:
return window_height_get(vis->win->win)/2;
default:
- if (action.count > 0)
- return action.count;
+ if (vis->action.count > 0)
+ return vis->action.count;
return arg->i < 0 ? -arg->i : arg->i;
}
}
@@ -1172,9 +1061,9 @@ static void insert_newline(const Arg *arg) {
}
static void put(const Arg *arg) {
- action.arg = *arg;
+ vis->action.arg = *arg;
operator(&(const Arg){ .i = OP_PUT });
- action_do(&action);
+ action_do(&vis->action);
}
static void openline(const Arg *arg) {
@@ -1309,9 +1198,9 @@ static void action_do(Action *a) {
text_snapshot(txt);
}
- if (a != &action_prev) {
+ if (a != &vis->action_prev) {
if (a->op)
- action_prev = *a;
+ vis->action_prev = *a;
action_reset(a);
}
}
@@ -1869,7 +1758,7 @@ static bool exec_command(char type, const char *cmd) {
case '/':
case '?':
if (text_regex_compile(vis->search_pattern, cmd, REG_EXTENDED)) {
- action_reset(&action);
+ action_reset(&vis->action);
return false;
}
movement(&(const Arg){ .i =