aboutsummaryrefslogtreecommitdiff
path: root/vis.c
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 /vis.c
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.
Diffstat (limited to 'vis.c')
-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);