tvi: searching with line offset - neatvi - [fork] simple vi-type editor with UT… | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit 390adf97095970215ad4f23c3288ec3e2d374e11 | |
parent 76467fcd1b5e8fc4fbc9ac1eae7d933272a8c09c | |
Author: Ali Gholami Rudi <[email protected]> | |
Date: Thu, 14 May 2015 12:53:02 +0430 | |
vi: searching with line offset | |
Like "/abc/+1"; note that, unlike "/abc/", it is a line motion. | |
Diffstat: | |
M vi.c | 179 ++++++++++++++++++-----------… | |
1 file changed, 103 insertions(+), 76 deletions(-) | |
--- | |
diff --git a/vi.c b/vi.c | |
t@@ -179,6 +179,7 @@ static int vi_search(int cmd, int cnt, int *row, int *col) | |
int failed = 0; | |
int len = 0; | |
int i, dir; | |
+ char *off = ""; | |
if (cmd == '/' || cmd == '?') { | |
char sign[4] = {cmd}; | |
char *kw; | |
t@@ -187,10 +188,12 @@ static int vi_search(int cmd, int cnt, int *row, int *co… | |
if (!(kw = led_prompt(sign, ""))) | |
return 1; | |
vi_finddir = cmd == '/' ? +1 : -1; | |
- if (strchr(kw, cmd)) | |
- *strchr(kw, cmd) = '\0'; | |
if (kw[0]) | |
snprintf(vi_findlast, sizeof(vi_findlast), "%s", kw); | |
+ if (strchr(vi_findlast, cmd)) { | |
+ off = strchr(vi_findlast, cmd) + 1; | |
+ *strchr(vi_findlast, cmd) = '\0'; | |
+ } | |
free(kw); | |
} | |
dir = cmd == 'N' ? -vi_finddir : vi_finddir; | |
t@@ -208,10 +211,70 @@ static int vi_search(int cmd, int cnt, int *row, int *co… | |
if (!failed) { | |
*row = r; | |
*col = ren_pos(lbuf_get(xb, r), c); | |
+ while (off[0] && isspace((unsigned char) off[0])) | |
+ off++; | |
+ if (off[0]) { | |
+ *col = -1; | |
+ if (*row + atoi(off) < 0 || *row + atoi(off) >= lbuf_l… | |
+ failed = 1; | |
+ else | |
+ *row += atoi(off); | |
+ } | |
} | |
return failed; | |
} | |
+/* move to the last character of the word */ | |
+static int lbuf_wordlast(struct lbuf *lb, int *row, int *col, int kind, int di… | |
+{ | |
+ if (!kind || !(uc_kind(lbuf_chr(lb, *row, *col)) & kind)) | |
+ return 0; | |
+ while (uc_kind(lbuf_chr(lb, *row, *col)) & kind) | |
+ if (lbuf_next(lb, row, col, dir)) | |
+ return 1; | |
+ if (!(uc_kind(lbuf_chr(lb, *row, *col)) & kind)) | |
+ lbuf_next(lb, row, col, -dir); | |
+ return 0; | |
+} | |
+ | |
+static int lbuf_wordbeg(struct lbuf *lb, int *row, int *col, int big, int dir) | |
+{ | |
+ int nl = 0; | |
+ lbuf_wordlast(lb, row, col, big ? 3 : uc_kind(lbuf_chr(lb, *row, *col)… | |
+ if (lbuf_next(lb, row, col, dir)) | |
+ return 1; | |
+ while (uc_isspace(lbuf_chr(lb, *row, *col))) { | |
+ nl = uc_code(lbuf_chr(lb, *row, *col)) == '\n' ? nl + 1 : 0; | |
+ if (nl == 2) | |
+ return 0; | |
+ if (lbuf_next(lb, row, col, dir)) | |
+ return 1; | |
+ } | |
+ return 0; | |
+} | |
+ | |
+static int lbuf_wordend(struct lbuf *lb, int *row, int *col, int big, int dir) | |
+{ | |
+ int nl = uc_code(lbuf_chr(lb, *row, *col)) == '\n' ? -1 : 0; | |
+ if (!uc_isspace(lbuf_chr(lb, *row, *col))) | |
+ if (lbuf_next(lb, row, col, dir)) | |
+ return 1; | |
+ while (uc_isspace(lbuf_chr(lb, *row, *col))) { | |
+ nl = uc_code(lbuf_chr(lb, *row, *col)) == '\n' ? nl + 1 : 0; | |
+ if (nl == 2) { | |
+ if (dir < 0) | |
+ lbuf_next(lb, row, col, -dir); | |
+ return 0; | |
+ } | |
+ if (lbuf_next(lb, row, col, dir)) | |
+ return 1; | |
+ } | |
+ if (lbuf_wordlast(lb, row, col, big ? 3 : uc_kind(lbuf_chr(lb, *row, *… | |
+ return 1; | |
+ return 0; | |
+} | |
+ | |
+/* read a line motion */ | |
static int vi_motionln(int *row, int cmd, int pre1, int pre2) | |
{ | |
int pre = (pre1 ? pre1 : 1) * (pre2 ? pre2 : 1); | |
t@@ -271,65 +334,21 @@ static int vi_motionln(int *row, int cmd, int pre1, int … | |
return c; | |
} | |
-/* move to the last character of the word */ | |
-static int lbuf_wordlast(struct lbuf *lb, int *row, int *col, int kind, int di… | |
-{ | |
- if (!kind || !(uc_kind(lbuf_chr(lb, *row, *col)) & kind)) | |
- return 0; | |
- while (uc_kind(lbuf_chr(lb, *row, *col)) & kind) | |
- if (lbuf_next(lb, row, col, dir)) | |
- return 1; | |
- if (!(uc_kind(lbuf_chr(lb, *row, *col)) & kind)) | |
- lbuf_next(lb, row, col, -dir); | |
- return 0; | |
-} | |
- | |
-static int lbuf_wordbeg(struct lbuf *lb, int *row, int *col, int big, int dir) | |
-{ | |
- int nl = 0; | |
- lbuf_wordlast(lb, row, col, big ? 3 : uc_kind(lbuf_chr(lb, *row, *col)… | |
- if (lbuf_next(lb, row, col, dir)) | |
- return 1; | |
- while (uc_isspace(lbuf_chr(lb, *row, *col))) { | |
- nl = uc_code(lbuf_chr(lb, *row, *col)) == '\n' ? nl + 1 : 0; | |
- if (nl == 2) | |
- return 0; | |
- if (lbuf_next(lb, row, col, dir)) | |
- return 1; | |
- } | |
- return 0; | |
-} | |
- | |
-static int lbuf_wordend(struct lbuf *lb, int *row, int *col, int big, int dir) | |
-{ | |
- int nl = uc_code(lbuf_chr(lb, *row, *col)) == '\n' ? -1 : 0; | |
- if (!uc_isspace(lbuf_chr(lb, *row, *col))) | |
- if (lbuf_next(lb, row, col, dir)) | |
- return 1; | |
- while (uc_isspace(lbuf_chr(lb, *row, *col))) { | |
- nl = uc_code(lbuf_chr(lb, *row, *col)) == '\n' ? nl + 1 : 0; | |
- if (nl == 2) { | |
- if (dir < 0) | |
- lbuf_next(lb, row, col, -dir); | |
- return 0; | |
- } | |
- if (lbuf_next(lb, row, col, dir)) | |
- return 1; | |
- } | |
- if (lbuf_wordlast(lb, row, col, big ? 3 : uc_kind(lbuf_chr(lb, *row, *… | |
- return 1; | |
- return 0; | |
-} | |
- | |
+/* read a motion */ | |
static int vi_motion(int *row, int *col, int pre1, int pre2) | |
{ | |
- int c = vi_read(); | |
int pre = (pre1 ? pre1 : 1) * (pre2 ? pre2 : 1); | |
char *ln = lbuf_get(xb, *row); | |
int dir = dir_context(ln ? ln : ""); | |
char *cs; | |
+ int mv; | |
int i; | |
- switch (c) { | |
+ if ((mv = vi_motionln(row, 0, pre1, pre2))) { | |
+ *col = -1; | |
+ return mv; | |
+ } | |
+ mv = vi_read(); | |
+ switch (mv) { | |
case ' ': | |
for (i = 0; i < pre; i++) | |
if (lbuf_lnnext(xb, row, col, 1)) | |
t@@ -337,11 +356,11 @@ static int vi_motion(int *row, int *col, int pre1, int p… | |
break; | |
case 'f': | |
if ((cs = vi_char())) | |
- lbuf_findchar(xb, row, col, cs, c, pre); | |
+ lbuf_findchar(xb, row, col, cs, mv, pre); | |
break; | |
case 'F': | |
if ((cs = vi_char())) | |
- lbuf_findchar(xb, row, col, cs, c, pre); | |
+ lbuf_findchar(xb, row, col, cs, mv, pre); | |
break; | |
case ';': | |
if (vi_charlast[0]) | |
t@@ -363,11 +382,11 @@ static int vi_motion(int *row, int *col, int pre1, int p… | |
break; | |
case 't': | |
if ((cs = vi_char())) | |
- lbuf_findchar(xb, row, col, cs, c, pre); | |
+ lbuf_findchar(xb, row, col, cs, mv, pre); | |
break; | |
case 'T': | |
if ((cs = vi_char())) | |
- lbuf_findchar(xb, row, col, cs, c, pre); | |
+ lbuf_findchar(xb, row, col, cs, mv, pre); | |
break; | |
case 'B': | |
for (i = 0; i < pre; i++) | |
t@@ -413,16 +432,16 @@ static int vi_motion(int *row, int *col, int pre1, int p… | |
*col = pre - 1; | |
break; | |
case '/': | |
- vi_search(c, pre, row, col); | |
+ vi_search(mv, pre, row, col); | |
break; | |
case '?': | |
- vi_search(c, pre, row, col); | |
+ vi_search(mv, pre, row, col); | |
break; | |
case 'n': | |
- vi_search(c, pre, row, col); | |
+ vi_search(mv, pre, row, col); | |
break; | |
case 'N': | |
- vi_search(c, pre, row, col); | |
+ vi_search(mv, pre, row, col); | |
break; | |
case 127: | |
case TK_CTL('h'): | |
t@@ -431,10 +450,10 @@ static int vi_motion(int *row, int *col, int pre1, int p… | |
break; | |
break; | |
default: | |
- vi_back(c); | |
+ vi_back(mv); | |
return 0; | |
} | |
- return c; | |
+ return mv; | |
} | |
static void swap(int *a, int *b) | |
t@@ -616,15 +635,17 @@ static void vc_motion(int cmd, int pre1) | |
int pre2 = vi_prefix(); | |
if (pre2 < 0) | |
return; | |
- if (vi_motionln(&r2, cmd, pre1, pre2)) { | |
- lnmode = 1; | |
+ if ((mv = vi_motionln(&r2, cmd, pre1, pre2))) { | |
+ c2 = -1; | |
+ } else if (!(mv = vi_motion(&r2, &c2, pre1, pre2))) { | |
+ return; | |
+ } | |
+ if (!strchr("fFtTeE$", mv)) | |
+ closed = 0; | |
+ lnmode = c2 < 0; | |
+ if (lnmode) { | |
lbuf_eol(xb, &r1, &c1, -1); | |
lbuf_eol(xb, &r2, &c2, +1); | |
- } else if ((mv = vi_motion(&r2, &c2, pre1, pre2))) { | |
- if (!strchr("fFtTeE$", mv)) | |
- closed = 0; | |
- } else { | |
- return; | |
} | |
if (cmd == 'y') | |
vi_yank(r1, c1, r2, c2, lnmode, closed); | |
t@@ -785,15 +806,21 @@ static void vi(void) | |
while (!xquit) { | |
int redraw = 0; | |
int orow = xrow; | |
+ int ocol = xcol; | |
int pre1, mv; | |
if ((pre1 = vi_prefix()) < 0) | |
continue; | |
- if ((mv = vi_motionln(&xrow, 0, pre1, 0))) { | |
- if (strchr("\'GHML", mv)) | |
+ mv = vi_motion(&xrow, &xcol, pre1, 0); | |
+ if (mv) { | |
+ if (strchr("\'GHML/?", mv)) | |
lbuf_mark(xb, '\'', orow); | |
- if (!strchr("jk", mv)) | |
- lbuf_postindents(xb, &xrow, &xcol); | |
- } else if (!vi_motion(&xrow, &xcol, pre1, 0)) { | |
+ if (xcol < 0) { | |
+ if (strchr("jk", mv)) | |
+ xcol = ocol; | |
+ else | |
+ lbuf_postindents(xb, &xrow, &xcol); | |
+ } | |
+ } else { | |
int c = vi_read(); | |
int z; | |
if (c <= 0) |