aboutsummaryrefslogtreecommitdiff
path: root/src/nvim
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim')
-rw-r--r--src/nvim/api/buffer.c8
-rw-r--r--src/nvim/ex_cmds.c8
-rw-r--r--src/nvim/fileio.c24
-rw-r--r--src/nvim/testdir/check.vim24
-rw-r--r--src/nvim/testdir/test_edit.vim27
-rw-r--r--src/nvim/testdir/test_undo.vim39
-rw-r--r--src/nvim/undo.c7
7 files changed, 124 insertions, 13 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 174f6e94a9..2811a2da12 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -1531,10 +1531,10 @@ Integer nvim_buf_add_highlight(Buffer buffer,
end_line++;
}
- ns_id = extmark_set(buf, ns_id, 0,
- (int)line, (colnr_T)col_start,
- end_line, (colnr_T)col_end,
- decoration_hl(hl_id), kExtmarkNoUndo);
+ extmark_set(buf, ns_id, 0,
+ (int)line, (colnr_T)col_start,
+ end_line, (colnr_T)col_end,
+ decoration_hl(hl_id), kExtmarkNoUndo);
return src_id;
}
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 9be6adcd61..bb4e92efc0 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -2497,8 +2497,12 @@ int do_ecmd(
new_name = NULL;
}
set_bufref(&bufref, buf);
- if (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur) {
- // Save all the text, so that the reload can be undone.
+
+ // If the buffer was used before, store the current contents so that
+ // the reload can be undone. Do not do this if the (empty) buffer is
+ // being re-used for another file.
+ if (!(curbuf->b_flags & BF_NEVERLOADED)
+ && (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur)) {
// Sync first so that this is a separate undo-able action.
u_sync(false);
if (u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, true)
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index ed8b72e2be..521d5c9deb 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -350,6 +350,7 @@ readfile(
char_u *old_b_fname;
int using_b_ffname;
int using_b_fname;
+ static char *msg_is_a_directory = N_("is a directory");
au_did_filetype = false; // reset before triggering any autocommands
@@ -444,16 +445,27 @@ readfile(
else
msg_scroll = TRUE; /* don't overwrite previous file message */
- /*
- * If the name is too long we might crash further on, quit here.
- */
+ // If the name is too long we might crash further on, quit here.
if (fname != NULL && *fname != NUL) {
- if (STRLEN(fname) >= MAXPATHL) {
+ size_t namelen = STRLEN(fname);
+
+ // If the name is too long we might crash further on, quit here.
+ if (namelen >= MAXPATHL) {
filemess(curbuf, fname, (char_u *)_("Illegal file name"), 0);
msg_end();
msg_scroll = msg_save;
return FAIL;
}
+
+ // If the name ends in a path separator, we can't open it. Check here,
+ // because reading the file may actually work, but then creating the
+ // swap file may destroy it! Reported on MS-DOS and Win 95.
+ if (after_pathsep((const char *)fname, (const char *)(fname + namelen))) {
+ filemess(curbuf, fname, (char_u *)_(msg_is_a_directory), 0);
+ msg_end();
+ msg_scroll = msg_save;
+ return FAIL;
+ }
}
if (!read_buffer && !read_stdin && !read_fifo) {
@@ -474,7 +486,7 @@ readfile(
# endif
) {
if (S_ISDIR(perm)) {
- filemess(curbuf, fname, (char_u *)_("is a directory"), 0);
+ filemess(curbuf, fname, (char_u *)_(msg_is_a_directory), 0);
} else {
filemess(curbuf, fname, (char_u *)_("is not a file"), 0);
}
@@ -544,7 +556,7 @@ readfile(
#ifndef UNIX
// On non-unix systems we can't open a directory, check here.
if (os_isdir(fname)) {
- filemess(curbuf, sfname, (char_u *)_("is a directory"), 0);
+ filemess(curbuf, sfname, (char_u *)_(msg_is_a_directory), 0);
curbuf->b_p_ro = true; // must use "w!" now
} else {
#endif
diff --git a/src/nvim/testdir/check.vim b/src/nvim/testdir/check.vim
index e0ebe8fd49..7f6b7dcfec 100644
--- a/src/nvim/testdir/check.vim
+++ b/src/nvim/testdir/check.vim
@@ -25,6 +25,14 @@ func CheckFunction(name)
endif
endfunc
+" Command to check for the presence of python. Argument should have been
+" obtained with PythonProg()
+func CheckPython(name)
+ if a:name == ''
+ throw 'Skipped: python command not available'
+ endif
+endfunc
+
" Command to check for running on MS-Windows
command CheckMSWindows call CheckMSWindows()
func CheckMSWindows()
@@ -73,3 +81,19 @@ func CheckNotGui()
throw 'Skipped: only works in the terminal'
endif
endfunc
+
+" Command to check that the current language is English
+command CheckEnglish call CheckEnglish()
+func CheckEnglish()
+ if v:lang != "C" && v:lang !~ '^[Ee]n'
+ throw 'Skipped: only works in English language environment'
+ endif
+endfunc
+
+" Command to check for NOT running on MS-Windows
+command CheckNotMSWindows call CheckNotMSWindows()
+func CheckNotMSWindows()
+ if has('win32')
+ throw 'Skipped: does not work on MS-Windows'
+ endif
+endfunc
diff --git a/src/nvim/testdir/test_edit.vim b/src/nvim/testdir/test_edit.vim
index 7f456ffbce..97a8ad25a3 100644
--- a/src/nvim/testdir/test_edit.vim
+++ b/src/nvim/testdir/test_edit.vim
@@ -1534,3 +1534,30 @@ func Test_edit_noesckeys()
bwipe!
" set esckeys
endfunc
+
+" Test for editing a directory
+" Todo: "is a directory" message is not displayed in Windows.
+func Test_edit_is_a_directory()
+ CheckEnglish
+ CheckNotMSWindows
+ let dirname = getcwd() . "/Xdir"
+ call mkdir(dirname, 'p')
+
+ new
+ redir => msg
+ exe 'edit' dirname
+ redir END
+ call assert_match("is a directory$", split(msg, "\n")[0])
+ bwipe!
+
+ let dirname .= '/'
+
+ new
+ redir => msg
+ exe 'edit' dirname
+ redir END
+ call assert_match("is a directory$", split(msg, "\n")[0])
+ bwipe!
+
+ call delete(dirname, 'rf')
+endfunc
diff --git a/src/nvim/testdir/test_undo.vim b/src/nvim/testdir/test_undo.vim
index adcdcb1cd9..3b66071d6d 100644
--- a/src/nvim/testdir/test_undo.vim
+++ b/src/nvim/testdir/test_undo.vim
@@ -364,6 +364,25 @@ func Test_wundo_errors()
bwipe!
endfunc
+" Check that reading a truncted undo file doesn't hang.
+func Test_undofile_truncated()
+ throw 'skipped: TODO: '
+ new
+ call setline(1, 'hello')
+ set ul=100
+ wundo Xundofile
+ let contents = readfile('Xundofile', 'B')
+
+ " try several sizes
+ for size in range(20, 500, 33)
+ call writefile(contents[0:size], 'Xundofile')
+ call assert_fails('rundo Xundofile', 'E825:')
+ endfor
+
+ bwipe!
+ call delete('Xundofile')
+endfunc
+
func Test_rundo_errors()
call assert_fails('rundo XfileDoesNotExist', 'E822:')
@@ -373,6 +392,26 @@ func Test_rundo_errors()
call delete('Xundofile')
endfunc
+func Test_undofile_next()
+ set undofile
+ new Xfoo.txt
+ execute "norm ix\<c-g>uy\<c-g>uz\<Esc>"
+ write
+ bwipe
+
+ next Xfoo.txt
+ call assert_equal('xyz', getline(1))
+ silent undo
+ call assert_equal('xy', getline(1))
+ silent undo
+ call assert_equal('x', getline(1))
+ bwipe!
+
+ call delete('Xfoo.txt')
+ call delete('.Xfoo.txt.un~')
+ set undofile&
+endfunc
+
" Test for undo working properly when executing commands from a register.
" Also test this in an empty buffer.
func Test_cmd_in_reg_undo()
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index 903e57732f..6c5a6cdb46 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -878,7 +878,12 @@ static u_header_T *unserialize_uhp(bufinfo_T *bi,
for (;; ) {
int len = undo_read_byte(bi);
- if (len == 0 || len == EOF) {
+ if (len == EOF) {
+ corruption_error("truncated", file_name);
+ u_free_uhp(uhp);
+ return NULL;
+ }
+ if (len == 0) {
break;
}
int what = undo_read_byte(bi);