From 75ff22469b21e72a4c9126d89cfa3623af1784fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Wed, 22 Feb 2017 09:28:40 +0100 Subject: 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 --- vis-core.h | 1 + vis-motions.c | 6 ++++-- vis.c | 10 +++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/vis-core.h b/vis-core.h index 6147967..bbfab36 100644 --- 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 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, diff --git a/vis.c b/vis.c index 58c1a5c..aaead35 100644 --- 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) { -- cgit v1.2.3