aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2017-02-22 09:28:40 +0100
committerMarc André Tanner <mat@brain-dump.org>2017-02-22 12:42:19 +0100
commit75ff22469b21e72a4c9126d89cfa3623af1784fd (patch)
tree0cfd4b74d377735db2d7f81d34b630b1f79f2a0a
parenta08d2fa4e547341e9298b0eaf7678f1dc67f0612 (diff)
downloadvis-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.h1
-rw-r--r--vis-motions.c6
-rw-r--r--vis.c10
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) {