Make the ':s/find/replace/g' command behave more like vi:

- the final delimiter is optional if no flag is specified;

- the cursor is moved to the first visible character of the last
  line where a substitution was made;

- a warning is displayed if no substitution was made.

function                                             old     new   delta
colon                                               3156    3212     +56
.rodata                                           105133  105142      +9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 65/0)               Total: 65 bytes

Signed-off-by: Ron Yorston <[email protected]>
---
 editors/vi.c | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/editors/vi.c b/editors/vi.c
index 3ae961feb..38fdd3d61 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -2801,10 +2801,8 @@ static void colon(char *buf)
        } else if (cmd[0] == 's') {     // substitute a pattern with a 
replacement pattern
                char *F, *R, *flags;
                size_t len_F, len_R;
-               int gflag;              // global replace flag
-#  if ENABLE_FEATURE_VI_UNDO
-               int dont_chain_first_item = ALLOW_UNDO;
-#  endif
+               int gflag = 0;          // global replace flag
+               int subs = 0;   // number of substitutions
 
                // F points to the "find" pattern
                // R points to the "replace" pattern
@@ -2817,11 +2815,11 @@ static void colon(char *buf)
                len_F = R - F;
                *R++ = '\0';    // terminate "find"
                flags = strchr(R, c);
-               if (!flags)
-                       goto colon_s_fail;
-               len_R = flags - R;
-               *flags++ = '\0';        // terminate "replace"
-               gflag = *flags;
+               if (flags) {
+                       *flags++ = '\0';        // terminate "replace"
+                       gflag = *flags;
+               }
+               len_R = strlen(R);
 
                q = begin_line(q);
                if (b < 0) {    // maybe :s/foo/bar/
@@ -2840,14 +2838,15 @@ static void colon(char *buf)
                                uintptr_t bias;
                                // we found the "find" pattern - delete it
                                // For undo support, the first item should not 
be chained
-                               text_hole_delete(found, found + len_F - 1, 
dont_chain_first_item);
-#  if ENABLE_FEATURE_VI_UNDO
-                               dont_chain_first_item = ALLOW_UNDO_CHAIN;
-#  endif
+                               text_hole_delete(found, found + len_F - 1,
+                                                       subs ? 
ALLOW_UNDO_CHAIN: ALLOW_UNDO);
+                               // can't do this above, no undo => no third 
argument
+                               subs++;
                                // insert the "replace" patern
                                bias = string_insert(found, R, 
ALLOW_UNDO_CHAIN);
                                found += bias;
                                ls += bias;
+                               dot = ls;
                                //q += bias; - recalculated anyway
                                // check for "global"  :s/foo/bar/g
                                if (gflag == 'g') {
@@ -2859,6 +2858,11 @@ static void colon(char *buf)
                        }
                        q = next_line(ls);
                }
+               if (subs == 0) {
+                       status_line_bold("No match");
+               } else {
+                       dot_skip_over_ws();
+               }
 # endif /* FEATURE_VI_SEARCH */
        } else if (strncmp(cmd, "version", i) == 0) {  // show software version
                status_line(BB_VER);
-- 
2.30.2

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to