tvi: searching with line offset - neatvi - [fork] simple vi-type editor with UTF-8 support
(HTM) git clone git://src.adamsgaard.dk/neatvi
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
(DIR) commit 390adf97095970215ad4f23c3288ec3e2d374e11
(DIR) parent 76467fcd1b5e8fc4fbc9ac1eae7d933272a8c09c
(HTM) Author: Ali Gholami Rudi <ali@rudi.ir>
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(-)
---
(DIR) 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 *col)
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 *col)
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_len(xb))
+ 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 dir)
+{
+ 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)), dir);
+ 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, *col)), dir))
+ 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 pre2)
return c;
}
-/* move to the last character of the word */
-static int lbuf_wordlast(struct lbuf *lb, int *row, int *col, int kind, int dir)
-{
- 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)), dir);
- 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, *col)), dir))
- 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 pre2)
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 pre2)
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 pre2)
*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 pre2)
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)