tvi: % motion - neatvi - [fork] simple vi-type editor with UTF-8 support | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit 5266f5c8be4e977eaac06ea4a978d13c9b378d28 | |
parent 881d54517a9ce3a460cbfbf53c3efc323abd04d4 | |
Author: Ali Gholami Rudi <[email protected]> | |
Date: Wed, 10 Jun 2015 14:47:38 +0430 | |
vi: % motion | |
Diffstat: | |
M mot.c | 29 +++++++++++++++++++++++++++++ | |
M vi.c | 19 ++++++++++++++++--- | |
M vi.h | 1 + | |
3 files changed, 46 insertions(+), 3 deletions(-) | |
--- | |
diff --git a/mot.c b/mot.c | |
t@@ -184,3 +184,32 @@ int lbuf_wordend(struct lbuf *lb, int big, int dir, int *… | |
return 1; | |
return 0; | |
} | |
+ | |
+/* move to the matching character */ | |
+int lbuf_pair(struct lbuf *lb, int *row, int *off) | |
+{ | |
+ int r = *row, o = *off; | |
+ char *ln = lbuf_get(lb, *row); | |
+ char *pairs = "()[]{}"; | |
+ int p; /* index for pairs[] */ | |
+ int dep = 1; /* parenthesis depth */ | |
+ if (!ln || !ln[o]) | |
+ return 1; | |
+ while (!strchr(pairs, ln[o])) | |
+ if (!ln[++o]) | |
+ return 1; | |
+ p = strchr(pairs, ln[o]) - pairs; | |
+ while (!lbuf_next(lb, (p & 1) ? -1 : +1, &r, &o)) { | |
+ int c = (unsigned char) lbuf_chr(lb, r, o)[0]; | |
+ if (c == pairs[p ^ 1]) | |
+ dep--; | |
+ if (c == pairs[p]) | |
+ dep++; | |
+ if (!dep) { | |
+ *row = r; | |
+ *off = o; | |
+ return 0; | |
+ } | |
+ } | |
+ return 1; | |
+} | |
diff --git a/vi.c b/vi.c | |
t@@ -279,6 +279,12 @@ static int vi_motionln(int *row, int cmd) | |
*row = MAX(0, MIN(*row + cnt - 1, lbuf_len(xb) - 1)); | |
break; | |
} | |
+ if (c == '%' && (vi_arg1 || vi_arg2)) { | |
+ if (cnt > 100) | |
+ return -1; | |
+ *row = MAX(0, lbuf_len(xb) - 1) * cnt / 100; | |
+ break; | |
+ } | |
vi_back(c); | |
return 0; | |
} | |
t@@ -480,6 +486,10 @@ static int vi_motion(int *row, int *off) | |
*row = mark_row; | |
*off = mark_off; | |
break; | |
+ case '%': | |
+ if (lbuf_pair(xb, row, off)) | |
+ return -1; | |
+ break; | |
default: | |
vi_back(mv); | |
return 0; | |
t@@ -733,7 +743,7 @@ static int vc_motion(int cmd) | |
if (r1 == r2 && o1 > o2) | |
swap(&o1, &o2); | |
o1 = ren_noeol(lbuf_get(xb, r1), o1); | |
- if (!lnmode && strchr("fFtTeE", mv)) | |
+ if (!lnmode && strchr("fFtTeE%", mv)) | |
if (o2 < lbuf_eol(xb, r2)) | |
o2 = ren_noeol(lbuf_get(xb, r2), o2) + 1; | |
if (cmd == 'y') | |
t@@ -793,8 +803,10 @@ static int vc_put(int cmd) | |
int lnmode; | |
char *buf = reg_get(vi_ybuf, &lnmode); | |
int i; | |
- if (!buf) | |
+ if (!buf) { | |
+ snprintf(vi_msg, sizeof(vi_msg), "yank buffer empty\n"); | |
return 1; | |
+ } | |
if (lnmode) { | |
struct sbuf *sb = sbuf_make(); | |
for (i = 0; i < cnt; i++) | |
t@@ -982,7 +994,8 @@ static void vi(void) | |
vi_ybuf = vi_yankbuf(); | |
mv = vi_motion(&nrow, &noff); | |
if (mv > 0) { | |
- if (strchr("\'`GHML/?{}[]nN", mv)) { | |
+ if (strchr("\'`GHML/?{}[]nN", mv) || | |
+ (mv == '%' && noff < 0)) { | |
lbuf_mark(xb, '\'', xrow, xoff); | |
lbuf_mark(xb, '`', xrow, xoff); | |
} | |
diff --git a/vi.h b/vi.h | |
t@@ -30,6 +30,7 @@ int lbuf_paragraphbeg(struct lbuf *lb, int dir, int *row, in… | |
int lbuf_sectionbeg(struct lbuf *lb, int dir, int *row, int *off); | |
int lbuf_wordbeg(struct lbuf *lb, int big, int dir, int *row, int *off); | |
int lbuf_wordend(struct lbuf *lb, int big, int dir, int *row, int *off); | |
+int lbuf_pair(struct lbuf *lb, int *row, int *off); | |
/* string buffer, variable-sized string */ | |
struct sbuf *sbuf_make(void); |