diff options
| -rw-r--r-- | config.def.h | 4 | ||||
| -rw-r--r-- | main.c | 20 | ||||
| -rw-r--r-- | vis.c | 12 |
3 files changed, 32 insertions, 4 deletions
diff --git a/config.def.h b/config.def.h index 3255bc2..9625512 100644 --- a/config.def.h +++ b/config.def.h @@ -190,8 +190,8 @@ static KeyBinding vis_mode_normal[] = { { "<C-i>", ACTION(JUMPLIST_NEXT) }, { "g;", ACTION(CHANGELIST_PREV) }, { "g,", ACTION(CHANGELIST_NEXT) }, - { "a", ALIAS("li") }, - { "A", ALIAS("$a") }, + { "a", ACTION(APPEND_CHAR_NEXT) }, + { "A", ACTION(APPEND_LINE_END) }, { "C", ALIAS("c$") }, { "D", ALIAS("d$") }, { "I", ALIAS("^i") }, @@ -24,6 +24,8 @@ static const char *macro_replay(Vis*, const char *keys, const Arg *arg); static const char *suspend(Vis*, const char *keys, const Arg *arg); /* switch to mode indicated by arg->i */ static const char *switchmode(Vis*, const char *keys, const Arg *arg); +/* switch to insert mode after performing movement indicated by arg->i */ +static const char *insertmode(Vis*, const char *keys, const Arg *arg); /* set mark indicated by keys to current cursor position */ static const char *mark_set(Vis*, const char *keys, const Arg *arg); /* add a new line either before or after the one where the cursor currently is */ @@ -198,6 +200,8 @@ enum { VIS_ACTION_INSERT_REGISTER, VIS_ACTION_WINDOW_NEXT, VIS_ACTION_WINDOW_PREV, + VIS_ACTION_APPEND_CHAR_NEXT, + VIS_ACTION_APPEND_LINE_END, VIS_ACTION_OPEN_LINE_ABOVE, VIS_ACTION_OPEN_LINE_BELOW, VIS_ACTION_JOIN_LINE_BELOW, @@ -730,6 +734,16 @@ static KeyAction vis_action[] = { "Focus previous window", call, { .f = vis_window_prev } }, + [VIS_ACTION_APPEND_CHAR_NEXT] = { + "append-char-next", + "Append text after the cursor", + insertmode, { .i = MOVE_CHAR_NEXT } + }, + [VIS_ACTION_APPEND_LINE_END] = { + "append-line-end", + "Append text after the end of the line", + insertmode, { .i = MOVE_LINE_END }, + }, [VIS_ACTION_OPEN_LINE_ABOVE] = { "open-line-above", "Begin a new line above the cursor", @@ -1519,6 +1533,12 @@ static const char *switchmode(Vis *vis, const char *keys, const Arg *arg) { return keys; } +static const char *insertmode(Vis *vis, const char *keys, const Arg *arg) { + vis_operator(vis, OP_INSERT); + vis_motion(vis, arg->i); + return keys; +} + static Vis *vis; static KeyBinding *default_bindings[] = { @@ -78,6 +78,7 @@ typedef struct { 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? */ + size_t newpos; /* new position after motion or EPOS if none given */ bool linewise; /* should the changes always affect whole lines? */ const Arg *arg; /* arbitrary arguments */ } OperatorContext; @@ -1307,13 +1308,13 @@ static size_t op_join(Vis *vis, Text *txt, OperatorContext *c) { static size_t op_insert(Vis *vis, Text *txt, OperatorContext *c) { macro_operator_record(vis); vis_mode_switch(vis, VIS_MODE_INSERT); - return c->pos; // c->range.end; // TODO + return c->newpos != EPOS ? c->newpos : c->pos; } static size_t op_replace(Vis *vis, Text *txt, OperatorContext *c) { macro_operator_record(vis); vis_mode_switch(vis, VIS_MODE_REPLACE); - return c->pos; // c->range.end; // TODO + return c->newpos != EPOS ? c->newpos : c->pos; } /** movement implementations of type: size_t (*move)(const Arg*) */ @@ -1515,6 +1516,7 @@ static void action_do(Vis *vis, Action *a) { OperatorContext c = { .count = a->count, .pos = pos, + .newpos = EPOS, .range = text_range_empty(), .reg = reg, .linewise = linewise, @@ -1546,6 +1548,7 @@ static void action_do(Vis *vis, Action *a) { pos = start; } else { c.range = text_range_new(start, pos); + c.newpos = pos; } if (!a->op) { @@ -3113,7 +3116,12 @@ void vis_repeat(Vis *vis) { } if (count) vis->action_prev.count = count; + count = vis->action_prev.count; + /* for some operators count should be applied only to the macro not the motion */ + if (vis->action_prev.op == &ops[OP_INSERT] || vis->action_prev.op == &ops[OP_REPLACE]) + vis->action_prev.count = 1; action_do(vis, &vis->action_prev); + vis->action_prev.count = count; if (macro) { Mode *mode = vis->mode; Action action_prev = vis->action_prev; |
