vis
a vi-like editor based on Plan 9's structural regular expressions
git clone https://9o.is/git/vis.git
commit 2266bcb8841c9f61feec280c7545799b9b20328c parent 20b7c994fe52b631e58fe9f332d84ce35b0acb0e Author: Marc André Tanner <mat@brain-dump.org> Date: Wed, 22 Feb 2017 09:28:40 +0100 vis: add exact count motion flag Some motions should fail (i.e. keep the initial position) when the specified count can not be satisfied exactly. Examples include t, f, T, and F. Fix #497 Diffstat:
| M | vis-core.h | | | 1 | + |
| M | vis-motions.c | | | 6 | ++++-- |
| M | vis.c | | | 10 | +++++++++- |
3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/vis-core.h b/vis-core.h @@ -69,6 +69,7 @@ typedef struct { /* Motion implementation, takes a cursor postion and returns a LINEWISE_INCLUSIVE = 1 << 3, /* inclusive, but only if motion is linewise? */ IDEMPOTENT = 1 << 4, /* does the returned postion remain the same if called multiple times? */ JUMP = 1 << 5, /* should the resulting position of the motion be recorded in the jump list? */ + COUNT_EXACT = 1 << 6, /* fail (keep initial position) if count can not be satisfied exactly */ } type; void *data; } Movement; diff --git a/vis-motions.c b/vis-motions.c @@ -502,17 +502,19 @@ const Movement vis_motions[] = { }, [VIS_MOVE_LEFT_TO] = { .vis = to_left, + .type = COUNT_EXACT, }, [VIS_MOVE_RIGHT_TO] = { .vis = to, - .type = INCLUSIVE, + .type = INCLUSIVE|COUNT_EXACT, }, [VIS_MOVE_LEFT_TILL] = { .vis = till_left, + .type = COUNT_EXACT, }, [VIS_MOVE_RIGHT_TILL] = { .vis = till, - .type = INCLUSIVE, + .type = INCLUSIVE|COUNT_EXACT, }, [VIS_MOVE_MARK] = { .file = mark_goto, diff --git a/vis.c b/vis.c @@ -710,6 +710,7 @@ void vis_do(Vis *vis) { .arg = &a->arg, }; + bool err = false; if (a->movement) { size_t start = pos; for (int i = 0; i < count; i++) { @@ -728,8 +729,15 @@ void vis_do(Vis *vis) { pos = a->movement->win(vis, win, pos); else if (a->movement->user) pos = a->movement->user(vis, win, a->movement->data, pos); - if (pos == EPOS || a->movement->type & IDEMPOTENT || pos == pos_prev) + if (pos == EPOS || a->movement->type & IDEMPOTENT || pos == pos_prev) { + err = a->movement->type & COUNT_EXACT; break; + } + } + + if (err) { + repeatable = false; + continue; // break? } if (pos == EPOS) {