[git commit] vi: improvements to ':read' command

Denys Vlasenko vda.linux at googlemail.com
Wed Apr 28 09:29:33 UTC 2021


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

Improvements to ':read':

- When a file is read into the current buffer the cursor should be
  placed on the first line read.

- If invoked without supplying a filename the current filename should
  be used.  This is similar to how ':edit' works.

- The code for ':edit' included an explicit check that the current
  filename was non-empty.  Both vim and traditional vi accept non-empty
  filenames, only issuing an error message when an attempt to use such
  a name fails.

- Allow undo of a file read.

function                                             old     new   delta
file_insert                                          367     382     +15
colon                                               3841    3848      +7
.rodata                                           105236  105218     -18
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 22/-18)              Total: 4 bytes

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

diff --git a/editors/vi.c b/editors/vi.c
index 8d9d04a88..dd22eb45b 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -2007,6 +2007,11 @@ static int file_insert(const char *fn, char *p, int initial)
 		p = text_hole_delete(p + cnt, p + size - 1, NO_UNDO);
 		status_line_bold("can't read '%s'", fn);
 	}
+# if ENABLE_FEATURE_VI_UNDO
+	else {
+		undo_push_insert(p, size, ALLOW_UNDO);
+	}
+# endif
  fi:
 	close(fd);
 
@@ -2743,10 +2748,7 @@ static void colon(char *buf)
 		if (args[0]) {
 			// the user supplied a file name
 			fn = args;
-		} else if (current_filename && current_filename[0]) {
-			// no user supplied name- use the current filename
-			// fn = current_filename;  was set by default
-		} else {
+		} else if (current_filename == NULL) {
 			// no user file name, no current name- punt
 			status_line_bold("No current filename");
 			goto ret;
@@ -2864,11 +2866,14 @@ static void colon(char *buf)
 		}
 		editing = 0;
 	} else if (strncmp(cmd, "read", i) == 0) {	// read file into text[]
-		int size;
+		int size, num;
 
-		fn = args;
-		if (!fn[0]) {
-			status_line_bold("No filename given");
+		if (args[0]) {
+			// the user supplied a file name
+			fn = args;
+		} else if (current_filename == NULL) {
+			// no user file name, no current name- punt
+			status_line_bold("No current filename");
 			goto ret;
 		}
 		if (e < 0) {	// no addr given- read after current line
@@ -2881,6 +2886,9 @@ static void colon(char *buf)
 			if (q == end-1)
 				++q;
 		}
+		num = count_lines(text, q);
+		if (q == end)
+			num++;
 		{ // dance around potentially-reallocated text[]
 			uintptr_t ofs = q - text;
 			size = file_insert(fn, q, 0);
@@ -2897,11 +2905,7 @@ static void colon(char *buf)
 			IF_FEATURE_VI_READONLY((readonly_mode ? " [Readonly]" : ""),)
 			li, size
 		);
-		if (size > 0) {
-			// if the insert is before "dot" then we need to update
-			if (q <= dot)
-				dot += size;
-		}
+		dot = find_line(num);
 	} else if (strncmp(cmd, "rewind", i) == 0) {	// rewind cmd line args
 		if (modified_count && !useforce) {
 			status_line_bold("No write since last change (:%s! overrides)", cmd);


More information about the busybox-cvs mailing list