diff options
author | Ron Yorston <rmy@pobox.com> | 2021-04-06 13:43:32 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-04-11 00:18:55 +0200 |
commit | 6220b4d531a64825eb9698e98afa6be2d92abd8d (patch) | |
tree | fb19140dd2a7ae9e83eba4ca9e37fc2b81a29527 | |
parent | 951c6ded3aa7f0dc414306e27aed8b2785965857 (diff) | |
download | busybox-w32-6220b4d531a64825eb9698e98afa6be2d92abd8d.tar.gz busybox-w32-6220b4d531a64825eb9698e98afa6be2d92abd8d.tar.bz2 busybox-w32-6220b4d531a64825eb9698e98afa6be2d92abd8d.zip |
vi: make the substitute command more like vi
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 <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | editors/vi.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/editors/vi.c b/editors/vi.c index fd4526dda..4fda6aebf 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -2817,10 +2817,8 @@ static void colon(char *buf) | |||
2817 | } else if (cmd[0] == 's') { // substitute a pattern with a replacement pattern | 2817 | } else if (cmd[0] == 's') { // substitute a pattern with a replacement pattern |
2818 | char *F, *R, *flags; | 2818 | char *F, *R, *flags; |
2819 | size_t len_F, len_R; | 2819 | size_t len_F, len_R; |
2820 | int gflag; // global replace flag | 2820 | int gflag = 0; // global replace flag |
2821 | # if ENABLE_FEATURE_VI_UNDO | 2821 | int subs = 0; // number of substitutions |
2822 | int dont_chain_first_item = ALLOW_UNDO; | ||
2823 | # endif | ||
2824 | 2822 | ||
2825 | // F points to the "find" pattern | 2823 | // F points to the "find" pattern |
2826 | // R points to the "replace" pattern | 2824 | // R points to the "replace" pattern |
@@ -2833,11 +2831,11 @@ static void colon(char *buf) | |||
2833 | len_F = R - F; | 2831 | len_F = R - F; |
2834 | *R++ = '\0'; // terminate "find" | 2832 | *R++ = '\0'; // terminate "find" |
2835 | flags = strchr(R, c); | 2833 | flags = strchr(R, c); |
2836 | if (!flags) | 2834 | if (flags) { |
2837 | goto colon_s_fail; | 2835 | *flags++ = '\0'; // terminate "replace" |
2838 | len_R = flags - R; | 2836 | gflag = *flags; |
2839 | *flags++ = '\0'; // terminate "replace" | 2837 | } |
2840 | gflag = *flags; | 2838 | len_R = strlen(R); |
2841 | 2839 | ||
2842 | q = begin_line(q); | 2840 | q = begin_line(q); |
2843 | if (b < 0) { // maybe :s/foo/bar/ | 2841 | if (b < 0) { // maybe :s/foo/bar/ |
@@ -2856,14 +2854,15 @@ static void colon(char *buf) | |||
2856 | uintptr_t bias; | 2854 | uintptr_t bias; |
2857 | // we found the "find" pattern - delete it | 2855 | // we found the "find" pattern - delete it |
2858 | // For undo support, the first item should not be chained | 2856 | // For undo support, the first item should not be chained |
2859 | text_hole_delete(found, found + len_F - 1, dont_chain_first_item); | 2857 | text_hole_delete(found, found + len_F - 1, |
2860 | # if ENABLE_FEATURE_VI_UNDO | 2858 | subs ? ALLOW_UNDO_CHAIN: ALLOW_UNDO); |
2861 | dont_chain_first_item = ALLOW_UNDO_CHAIN; | 2859 | // can't do this above, no undo => no third argument |
2862 | # endif | 2860 | subs++; |
2863 | // insert the "replace" patern | 2861 | // insert the "replace" patern |
2864 | bias = string_insert(found, R, ALLOW_UNDO_CHAIN); | 2862 | bias = string_insert(found, R, ALLOW_UNDO_CHAIN); |
2865 | found += bias; | 2863 | found += bias; |
2866 | ls += bias; | 2864 | ls += bias; |
2865 | dot = ls; | ||
2867 | //q += bias; - recalculated anyway | 2866 | //q += bias; - recalculated anyway |
2868 | // check for "global" :s/foo/bar/g | 2867 | // check for "global" :s/foo/bar/g |
2869 | if (gflag == 'g') { | 2868 | if (gflag == 'g') { |
@@ -2875,6 +2874,11 @@ static void colon(char *buf) | |||
2875 | } | 2874 | } |
2876 | q = next_line(ls); | 2875 | q = next_line(ls); |
2877 | } | 2876 | } |
2877 | if (subs == 0) { | ||
2878 | status_line_bold("No match"); | ||
2879 | } else { | ||
2880 | dot_skip_over_ws(); | ||
2881 | } | ||
2878 | # endif /* FEATURE_VI_SEARCH */ | 2882 | # endif /* FEATURE_VI_SEARCH */ |
2879 | } else if (strncmp(cmd, "version", i) == 0) { // show software version | 2883 | } else if (strncmp(cmd, "version", i) == 0) { // show software version |
2880 | status_line(BB_VER); | 2884 | status_line(BB_VER); |