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 <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Ron Yorston 2021-04-25 11:54:24 +01:00 committed by Denys Vlasenko
parent e6bc8a29a9
commit dadd909746

View File

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