[git commit] vi: make put commands more like vi

Denys Vlasenko vda.linux at googlemail.com
Sat Apr 10 22:18:55 UTC 2021


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

Make the put commands 'p' and 'P' behave more like vi:

- allow a repetition count to be specified;

- when the text being inserted doesn't include a newline the cursor
  should be positioned at the end of the inserted text.

function                                             old     new   delta
do_cmd                                              4765    4842     +77
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 77/0)               Total: 77 bytes

v2: Don't break build when FEATURE_VI_UNDO is disabled.

Signed-off-by: Ron Yorston <rmy at pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 editors/vi.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/editors/vi.c b/editors/vi.c
index 9a2d7b0d9..fd4526dda 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -3429,11 +3429,12 @@ static void do_cmd(int c)
 			break;
 		}
 		// are we putting whole lines or strings
+		cnt = 0;
 		if (regtype[YDreg] == WHOLE) {
 			if (c == 'P') {
 				dot_begin();	// putting lines- Put above
 			}
-			if (c == 'p') {
+			else /* if ( c == 'p') */ {
 				// are we putting after very last line?
 				if (end_line(dot) == (end - 1)) {
 					dot = end;	// force dot to end of text[]
@@ -3444,8 +3445,18 @@ static void do_cmd(int c)
 		} else {
 			if (c == 'p')
 				dot_right();	// move to right, can move to NL
+			// how far to move cursor if register doesn't have a NL
+			if (strchr(p, '\n') == NULL)
+				cnt = (cmdcnt ?: 1) * strlen(p) - 1;
 		}
-		string_insert(dot, p, ALLOW_UNDO);	// insert the string
+		do {
+			// dot is adjusted if text[] is reallocated so we don't have to
+			string_insert(dot, p, allow_undo);	// insert the string
+# if ENABLE_FEATURE_VI_UNDO
+			allow_undo = ALLOW_UNDO_CHAIN;
+# endif
+		} while (--cmdcnt > 0);
+		dot += cnt;
 		end_cmd_q();	// stop adding to q
 		break;
 	case 'U':			// U- Undo; replace current line with original version


More information about the busybox-cvs mailing list