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>
This commit is contained in:
parent
951c6ded3a
commit
6220b4d531
26
editors/vi.c
26
editors/vi.c
@ -2817,10 +2817,8 @@ static void colon(char *buf)
|
|||||||
} else if (cmd[0] == 's') { // substitute a pattern with a replacement pattern
|
} else if (cmd[0] == 's') { // substitute a pattern with a replacement pattern
|
||||||
char *F, *R, *flags;
|
char *F, *R, *flags;
|
||||||
size_t len_F, len_R;
|
size_t len_F, len_R;
|
||||||
int gflag; // global replace flag
|
int gflag = 0; // global replace flag
|
||||||
# if ENABLE_FEATURE_VI_UNDO
|
int subs = 0; // number of substitutions
|
||||||
int dont_chain_first_item = ALLOW_UNDO;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// F points to the "find" pattern
|
// F points to the "find" pattern
|
||||||
// R points to the "replace" pattern
|
// R points to the "replace" pattern
|
||||||
@ -2833,11 +2831,11 @@ static void colon(char *buf)
|
|||||||
len_F = R - F;
|
len_F = R - F;
|
||||||
*R++ = '\0'; // terminate "find"
|
*R++ = '\0'; // terminate "find"
|
||||||
flags = strchr(R, c);
|
flags = strchr(R, c);
|
||||||
if (!flags)
|
if (flags) {
|
||||||
goto colon_s_fail;
|
|
||||||
len_R = flags - R;
|
|
||||||
*flags++ = '\0'; // terminate "replace"
|
*flags++ = '\0'; // terminate "replace"
|
||||||
gflag = *flags;
|
gflag = *flags;
|
||||||
|
}
|
||||||
|
len_R = strlen(R);
|
||||||
|
|
||||||
q = begin_line(q);
|
q = begin_line(q);
|
||||||
if (b < 0) { // maybe :s/foo/bar/
|
if (b < 0) { // maybe :s/foo/bar/
|
||||||
@ -2856,14 +2854,15 @@ static void colon(char *buf)
|
|||||||
uintptr_t bias;
|
uintptr_t bias;
|
||||||
// we found the "find" pattern - delete it
|
// we found the "find" pattern - delete it
|
||||||
// For undo support, the first item should not be chained
|
// For undo support, the first item should not be chained
|
||||||
text_hole_delete(found, found + len_F - 1, dont_chain_first_item);
|
text_hole_delete(found, found + len_F - 1,
|
||||||
# if ENABLE_FEATURE_VI_UNDO
|
subs ? ALLOW_UNDO_CHAIN: ALLOW_UNDO);
|
||||||
dont_chain_first_item = ALLOW_UNDO_CHAIN;
|
// can't do this above, no undo => no third argument
|
||||||
# endif
|
subs++;
|
||||||
// insert the "replace" patern
|
// insert the "replace" patern
|
||||||
bias = string_insert(found, R, ALLOW_UNDO_CHAIN);
|
bias = string_insert(found, R, ALLOW_UNDO_CHAIN);
|
||||||
found += bias;
|
found += bias;
|
||||||
ls += bias;
|
ls += bias;
|
||||||
|
dot = ls;
|
||||||
//q += bias; - recalculated anyway
|
//q += bias; - recalculated anyway
|
||||||
// check for "global" :s/foo/bar/g
|
// check for "global" :s/foo/bar/g
|
||||||
if (gflag == 'g') {
|
if (gflag == 'g') {
|
||||||
@ -2875,6 +2874,11 @@ static void colon(char *buf)
|
|||||||
}
|
}
|
||||||
q = next_line(ls);
|
q = next_line(ls);
|
||||||
}
|
}
|
||||||
|
if (subs == 0) {
|
||||||
|
status_line_bold("No match");
|
||||||
|
} else {
|
||||||
|
dot_skip_over_ws();
|
||||||
|
}
|
||||||
# endif /* FEATURE_VI_SEARCH */
|
# endif /* FEATURE_VI_SEARCH */
|
||||||
} else if (strncmp(cmd, "version", i) == 0) { // show software version
|
} else if (strncmp(cmd, "version", i) == 0) { // show software version
|
||||||
status_line(BB_VER);
|
status_line(BB_VER);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user