aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-11-02 14:03:26 +0100
committerMarc André Tanner <mat@brain-dump.org>2015-11-02 16:10:29 +0100
commitc3cb6cae3c9d4fb625d5653715ce3323fe3aa1e5 (patch)
treeb9fa0a7f8b7ecab706bb893d7f3013632ec1c7e8
parent3840fe853ae3d904d05b583266827786923d8f9b (diff)
downloadvis-c3cb6cae3c9d4fb625d5653715ce3323fe3aa1e5.tar.gz
vis-c3cb6cae3c9d4fb625d5653715ce3323fe3aa1e5.tar.xz
vis: make append (a and A) commands repeatable
-rw-r--r--config.def.h4
-rw-r--r--main.c20
-rw-r--r--vis.c12
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") },
diff --git a/main.c b/main.c
index 722e3dd..3a28e75 100644
--- a/main.c
+++ b/main.c
@@ -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[] = {
diff --git a/vis.c b/vis.c
index 720f331..398d0b9 100644
--- a/vis.c
+++ b/vis.c
@@ -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;