diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2017-02-22 09:28:40 +0100 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2017-02-22 12:42:19 +0100 |
| commit | 75ff22469b21e72a4c9126d89cfa3623af1784fd (patch) | |
| tree | 0cfd4b74d377735db2d7f81d34b630b1f79f2a0a | |
| parent | a08d2fa4e547341e9298b0eaf7678f1dc67f0612 (diff) | |
| download | vis-75ff22469b21e72a4c9126d89cfa3623af1784fd.tar.gz vis-75ff22469b21e72a4c9126d89cfa3623af1784fd.tar.xz | |
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
| -rw-r--r-- | vis-core.h | 1 | ||||
| -rw-r--r-- | vis-motions.c | 6 | ||||
| -rw-r--r-- | vis.c | 10 |
3 files changed, 14 insertions, 3 deletions
@@ -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 index 0a44555..9b4a8ab 100644 --- 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, @@ -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) { |
