diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2015-11-06 11:09:28 +0100 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2015-11-06 11:30:53 +0100 |
| commit | 08ab694b4b8c7a0b6de5033801e3bf53c693a47a (patch) | |
| tree | 8272ceb391e87e83e5dc988ce8f1805267208030 | |
| parent | 7690c6cccc97d2df30d96c7e822bbfcf5118385b (diff) | |
| download | vis-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.c | 12 |
1 files changed, 8 insertions, 4 deletions
@@ -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); |
