From dadd90974639c0b8cb0561eb946746ca2678b5fb Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sun, 25 Apr 2021 11:54:24 +0100 Subject: [PATCH] vi: improvements to ':read' command 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 Signed-off-by: Denys Vlasenko --- 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);