------- Original Message -------
On Tuesday, October 17th, 2023 at 04:42, Rob Landley <[email protected]> wrote:


> On 10/16/23 22:29, Oliver Webb wrote:
> 
> > > I was hoping to get stuff to share code, but I can worry about that in the
> > > eventual cleanup pass.
> > 
> > If you are planning on code-sharing the regex line substitution stuff.
> > Then this will probably be my last patch to vi.c for a while
> > (Unless there is something wrong with it that can be fixed reasonably).
> 
> 
> "Planning" is a strong word. I would generally like code to be shared in the
> toybox when that isn't hard to do, but I haven't evaluated how hard it is to 
> do
> here.

When attempting to write 's'[ubsitute] in vi. I tried to copy off sed.c more 
then once.
Although the reason I failed probably because I am unfamiliar with the code for 
sed.

> Elsewhere, I'm 3/4 of the way to convincing myself to just add hd/hexdump as a
> fourth implementation of the same darn thing, because hexedit, xxd, and od
> aren't really set up to share code with each other and neither of them is an
> obvious base for hd either. The perfect is the enemy of the good and all 
> that...
> 
> > I have removed some of the overhead to minimize throughput, Replacing 
> > "run_vi_cmd("j")"
> > with "cur_down(1, 1, 0)" The page clearing function calls with setting 
> > vi_mov_flag, etc.
> 
> 
> The person who ISN'T currently doing work shouldn't stand in the way of 
> somebody
> who's got momentum. You've built some familiarity with the vi codebase and 
> seem
> to be doing good things with it, I have no intention of stopping you, and I've
> applied your patch.

My main goal for vi.c was to put some ex commands I commonly used into it. 
The only non-trivial thing I had left to implement was the 's' command.
And once that is implemented, I don't really have many other things I would 
care to implement in vi.
If the regex line substitution algorithm gets code-shared OR it's not viable to 
code-share 
it in the cleanup pass I'll probably resume work on vi.c to add a 's' command 
if it's not already there.

The reason I started poking at other commands like count is because, now that 
the ex commands in vi have
90% of the things I care about. Perfecting them (Adding special formatting like 
"2,+5" into line ranges, 
Non-global global commands, Prying the ex commands from 'run_vi_cmd()' to 
minimize throughput, etc)
doesn't matter to me as much as adding to/fixing other stuff in toybox.

That being said, and after looking closer at vi.c. There are a few things other 
then ex commands
That I could add. I added backwards searches, with the corresponding 
"N" (goto previous match while searching) (vi normal mode, not ex) command.
The 'j'[oin] ex command is occasionally useful in conjunction with 'g' so I 
added that too.

- Oliver Webb <[email protected]>
From 4cb4b801aab40a93204649c90330ad4a8efa15b9 Mon Sep 17 00:00:00 2001
From: Oliver Webb <[email protected]>
Date: Tue, 17 Oct 2023 17:55:01 -0500
Subject: [PATCH] vi.c: add backwards search, add j(oin) ex command

---
 toys/pending/vi.c | 40 +++++++++++++++++++++++-----------------
 1 file changed, 23 insertions(+), 17 deletions(-)

diff --git a/toys/pending/vi.c b/toys/pending/vi.c
index 6f55466e..2ba6e6a3 100644
--- a/toys/pending/vi.c
+++ b/toys/pending/vi.c
@@ -510,17 +510,20 @@ 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)
+static size_t text_strstr(size_t offset, char *str, int dir)
 {
   size_t bytes, pos = offset;
   char *s = 0;
 
   do {
     bytes = text_getline(toybuf, pos, ARRAY_LEN(toybuf));
-    if (!bytes) pos++; //empty line
+    if (!bytes) pos += (dir ? 1 : -1); //empty line
     else if ((s = strstr(toybuf, str))) return pos+(s-toybuf);
-    else pos += bytes;
-  } while (pos < TT.filesize);
+    else {
+      if (!dir) pos -= bytes;
+      else pos += bytes;
+    }
+  } while (pos < (dir ? 0 : TT.filesize));
 
   return SIZE_MAX;
 }
@@ -839,9 +842,9 @@ static int vi_M(int count0, int count1, char *unused)
   return 1;
 }
 
-static int search_str(char *s)
+static int search_str(char *s, int direction)
 {
-  size_t pos = text_strstr(TT.cursor+1, s);
+  size_t pos = text_strstr(TT.cursor+1, s, direction);
 
   if (TT.last_search != s) {
     free(TT.last_search);
@@ -1197,7 +1200,13 @@ static int vi_join(char reg, int count0, int count1)
 
 static int vi_find_next(char reg, int count0, int count1)
 {
-  if (TT.last_search) search_str(TT.last_search);
+  if (TT.last_search) search_str(TT.last_search, 1);
+  return 1;
+}
+
+static int vi_find_prev(char reg, int count0, int count1)
+{
+  if (TT.last_search) search_str(TT.last_search, 0);
   return 1;
 }
 
@@ -1225,6 +1234,7 @@ struct vi_special_param {
   {"I", &vi_I},
   {"J", &vi_join},
   {"O", &vi_O},
+  {"N", &vi_find_prev},
   {"n", &vi_find_next},
   {"o", &vi_o},
   {"p", &vi_push},
@@ -1346,10 +1356,8 @@ 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.
-  } else if (cmd[0] == ':') {
+  if (*cmd == '/' || *cmd == '\?') search_str(cmd+1, *cmd == '/' ? 0 : 1);
+  else if (*cmd == ':') {
     if (cmd[1] == 'q') {
       if (cmd[2] != '!' && modified())
         show_error("Unsaved changes (\"q!\" to ignore)");
@@ -1371,7 +1379,8 @@ 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] == 'g' || cmd[1] == 'v') {
+    } else if (cmd[1] == 'j') run_vi_cmd("J");
+    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;
@@ -1402,16 +1411,13 @@ gcleanup:
     } else if (cmd[1] == '$') run_vi_cmd("G");
     else if (cmd[1] == '%') {
       endline = get_endline();
-      ofst = startline = 1;
+      ofst = 1;
     } else show_error("unknown command '%s'",cmd+1);
 
     if (ofst) {
-      int cline;
+      int cline = TT.cur_row+1;
 
-      draw_page();
-      cline = TT.cur_row+1;
       cmd[ofst] = ':';
-      run_vi_cmd(xmprintf("%dG", startline));
       for (; startline <= endline; startline++) {
         run_ex_cmd(cmd+ofst);
         cur_down(1, 1, 0);
-- 
2.34.1

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

Reply via email to