I have added the 'v' command (Which is essentially the opposite of the g[lobal] 
command).
Fixed a memory leak in the g[lobal] command (Freeing data while aborting)
Along with some code formatting (Replacing *(cmd+1) with cmd[1])

I have been trying to get a implementation of the s[ubsitute] command to work 
in vi.c.
The best I have been able to implement barely works. I know sed.c has one that 
does what
I am trying to do but I haven't been able to implement the algorithm that sed.c 
is using.

- Oliver Webb <[email protected]>
From 57662e80efd82f961e98beb61372d5fe39dd273e Mon Sep 17 00:00:00 2001
From: Oliver Webb <[email protected]>
Date: Sat, 14 Oct 2023 16:33:47 -0500
Subject: [PATCH] vi.c: Added 'v' command and updated help text

---
 toys/pending/vi.c | 34 +++++++++++++++++++---------------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/toys/pending/vi.c b/toys/pending/vi.c
index ee6fd96e..74e644b1 100644
--- a/toys/pending/vi.c
+++ b/toys/pending/vi.c
@@ -33,7 +33,7 @@ config VI
     ex mode commands:
 
       [cmd]
-      \b \e \n w wq q! 'set list' 'set nolist' d $ %
+      \b \e \n w wq q! 'set list' 'set nolist' d $ % g v
 */
 #define FOR_vi
 #include "toys.h"
@@ -1341,6 +1341,8 @@ static int get_endline(void)
   return rln+1;
 }
 
+#define SUBSTRING(str, slen, elen) xmprintf("%.*s", elen, str+slen);
+
 // Return non-zero to exit.
 static int run_ex_cmd(char *cmd)
 {
@@ -1368,31 +1370,33 @@ static int run_ex_cmd(char *cmd)
       TT.vi_mov_flag |= 0x30000000;
     }
 
-    else if (*(cmd+1) == 'd') {
+    else if (cmd[1] == 'd') {
       run_vi_cmd("dd");
       run_vi_cmd("k");
-    } else if (*(cmd+1) == 'g') {
-      char *rgx = malloc(strlen(cmd));
-      int el = get_endline(), ln = 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);
       regex_t rgxc;
-      if (!sscanf(cmd, ":g/%[^/]/%[^\ng]", rgx, cmd+1)) return 0;
-      if (regcomp(&rgxc, rgx, 0)) return 0;
+
+      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)) run_ex_cmd(cmd);
+        if (regexec(&rgxc, TT.yank.data, 0, 0, 0) == vorg) run_ex_cmd(cmd);
         run_vi_cmd("j");
       }
 
       // Reset Frame
-      ctrl_f();
-      draw_page();
-      ctrl_b();
-    }
+      ctrl_f(); draw_page(); ctrl_b();
+gcleanup:
+      regfree(&rgxc); free(rgx);
+    } 
 
     // Line Ranges
-    else if (*(cmd+1) >= '0' && *(cmd+1) <= '9') {
+    else if (cmd[1] >= '0' && cmd[1] <= '9') {
       if (strstr(cmd, ",")) {
         char *tcmd = xmalloc(strlen(cmd));
 
@@ -1400,8 +1404,8 @@ static int run_ex_cmd(char *cmd)
         cmd = tcmd;
         ofst = 1;
       } else run_vi_cmd(xmprintf("%dG", atoi(cmd+1)));
-    } else if (*(cmd+1) == '$') run_vi_cmd("G");
-    else if (*(cmd+1) == '%') {
+    } else if (cmd[1] == '$') run_vi_cmd("G");
+    else if (cmd[1] == '%') {
       startline = 1;
       endline = get_endline();
       ofst = 1;
-- 
2.34.1

_______________________________________________
Toybox mailing list
[email protected]
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to