tvi: specifying yank buffer for d, c, y, and p - neatvi - [fork] simple vi-type… | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit 6e9f030b017fe128151501d6c0bad0c6e72a8c73 | |
parent d7772d9c05727a0892b134ed83bd2f834a039fa6 | |
Author: Ali Gholami Rudi <[email protected]> | |
Date: Fri, 15 May 2015 10:18:52 +0430 | |
vi: specifying yank buffer for d, c, y, and p | |
Diffstat: | |
M vi.c | 211 +++++++++++++++++------------… | |
1 file changed, 117 insertions(+), 94 deletions(-) | |
--- | |
diff --git a/vi.c b/vi.c | |
t@@ -26,6 +26,8 @@ static char vi_findlast[256]; /* the last searched ke… | |
static int vi_finddir; /* the last search direction */ | |
static char vi_charlast[8]; /* the last character searched via f, t, F,… | |
static int vi_charcmd; /* the character finding command */ | |
+static int vi_arg1, vi_arg2; /* the first and second arguments */ | |
+static int vi_ybuf; /* current yank buffer */ | |
static void vi_draw(void) | |
{ | |
t@@ -60,18 +62,27 @@ static char *vi_char(void) | |
return TK_INT(key) ? NULL : led_keymap(key); | |
} | |
+static int vi_yankbuf(void) | |
+{ | |
+ int c = vi_read(); | |
+ if (c == '"') | |
+ return vi_read(); | |
+ vi_back(c); | |
+ return 0; | |
+} | |
+ | |
static int vi_prefix(void) | |
{ | |
- int pre = 0; | |
+ int n = 0; | |
int c = vi_read(); | |
if ((c >= '1' && c <= '9')) { | |
while (isdigit(c)) { | |
- pre = pre * 10 + c - '0'; | |
+ n = n * 10 + c - '0'; | |
c = vi_read(); | |
} | |
} | |
vi_back(c); | |
- return pre; | |
+ return n; | |
} | |
static int lbuf_lnnext(struct lbuf *lb, int *r, int *c, int dir) | |
t@@ -271,21 +282,21 @@ static int lbuf_wordend(struct lbuf *lb, int *row, int *… | |
} | |
/* read a line motion */ | |
-static int vi_motionln(int *row, int cmd, int pre1, int pre2) | |
+static int vi_motionln(int *row, int cmd) | |
{ | |
- int pre = (pre1 ? pre1 : 1) * (pre2 ? pre2 : 1); | |
+ int cnt = (vi_arg1 ? vi_arg1 : 1) * (vi_arg2 ? vi_arg2 : 1); | |
int c = vi_read(); | |
int mark; | |
switch (c) { | |
case '\n': | |
case '+': | |
- *row = MIN(*row + pre, lbuf_len(xb) - 1); | |
+ *row = MIN(*row + cnt, lbuf_len(xb) - 1); | |
break; | |
case '-': | |
- *row = MAX(*row - pre, 0); | |
+ *row = MAX(*row - cnt, 0); | |
break; | |
case '_': | |
- *row = MIN(*row + pre - 1, lbuf_len(xb) - 1); | |
+ *row = MIN(*row + cnt - 1, lbuf_len(xb) - 1); | |
break; | |
case '\'': | |
if ((mark = vi_read()) > 0 && (isalpha(mark) || mark == '\'')) | |
t@@ -293,23 +304,23 @@ static int vi_motionln(int *row, int cmd, int pre1, int … | |
*row = lbuf_markpos(xb, mark); | |
break; | |
case 'j': | |
- *row = MIN(*row + pre, lbuf_len(xb) - 1); | |
+ *row = MIN(*row + cnt, lbuf_len(xb) - 1); | |
break; | |
case 'k': | |
- *row = MAX(*row - pre, 0); | |
+ *row = MAX(*row - cnt, 0); | |
break; | |
case 'G': | |
- *row = (pre1 || pre2) ? pre - 1 : lbuf_len(xb) - 1; | |
+ *row = (vi_arg1 || vi_arg2) ? cnt - 1 : lbuf_len(xb) - 1; | |
break; | |
case 'H': | |
if (lbuf_len(xb)) | |
- *row = MIN(xtop + pre - 1, lbuf_len(xb) - 1); | |
+ *row = MIN(xtop + cnt - 1, lbuf_len(xb) - 1); | |
else | |
*row = 0; | |
break; | |
case 'L': | |
if (lbuf_len(xb)) | |
- *row = MIN(xtop + xrows - 1 - pre + 1, lbuf_len(xb) - … | |
+ *row = MIN(xtop + xrows - 1 - cnt + 1, lbuf_len(xb) - … | |
else | |
*row = 0; | |
break; | |
t@@ -321,7 +332,7 @@ static int vi_motionln(int *row, int cmd, int pre1, int pr… | |
break; | |
default: | |
if (c == cmd) { | |
- *row = MIN(*row + pre - 1, lbuf_len(xb) - 1); | |
+ *row = MIN(*row + cnt - 1, lbuf_len(xb) - 1); | |
break; | |
} | |
vi_back(c); | |
t@@ -331,92 +342,92 @@ static int vi_motionln(int *row, int cmd, int pre1, int … | |
} | |
/* read a motion */ | |
-static int vi_motion(int *row, int *col, int pre1, int pre2) | |
+static int vi_motion(int *row, int *col) | |
{ | |
- int pre = (pre1 ? pre1 : 1) * (pre2 ? pre2 : 1); | |
+ int cnt = (vi_arg1 ? vi_arg1 : 1) * (vi_arg2 ? vi_arg2 : 1); | |
char *ln = lbuf_get(xb, *row); | |
int dir = dir_context(ln ? ln : ""); | |
char *cs; | |
int mv; | |
int i; | |
- if ((mv = vi_motionln(row, 0, pre1, pre2))) { | |
+ if ((mv = vi_motionln(row, 0))) { | |
*col = -1; | |
return mv; | |
} | |
mv = vi_read(); | |
switch (mv) { | |
case ' ': | |
- for (i = 0; i < pre; i++) | |
+ for (i = 0; i < cnt; i++) | |
if (lbuf_lnnext(xb, row, col, 1)) | |
break; | |
break; | |
case 'f': | |
if ((cs = vi_char())) | |
- if (lbuf_findchar(xb, row, col, cs, mv, pre)) | |
+ if (lbuf_findchar(xb, row, col, cs, mv, cnt)) | |
return -1; | |
break; | |
case 'F': | |
if ((cs = vi_char())) | |
- if (lbuf_findchar(xb, row, col, cs, mv, pre)) | |
+ if (lbuf_findchar(xb, row, col, cs, mv, cnt)) | |
return -1; | |
break; | |
case ';': | |
if (vi_charlast[0]) | |
- if (lbuf_findchar(xb, row, col, vi_charlast, vi_charcm… | |
+ if (lbuf_findchar(xb, row, col, vi_charlast, vi_charcm… | |
return -1; | |
break; | |
case ',': | |
if (vi_charlast[0]) | |
- if (lbuf_findchar(xb, row, col, vi_charlast, vi_charcm… | |
+ if (lbuf_findchar(xb, row, col, vi_charlast, vi_charcm… | |
return -1; | |
break; | |
case 'h': | |
- for (i = 0; i < pre; i++) | |
+ for (i = 0; i < cnt; i++) | |
if (lbuf_lnnext(xb, row, col, -1 * dir)) | |
break; | |
break; | |
case 'l': | |
- for (i = 0; i < pre; i++) | |
+ for (i = 0; i < cnt; i++) | |
if (lbuf_lnnext(xb, row, col, +1 * dir)) | |
break; | |
break; | |
case 't': | |
if ((cs = vi_char())) | |
- if (lbuf_findchar(xb, row, col, cs, mv, pre)) | |
+ if (lbuf_findchar(xb, row, col, cs, mv, cnt)) | |
return -1; | |
break; | |
case 'T': | |
if ((cs = vi_char())) | |
- if (lbuf_findchar(xb, row, col, cs, mv, pre)) | |
+ if (lbuf_findchar(xb, row, col, cs, mv, cnt)) | |
return -1; | |
break; | |
case 'B': | |
- for (i = 0; i < pre; i++) | |
+ for (i = 0; i < cnt; i++) | |
if (lbuf_wordend(xb, row, col, 1, -1)) | |
break; | |
break; | |
case 'E': | |
- for (i = 0; i < pre; i++) | |
+ for (i = 0; i < cnt; i++) | |
if (lbuf_wordend(xb, row, col, 1, +1)) | |
break; | |
break; | |
case 'W': | |
- for (i = 0; i < pre; i++) | |
+ for (i = 0; i < cnt; i++) | |
if (lbuf_wordbeg(xb, row, col, 1, +1)) | |
break; | |
break; | |
case 'b': | |
- for (i = 0; i < pre; i++) | |
+ for (i = 0; i < cnt; i++) | |
if (lbuf_wordend(xb, row, col, 0, -1)) | |
break; | |
break; | |
case 'e': | |
- for (i = 0; i < pre; i++) | |
+ for (i = 0; i < cnt; i++) | |
if (lbuf_wordend(xb, row, col, 0, +1)) | |
break; | |
break; | |
case 'w': | |
- for (i = 0; i < pre; i++) | |
+ for (i = 0; i < cnt; i++) | |
if (lbuf_wordbeg(xb, row, col, 0, +1)) | |
break; | |
break; | |
t@@ -431,27 +442,27 @@ static int vi_motion(int *row, int *col, int pre1, int p… | |
lbuf_lnnext(xb, row, col, -1); | |
break; | |
case '|': | |
- *col = pre - 1; | |
+ *col = cnt - 1; | |
break; | |
case '/': | |
- if (vi_search(mv, pre, row, col)) | |
+ if (vi_search(mv, cnt, row, col)) | |
return -1; | |
break; | |
case '?': | |
- if (vi_search(mv, pre, row, col)) | |
+ if (vi_search(mv, cnt, row, col)) | |
return -1; | |
break; | |
case 'n': | |
- if (vi_search(mv, pre, row, col)) | |
+ if (vi_search(mv, cnt, row, col)) | |
return -1; | |
break; | |
case 'N': | |
- if (vi_search(mv, pre, row, col)) | |
+ if (vi_search(mv, cnt, row, col)) | |
return -1; | |
break; | |
case 127: | |
case TK_CTL('h'): | |
- for (i = 0; i < pre; i++) | |
+ for (i = 0; i < cnt; i++) | |
if (lbuf_lnnext(xb, row, col, -1)) | |
break; | |
break; | |
t@@ -534,7 +545,7 @@ static void vi_yank(int r1, int c1, int r2, int c2, int ln… | |
int l1, l2; | |
vi_commandregion(&r1, &r2, &c1, &c2, &l1, &l2, closed); | |
region = lbuf_region(xb, r1, lnmode ? 0 : l1, r2, lnmode ? -1 : l2); | |
- reg_put(0, region, lnmode); | |
+ reg_put(vi_ybuf, region, lnmode); | |
free(region); | |
xrow = r1; | |
xcol = lnmode ? xcol : c1; | |
t@@ -547,7 +558,7 @@ static void vi_delete(int r1, int c1, int r2, int c2, int … | |
int l1, l2; | |
vi_commandregion(&r1, &r2, &c1, &c2, &l1, &l2, closed); | |
region = lbuf_region(xb, r1, lnmode ? 0 : l1, r2, lnmode ? -1 : l2); | |
- reg_put(0, region, lnmode); | |
+ reg_put(vi_ybuf, region, lnmode); | |
free(region); | |
pref = lnmode ? uc_dup("") : uc_sub(lbuf_get(xb, r1), 0, l1); | |
post = lnmode ? uc_dup("\n") : uc_sub(lbuf_get(xb, r2), l2, -1); | |
t@@ -640,7 +651,7 @@ static void vi_change(int r1, int c1, int r2, int c2, int … | |
char *pref, *post; | |
vi_commandregion(&r1, &r2, &c1, &c2, &l1, &l2, closed); | |
region = lbuf_region(xb, r1, lnmode ? 0 : l1, r2, lnmode ? -1 : l2); | |
- reg_put(0, region, lnmode); | |
+ reg_put(vi_ybuf, region, lnmode); | |
free(region); | |
pref = lnmode ? vi_indents(lbuf_get(xb, r1)) : uc_sub(lbuf_get(xb, r1)… | |
post = lnmode ? uc_dup("\n") : uc_sub(lbuf_get(xb, r2), l2, -1); | |
t@@ -656,23 +667,24 @@ static void vi_change(int r1, int c1, int r2, int c2, in… | |
free(post); | |
} | |
-static void vc_motion(int cmd, int pre1) | |
+static int vc_motion(int cmd) | |
{ | |
int r1 = xrow, r2 = xrow; /* region rows */ | |
int c1 = xcol, c2 = xcol; /* visual region columns */ | |
int lnmode = 0; /* line-based region */ | |
int closed = 1; /* include the last character */ | |
int mv; | |
- int pre2 = vi_prefix(); | |
- if (pre2 < 0) | |
- return; | |
- if ((mv = vi_motionln(&r2, cmd, pre1, pre2))) { | |
+ vi_arg2 = vi_prefix(); | |
+ if (vi_arg2 < 0) | |
+ return 1; | |
+ if ((mv = vi_motionln(&r2, cmd))) { | |
c2 = -1; | |
- } else if (!(mv = vi_motion(&r2, &c2, pre1, pre2))) { | |
- return; | |
+ } else if (!(mv = vi_motion(&r2, &c2))) { | |
+ vi_read(); | |
+ return 1; | |
} | |
if (mv < 0) | |
- return; | |
+ return 1; | |
if (!strchr("fFtTeE$", mv)) | |
closed = 0; | |
lnmode = c2 < 0; | |
t@@ -686,9 +698,10 @@ static void vc_motion(int cmd, int pre1) | |
vi_delete(r1, c1, r2, c2, lnmode, closed); | |
if (cmd == 'c') | |
vi_change(r1, c1, r2, c2, lnmode, closed); | |
+ return 0; | |
} | |
-static void vc_insert(int cmd) | |
+static int vc_insert(int cmd) | |
{ | |
char *pref, *post; | |
char *ln = lbuf_get(xb, xrow); | |
t@@ -721,18 +734,20 @@ static void vc_insert(int cmd) | |
} | |
free(pref); | |
free(post); | |
+ return !rep; | |
} | |
-static void vc_put(int cmd, int cnt) | |
+static int vc_put(int cmd) | |
{ | |
+ int cnt = MAX(1, vi_arg1); | |
int lnmode; | |
char *ln; | |
- char *buf = reg_get(0, &lnmode); | |
+ char *buf = reg_get(vi_ybuf, &lnmode); | |
struct sbuf *sb; | |
int off; | |
int i; | |
if (!buf) | |
- return; | |
+ return 1; | |
ln = lnmode ? NULL : lbuf_get(xb, xrow); | |
off = ln ? vi_insertionoffset(ln, xcol, cmd == 'P') : 0; | |
if (cmd == 'p' && !ln) | |
t@@ -750,11 +765,13 @@ static void vc_put(int cmd, int cnt) | |
sbuf_str(sb, s); | |
free(s); | |
} | |
+ if (!ln && !lbuf_len(xb)) | |
+ lbuf_put(xb, 0, "\n"); | |
if (ln) | |
lbuf_rm(xb, xrow, xrow + 1); | |
lbuf_put(xb, xrow, sbuf_buf(sb)); | |
sbuf_free(sb); | |
- | |
+ return 0; | |
} | |
static int join_spaces(char *prev, char *next) | |
t@@ -767,16 +784,16 @@ static int join_spaces(char *prev, char *next) | |
return prev[prevlen - 1] == '.' ? 2 : 1; | |
} | |
-static void vc_join(int arg) | |
+static int vc_join(void) | |
{ | |
struct sbuf *sb; | |
- int cnt = arg <= 1 ? 2 : arg; | |
+ int cnt = vi_arg1 <= 1 ? 2 : vi_arg1; | |
int beg = xrow; | |
int end = xrow + cnt; | |
int off = 0; | |
int i; | |
if (!lbuf_get(xb, beg) || !lbuf_get(xb, end - 1)) | |
- return; | |
+ return 1; | |
sb = sbuf_make(); | |
for (i = beg; i < end; i++) { | |
char *ln = lbuf_get(xb, i); | |
t@@ -796,6 +813,7 @@ static void vc_join(int arg) | |
lbuf_put(xb, beg, sbuf_buf(sb)); | |
xcol = ren_pos(sbuf_buf(sb), off); | |
sbuf_free(sb); | |
+ return 0; | |
} | |
static int vi_scrollforeward(int cnt) | |
t@@ -824,9 +842,9 @@ static void vi_status(void) | |
led_print(stat, xrows); | |
} | |
-static int vc_replace(int arg) | |
+static int vc_replace(void) | |
{ | |
- int cnt = MAX(1, arg); | |
+ int cnt = MAX(1, vi_arg1); | |
char *cs = vi_char(); | |
char *ln = lbuf_get(xb, xrow); | |
struct sbuf *sb; | |
t@@ -872,10 +890,13 @@ static void vi(void) | |
int redraw = 0; | |
int orow = xrow; | |
int ocol = xcol; | |
- int pre1, mv; | |
- if ((pre1 = vi_prefix()) < 0) | |
- continue; | |
- mv = vi_motion(&xrow, &xcol, pre1, 0); | |
+ int mv, n; | |
+ vi_arg2 = 0; | |
+ vi_ybuf = vi_yankbuf(); | |
+ vi_arg1 = vi_prefix(); | |
+ if (!vi_ybuf) | |
+ vi_ybuf = vi_yankbuf(); | |
+ mv = vi_motion(&xrow, &xcol); | |
if (mv > 0) { | |
if (strchr("\'GHML/?", mv)) | |
lbuf_mark(xb, '\'', orow); | |
t@@ -892,24 +913,24 @@ static void vi(void) | |
continue; | |
switch (c) { | |
case TK_CTL('b'): | |
- if (vi_scrollbackward((pre1 ? pre1 : 1) * (xro… | |
+ if (vi_scrollbackward(MAX(1, vi_arg1) * (xrows… | |
break; | |
lbuf_postindents(xb, &xrow, &xcol); | |
redraw = 1; | |
break; | |
case TK_CTL('f'): | |
- if (vi_scrollforeward((pre1 ? pre1 : 1) * (xro… | |
+ if (vi_scrollforeward(MAX(1, vi_arg1) * (xrows… | |
break; | |
lbuf_postindents(xb, &xrow, &xcol); | |
redraw = 1; | |
break; | |
case TK_CTL('e'): | |
- if (vi_scrollforeward((pre1 ? pre1 : 1))) | |
+ if (vi_scrollforeward(MAX(1, vi_arg1))) | |
break; | |
redraw = 1; | |
break; | |
case TK_CTL('y'): | |
- if (vi_scrollbackward((pre1 ? pre1 : 1))) | |
+ if (vi_scrollbackward(MAX(1, vi_arg1))) | |
break; | |
redraw = 1; | |
break; | |
t@@ -943,8 +964,8 @@ static void vi(void) | |
case 'c': | |
case 'd': | |
case 'y': | |
- vc_motion(c, pre1); | |
- redraw = 1; | |
+ if (!vc_motion(c)) | |
+ redraw = 1; | |
break; | |
case 'i': | |
case 'I': | |
t@@ -952,12 +973,12 @@ static void vi(void) | |
case 'A': | |
case 'o': | |
case 'O': | |
- vc_insert(c); | |
- redraw = 1; | |
+ if (!vc_insert(c)) | |
+ redraw = 1; | |
break; | |
case 'J': | |
- vc_join(pre1); | |
- redraw = 1; | |
+ if (!vc_join()) | |
+ redraw = 1; | |
break; | |
case 'm': | |
if ((mark = vi_read()) > 0 && isalpha(mark)) | |
t@@ -965,20 +986,22 @@ static void vi(void) | |
break; | |
case 'p': | |
case 'P': | |
- vc_put(c, pre1); | |
- redraw = 1; | |
+ if (!vc_put(c)) | |
+ redraw = 1; | |
break; | |
case 'z': | |
z = vi_read(); | |
switch (z) { | |
case '\n': | |
- xtop = pre1 ? pre1 : xrow; | |
+ xtop = vi_arg1 ? vi_arg1 : xrow; | |
break; | |
case '.': | |
- xtop = MAX(0, (pre1 ? pre1 : xrow) - x… | |
+ n = vi_arg1 ? vi_arg1 : xrow; | |
+ xtop = MAX(0, n - xrows / 2); | |
break; | |
case '-': | |
- xtop = MAX(0, (pre1 ? pre1 : xrow) - x… | |
+ n = vi_arg1 ? vi_arg1 : xrow; | |
+ xtop = MAX(0, n - xrows + 1); | |
break; | |
case 'l': | |
case 'r': | |
t@@ -991,42 +1014,42 @@ static void vi(void) | |
break; | |
case 'x': | |
vi_back(' '); | |
- vc_motion('d', pre1); | |
- redraw = 1; | |
+ if (!vc_motion('d')) | |
+ redraw = 1; | |
break; | |
case 'X': | |
vi_back(TK_CTL('h')); | |
- vc_motion('d', pre1); | |
- redraw = 1; | |
+ if (!vc_motion('d')) | |
+ redraw = 1; | |
break; | |
case 'C': | |
vi_back('$'); | |
- vc_motion('c', pre1); | |
- redraw = 1; | |
+ if (!vc_motion('c')) | |
+ redraw = 1; | |
break; | |
case 'D': | |
vi_back('$'); | |
- vc_motion('d', pre1); | |
- redraw = 1; | |
+ if (vc_motion('d')) | |
+ redraw = 1; | |
break; | |
case 'r': | |
- vc_replace(pre1); | |
- redraw = 1; | |
+ if (!vc_replace()) | |
+ redraw = 1; | |
break; | |
case 's': | |
vi_back(' '); | |
- vc_motion('c', pre1); | |
- redraw = 1; | |
+ if (!vc_motion('c')) | |
+ redraw = 1; | |
break; | |
case 'S': | |
vi_back('c'); | |
- vc_motion('c', pre1); | |
- redraw = 1; | |
+ if (!vc_motion('c')) | |
+ redraw = 1; | |
break; | |
case 'Y': | |
vi_back('y'); | |
- vc_motion('y', pre1); | |
- redraw = 1; | |
+ if (!vc_motion('y')) | |
+ redraw = 1; | |
break; | |
default: | |
continue; |