Looking at vi.c again, (I _know_ I can write code better then I did in October, and since the cleanup pass hasn't happened yet I thought I'd start improving things now) noticed there was no support for merging lines when doing a backspace at the start of a line (e.g. deleting blank lines by pressing backspace) So I added that. There is a bug where it will delete the last character of the line you are merging into, Still. That behavior is considerably better than nothing (And dunno how to debug it, vi_join isn't doing it's job for some reason) so I added it into the patch.
As far as ex commands go, this patch removes the function get_endline, and replaces it with directly probing the buffer. Which is much faster then redrawing the page 2 times. Other then that, This replaces a couple of variable names and removes a unnecessary goto - Oliver Webb <aquahobby...@proton.me>
From 96b3477da4a56cbc82d792319bfaf8464e5e20cf Mon Sep 17 00:00:00 2001 From: Oliver Webb <aquahobby...@proton.me> Date: Wed, 6 Mar 2024 22:13:12 -0600 Subject: [PATCH] vi.c: Merge with backspace at beginning of line support, Removed a goto, better variable names, removed get_endline and replaced it with a faster call. --- toys/pending/vi.c | 99 +++++++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 54 deletions(-) diff --git a/toys/pending/vi.c b/toys/pending/vi.c index 44a22a5e..96e78893 100644 --- a/toys/pending/vi.c +++ b/toys/pending/vi.c @@ -510,20 +510,17 @@ static size_t text_getline(char *dest, size_t offset, size_t max_len) // check big slices directly and just copy edge cases. // Also this is only line based search multiline // and regexec should be done instead. -static size_t text_strstr(size_t offset, char *str, int dir) +static size_t text_strstr(size_t offset, char *str, int forward) { size_t bytes, pos = offset; char *s = 0; do { bytes = text_getline(toybuf, pos, ARRAY_LEN(toybuf)); - if (!bytes) pos += (dir ? 1 : -1); //empty line + if (!bytes) pos += (forward ? 1 : -1); //empty line else if ((s = strstr(toybuf, str))) return pos+(s-toybuf); - else { - if (!dir) pos -= bytes; - else pos += bytes; - } - } while (pos < (dir ? 0 : TT.filesize)); + else pos += forward ? bytes : -bytes; + } while (pos < (forward ? 0 : TT.filesize)); return SIZE_MAX; } @@ -902,8 +899,28 @@ static int vi_x(char reg, int count0, int count1) return 1; } +static int vi_join(char reg, int count0, int count1) +{ + size_t next; + while (count0--) { + //just strchr(/n) and cut_str(pos, 1); + if ((next = text_strchr(TT.cursor, '\n')) == SIZE_MAX) break; + TT.cursor = next+1; + vi_delete(reg, TT.cursor-1, 0); + } + return 1; +} + +static int run_vi_cmd(char *); + static int backspace(char reg, int count0, int count1) { + if (!TT.cur_col) { + // TODO: Stop it from deleting the first character of the line it's + // merging into + cur_up(1, 1, 0); + run_vi_cmd("J"); + } size_t from = 0; size_t to = TT.cursor; cur_left(1, 1, 0); @@ -1187,18 +1204,6 @@ static int vi_I(char reg, int count0, int count1) return 1; } -static int vi_join(char reg, int count0, int count1) -{ - size_t next; - while (count0--) { - //just strchr(/n) and cut_str(pos, 1); - if ((next = text_strchr(TT.cursor, '\n')) == SIZE_MAX) break; - TT.cursor = next+1; - vi_delete(reg, TT.cursor-1, 0); - } - return 1; -} - static int vi_find_next(char reg, int count0, int count1) { if (TT.last_search) search_str(TT.last_search, 1); @@ -1335,29 +1340,13 @@ static int run_vi_cmd(char *cmd) return 0; } - -static void draw_page(); - -static int get_endline(void) -{ - int cln, rln; - - draw_page(); - cln = TT.cur_row+1; - run_vi_cmd("G"); - draw_page(); - rln = TT.cur_row+1; - run_vi_cmd(xmprintf("%dG", cln)); - - return rln+1; -} - // Return non-zero to exit. static int run_ex_cmd(char *cmd) { int startline = 1, ofst = 0, endline; if (*cmd == '/' || *cmd == '\?') search_str(cmd+1, *cmd == '/' ? 0 : 1); + else if (*cmd == ':') { if (cmd[1] == 'q') { if (cmd[2] != '!' && modified()) @@ -1380,26 +1369,28 @@ static int run_ex_cmd(char *cmd) else if (cmd[1] == 'd') { run_vi_cmd("dd"); cur_up(1, 1, 0); - } else if (cmd[1] == 'j') run_vi_cmd("J"); + } else if (cmd[1] == 'j') vi_join(0, 1, 0); + else if (cmd[1] == 'g' || cmd[1] == 'v') { char *rgx = xmalloc(strlen(cmd)); - int el = get_endline(), ln = 0, vorg = (cmd[1] == 'v' ? REG_NOMATCH : 0); + int el = text_count(0, text_filesize(), '\n'), i = 0, + vorg = (cmd[1] == 'v') ? REG_NOMATCH : 0; regex_t rgxc; if (!sscanf(cmd+2, "/%[^/]/%[^\ng]", rgx, cmd+1) || - regcomp(&rgxc, rgx, 0)) goto gcleanup; - - cmd[0] = ':'; - - for (; ln < el; ln++) { - run_vi_cmd("yy"); - if (regexec(&rgxc, TT.yank.data, 0, 0, 0) == vorg) run_ex_cmd(cmd); - cur_down(1, 1, 0); + !regcomp(&rgxc, rgx, 0)) { + *cmd = ':'; + + for (; i < el; i++) { + run_vi_cmd("yy"); + if (regexec(&rgxc, TT.yank.data, 0, 0, 0) == vorg) + run_ex_cmd(cmd); + cur_down(1, 1, 0); + } + + // Reset Frame + TT.vi_mov_flag |= 0x30000000; } - - // Reset Frame - TT.vi_mov_flag |= 0x30000000; -gcleanup: regfree(&rgxc); free(rgx); } @@ -1411,16 +1402,16 @@ gcleanup: } else run_vi_cmd(xmprintf("%dG", atoi(cmd+1))); } else if (cmd[1] == '$') run_vi_cmd("G"); else if (cmd[1] == '%') { - endline = get_endline(); + endline = text_count(0, text_filesize(), '\n')+1; ofst = 1; } else show_error("unknown command '%s'",cmd+1); if (ofst) { int cline = TT.cur_row+1; - cmd[ofst] = ':'; - for (; startline <= endline; startline++) { - run_ex_cmd(cmd+ofst); + cmd[1] = ':'; + for (run_vi_cmd(xmprintf("%dG", startline)); startline <= endline; startline++) { + run_ex_cmd(cmd+1); cur_down(1, 1, 0); } run_vi_cmd(xmprintf("%dG", cline)); -- 2.44.0
_______________________________________________ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net