| tvi: repeat and execute commands - neatvi - [fork] simple vi-type editor with U… | |
| git clone git://src.adamsgaard.dk/neatvi | |
| Log | |
| Files | |
| Refs | |
| README | |
| --- | |
| commit 901e0cd396e087f435fa96b51196d01d0f94ca18 | |
| parent 04a3edea64e70aae164a0550acaf5bf18ccac472 | |
| Author: Ali Gholami Rudi <[email protected]> | |
| Date: Tue, 2 Jun 2015 19:37:04 +0430 | |
| vi: repeat and execute commands | |
| Diffstat: | |
| M term.c | 45 +++++++++++++++++++++++++----… | |
| M vi.c | 39 +++++++++++++++++++++++++++++… | |
| M vi.h | 2 ++ | |
| 3 files changed, 78 insertions(+), 8 deletions(-) | |
| --- | |
| diff --git a/term.c b/term.c | |
| t@@ -109,17 +109,46 @@ int term_cols(void) | |
| return cols; | |
| } | |
| +static char ibuf[4096]; /* input character buffer */ | |
| +static char icmd[4096]; /* read after the last term_cmd() */ | |
| +static int ibuf_pos, ibuf_cnt; /* ibuf[] position and length */ | |
| +static int icmd_pos; /* icmd[] position */ | |
| + | |
| +/* read s before reading from the terminal */ | |
| +void term_push(char *s, int n) | |
| +{ | |
| + n = MIN(n, sizeof(ibuf) - ibuf_cnt); | |
| + memcpy(ibuf + ibuf_cnt, s, n); | |
| + ibuf_cnt += n; | |
| +} | |
| + | |
| +/* return a static buffer containing inputs read since the last term_cmd() */ | |
| +char *term_cmd(int *n) | |
| +{ | |
| + *n = icmd_pos; | |
| + icmd_pos = 0; | |
| + return icmd; | |
| +} | |
| + | |
| int term_read(int ms) | |
| { | |
| struct pollfd ufds[1]; | |
| - char b; | |
| - ufds[0].fd = 0; | |
| - ufds[0].events = POLLIN; | |
| - if (poll(ufds, 1, ms * 1000) <= 0) | |
| - return -1; | |
| - if (read(0, &b, 1) <= 0) | |
| - return -1; | |
| - return (unsigned char) b; | |
| + char n, c; | |
| + if (ibuf_pos >= ibuf_cnt) { | |
| + ufds[0].fd = 0; | |
| + ufds[0].events = POLLIN; | |
| + if (poll(ufds, 1, ms * 1000) <= 0) | |
| + return -1; | |
| + /* read a single input character */ | |
| + if ((n = read(0, ibuf, 1)) <= 0) | |
| + return -1; | |
| + ibuf_cnt = n; | |
| + ibuf_pos = 0; | |
| + } | |
| + c = ibuf_pos < ibuf_cnt ? (unsigned char) ibuf[ibuf_pos++] : -1; | |
| + if (icmd_pos < sizeof(icmd)) | |
| + icmd[icmd_pos++] = c; | |
| + return c; | |
| } | |
| /* return a static string that changes text attributes from old to att */ | |
| diff --git a/vi.c b/vi.c | |
| t@@ -907,6 +907,30 @@ static int vc_replace(void) | |
| return 0; | |
| } | |
| +static char rep_cmd[4096]; /* the last command */ | |
| +static int rep_len; | |
| + | |
| +static void vc_repeat(void) | |
| +{ | |
| + term_push(rep_cmd, rep_len); | |
| +} | |
| + | |
| +static void vc_execute(void) | |
| +{ | |
| + static int exec_buf; | |
| + int lnmode; | |
| + int c = vi_read(); | |
| + char *buf; | |
| + if (TK_INT(c)) | |
| + return; | |
| + if (c == '@') | |
| + c = exec_buf; | |
| + exec_buf = c; | |
| + buf = reg_get(exec_buf, &lnmode); | |
| + if (buf) | |
| + term_push(buf, strlen(buf)); | |
| +} | |
| + | |
| static void vi(void) | |
| { | |
| int xcol; | |
| t@@ -926,6 +950,7 @@ static void vi(void) | |
| int noff = ren_noeol(lbuf_get(xb, xrow), xoff); | |
| int otop = xtop; | |
| int mv, n; | |
| + term_cmd(&n); | |
| vi_arg2 = 0; | |
| vi_ybuf = vi_yankbuf(); | |
| vi_arg1 = vi_prefix(); | |
| t@@ -946,6 +971,7 @@ static void vi(void) | |
| if (mv == '|') | |
| xcol = vi_pcol; | |
| } else if (mv == 0) { | |
| + char *cmd; | |
| int c = vi_read(); | |
| int z, g; | |
| if (c <= 0) | |
| t@@ -1109,9 +1135,22 @@ static void vi(void) | |
| if (!vc_motion('~')) | |
| redraw = 1; | |
| break; | |
| + case '.': | |
| + vc_repeat(); | |
| + break; | |
| + case '@': | |
| + vc_execute(); | |
| + break; | |
| default: | |
| continue; | |
| } | |
| + cmd = term_cmd(&n); | |
| + if (strchr("!<>ACDIJOPRSXYacdioprsxy~", c)) { | |
| + if (n < sizeof(rep_cmd)) { | |
| + memcpy(rep_cmd, cmd, n); | |
| + rep_len = n; | |
| + } | |
| + } | |
| } | |
| if (xrow < 0 || xrow >= lbuf_len(xb)) | |
| xrow = lbuf_len(xb) ? lbuf_len(xb) - 1 : 0; | |
| diff --git a/vi.h b/vi.h | |
| t@@ -116,6 +116,8 @@ int term_read(int timeout); | |
| void term_record(void); | |
| void term_commit(void); | |
| char *term_att(int att, int old); | |
| +void term_push(char *s, int n); | |
| +char *term_cmd(int *n); | |
| #define TK_CTL(x) ((x) & 037) | |
| #define TK_INT(c) ((c) < 0 || (c) == TK_ESC || (c) == TK_CTL('c')) |