aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-11-06 11:09:28 +0100
committerMarc André Tanner <mat@brain-dump.org>2015-11-06 11:30:53 +0100
commit08ab694b4b8c7a0b6de5033801e3bf53c693a47a (patch)
tree8272ceb391e87e83e5dc988ce8f1805267208030
parent7690c6cccc97d2df30d96c7e822bbfcf5118385b (diff)
downloadvis-08ab694b4b8c7a0b6de5033801e3bf53c693a47a.tar.gz
vis-08ab694b4b8c7a0b6de5033801e3bf53c693a47a.tar.xz
vis: fix operators to correctly handle multiple selections
Operators must not switch modes, they might be called multiple times (once for every cursor/selection). Closes #91. The concrete problem was that op_change for the first cursor switched to insert mode, which cleared all the remaining selections. Hence the other cursors had nothing to operate on. Reverts parts of d395687b.
-rw-r--r--vis.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/vis.c b/vis.c
index 2d2b969..1cd473a 100644
--- a/vis.c
+++ b/vis.c
@@ -1135,7 +1135,6 @@ static size_t op_delete(Vis *vis, Text *txt, OperatorContext *c) {
static size_t op_change(Vis *vis, Text *txt, OperatorContext *c) {
op_delete(vis, txt, c);
macro_operator_record(vis);
- vis_mode_switch(vis, VIS_MODE_INSERT);
return c->range.start;
}
@@ -1310,13 +1309,11 @@ 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->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->newpos != EPOS ? c->newpos : c->pos;
}
@@ -1612,7 +1609,14 @@ static void action_do(Vis *vis, Action *a) {
}
if (a->op) {
- if (vis->mode == &vis_modes[VIS_MODE_OPERATOR])
+ /* operator implementations must not change the mode,
+ * they might get called multiple times (once for every cursor)
+ */
+ if (a->op == &ops[OP_INSERT] || a->op == &ops[OP_CHANGE])
+ vis_mode_switch(vis, VIS_MODE_INSERT);
+ else if (a->op == &ops[OP_REPLACE])
+ vis_mode_switch(vis, VIS_MODE_REPLACE);
+ else if (vis->mode == &vis_modes[VIS_MODE_OPERATOR])
mode_set(vis, vis->mode_prev);
else if (vis->mode->visual)
vis_mode_switch(vis, VIS_MODE_NORMAL);