[git commit] vi: fix regression in autoindent handling

Denys Vlasenko vda.linux at googlemail.com
Sun Jun 26 17:38:28 UTC 2022


commit: https://git.busybox.net/busybox/commit/?id=af3b585815de5af367995d6064d994394b46c928
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

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<CR>;r<CR>', 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 <rmy at pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 editors/vi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

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


More information about the busybox-cvs mailing list