Heya, I have been working a few days on vi.c and have managed to
add a few things. I have a barely-working version of the "g" command
which I have ultimately decided to omit from this patch.

First thing I added was line ranges, the ability to specify
stuff like "10,45d" and have it delete lines 10-45, and also "%"
so you can do stuff like "%d" (and "%s" if I can get that working) 
It only supports plain numbers and doesn't do anything fancy like "+NUMBER" yet.
To get line ranges to work properly, The page has to be re-drawn or else the 
frame 
breaks (At least while deleting lines, the only thing I can do with these 
features as of now)

Also, after some testing I realized that the line gotos that I
implemented didn't work in some circumstances, such as at the
top or bottom of a file and/or after moving around in a file using
the cursor keys. I don't know why it does this... my code called
vi_go() and after some testing, calls it in the exact same
way that the "G" command does. I fixed this by making all line goto's run the 
"G" command and let that do whatever it does to prevent that.

I have added in the support for "Go down half a page" CTRL-D, 
and added in the CTL macro after
<e...@google.com> mentioned it. and replaced "27" with "\e"

- Oliver Webb <aquahobby...@proton.me>
From 27e2af1238cfbed0d8474fc929813a3fa014dce7 Mon Sep 17 00:00:00 2001
From: Oliver Webb <aquahobby...@proton.me>
Date: Sat, 30 Sep 2023 23:42:05 -0500
Subject: [PATCH] vi.c: Fixed line gotos, added CTL() macro, Line ranges (and
 "%"), CTRL-D, Replaced '27' with '\e'

---
 toys/pending/vi.c | 78 ++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 67 insertions(+), 11 deletions(-)

diff --git a/toys/pending/vi.c b/toys/pending/vi.c
index bb9c26cb..385ad7a8 100644
--- a/toys/pending/vi.c
+++ b/toys/pending/vi.c
@@ -21,6 +21,7 @@ config VI
 
 #define FOR_vi
 #include "toys.h"
+#define CTL(a) a-'@'
 
 GLOBALS(
   char *s;
@@ -1037,6 +1038,15 @@ static void ctrl_b()
   }
 }
 
+static void ctrl_d()
+{
+  int i;
+
+  for (i=0; i<(TT.screen_height-2)/2; ++i) TT.screen = text_nsol(TT.screen);
+  // TODO: real vi keeps the x position.
+  if (TT.screen > TT.cursor) TT.cursor = TT.screen;
+}
+
 static void ctrl_f()
 {
   int i;
@@ -1298,10 +1308,26 @@ static int run_vi_cmd(char *cmd)
   return 0;
 }
 
+// Page breaks while doing things like ":2,3d" unless we can call this
+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[0] == '/') search_str(cmd+1);
   else if (cmd[0] == '?') {
     // TODO: backwards search.
@@ -1326,15 +1352,42 @@ static int run_ex_cmd(char *cmd)
 
 		else if (*(cmd+1) == 'd') {
 			run_vi_cmd("dd");
+			run_vi_cmd("k");
 		}
+
 		// Line Ranges
 		else if (*(cmd+1) >= '0' && *(cmd+1) <= '9') {
-			vi_go(atoi(cmd+1), 1, "");
+			if (strstr(cmd, ",")) {
+				char *tcmd = xmalloc(strlen(cmd));
+				sscanf(cmd, ":%d,%d%[^\n]", &startline, &endline, tcmd+2);
+				cmd = tcmd;
+				ofst = 1;
+			} else run_vi_cmd(xmprintf("%dG", atoi(cmd+1)));
 		} else if (*(cmd+1) == '$') {
-			vi_go(1, 1, "");
-		}
+			run_vi_cmd("G");
+		} else if (*(cmd+1) == '%') {
+      startline = 1;
+      endline = get_endline();
+      ofst = 1;
+    }
 
-		else show_error("unknown command '%s'",cmd+1);
+    else show_error("unknown command '%s'",cmd+1);
+
+		if (ofst) {
+			draw_page();
+			int cline = TT.cur_row+1;
+			*(cmd+ofst) = ':';
+			run_vi_cmd(xmprintf("%dG", startline));
+			for (; startline <= endline; startline++) {
+				run_ex_cmd(cmd+ofst);
+				run_vi_cmd("j");
+			}
+			run_vi_cmd(xmprintf("%dG", cline));
+			// Screen Reset
+			ctrl_f();
+			draw_page();
+			ctrl_b();
+		}
   }
   return 0;
 }
@@ -1625,19 +1678,22 @@ void vi_main(void)
         case 'i':
           TT.vi_mode = 2;
           break;
-        case 'B'-'@':
+				case CTL('D'):
+					ctrl_d();
+					break;
+        case CTL('B'):
           ctrl_b();
           break;
-        case 'E'-'@':
+        case CTL('E'):
           ctrl_e();
           break;
-        case 'F'-'@':
+        case CTL('F'):
           ctrl_f();
           break;
-        case 'Y'-'@':
+        case CTL('Y'):
           ctrl_y();
           break;
-        case 27:
+        case '\e':
           vi_buf[0] = 0;
           vi_buf_pos = 0;
           break;
@@ -1671,7 +1727,7 @@ void vi_main(void)
             break;
           }
           // FALLTHROUGH
-        case 27:
+        case '\e':
           TT.vi_mode = 1;
           TT.il->len = 0;
           memset(TT.il->data, 0, TT.il->alloc);
@@ -1696,7 +1752,7 @@ void vi_main(void)
       }
     } else if (TT.vi_mode == 2) {//INSERT MODE
       switch (key) {
-        case 27:
+        case '\e':
           i_insert(TT.il->data, TT.il->len);
           cur_left(1, 1, 0);
           TT.vi_mode = 1;
-- 
2.34.1

_______________________________________________
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to