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

Reply via email to