From af3b585815de5af367995d6064d994394b46c928 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Fri, 18 Mar 2022 11:29:53 +0000 Subject: vi: fix regression in autoindent handling Suppose autoindent is enabled and we have a line with an initial tab where we want to split the words onto separate lines: split the words One way to do this is with the sequence 'f r;r', but in BusyBox vi the result is: split he words This is a regression introduced by commit 9659a8db1 (vi: remove autoindent from otherwise empty lines). The amount of indentation is being recorded when the 'r' command inserts a newline but isn't subsequently reset. A fix is to only record the indent when in insert or replace mode. Proper handling of the 'o' and 'O' commands then requires them to switch to insert mode before calling char_insert() to insert a newline. function old new delta char_insert 884 891 +7 do_cmd 4243 4247 +4 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 11/0) Total: 11 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- editors/vi.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'editors/vi.c') diff --git a/editors/vi.c b/editors/vi.c index 6fa0a4e18..5b86b0516 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -2227,7 +2227,10 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' p--; // open above, indent before newly inserted NL if (len) { - indentcol = col; + // only record indent if in insert/replace mode or for + // the 'o'/'O' commands, which are switched to insert + // mode early. + indentcol = cmd_mode != 0 ? col : 0; if (expandtab) { ntab = 0; nspc = col; @@ -4265,6 +4268,9 @@ static void do_cmd(int c) case 'o': // o- open an empty line below dot_end(); dc3: +#if ENABLE_FEATURE_VI_SETOPTS + cmd_mode = 1; // switch to insert mode early +#endif dot = char_insert(dot, '\n', ALLOW_UNDO); if (c == 'O' && !autoindent) { // done in char_insert() for 'O'+autoindent -- cgit v1.2.1