aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/eval.txt2
-rwxr-xr-xscripts/vim-patch.sh16
-rw-r--r--src/nvim/eval.c2
-rw-r--r--src/nvim/fileio.c2
-rw-r--r--src/nvim/globals.h1
-rw-r--r--src/nvim/testdir/test_debugger.vim116
-rw-r--r--src/nvim/testdir/test_eval_stuff.vim9
-rw-r--r--src/nvim/testdir/test_startup.vim122
-rw-r--r--src/nvim/testdir/test_suspend.vim6
-rw-r--r--src/nvim/testdir/test_writefile.vim7
10 files changed, 254 insertions, 29 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 00194b4613..4dc63763ab 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -8958,7 +8958,7 @@ winwidth({nr}) *winwidth()*
Examples: >
:echo "The current window has " . winwidth(0) . " columns."
:if winwidth(0) <= 50
- : exe "normal 50\<C-W>|"
+ : 50 wincmd |
:endif
< For getting the terminal or screen size, see the 'columns'
option.
diff --git a/scripts/vim-patch.sh b/scripts/vim-patch.sh
index a9e9c5d6c3..d16266dd36 100755
--- a/scripts/vim-patch.sh
+++ b/scripts/vim-patch.sh
@@ -41,7 +41,7 @@ msg_ok() {
}
msg_err() {
- printf '\e[31m✘\e[0m %s\n' "$@"
+ printf '\e[31m✘\e[0m %s\n' "$@" >&2
}
# Checks if a program is in the user's PATH, and is executable.
@@ -393,10 +393,15 @@ list_missing_vimpatches() {
# Create an associative array mapping Vim commits to tags.
eval "declare -A vim_commit_tags=(
$(git -C "${VIM_SOURCE_DIR}" for-each-ref refs/tags \
- --format '[%(objectname)]=%(refname:lstrip=2)' \
+ --format '[%(objectname)]=%(refname:strip=2)' \
--sort='-*authordate' \
--shell)
)"
+ # Exit in case of errors from the above eval (empty vim_commit_tags).
+ if ! (( "${#vim_commit_tags[@]}" )); then
+ msg_err "Could not get Vim commits/tags."
+ exit 1
+ fi
# Get missing Vim commits
for vim_commit in $(list_vim_commits); do
@@ -425,8 +430,13 @@ show_vimpatches() {
get_vim_sources
printf "\nVim patches missing from Neovim:\n"
+ local -A runtime_commits
+ for commit in $(git -C "${VIM_SOURCE_DIR}" log --format="%H %D" -- runtime | sed 's/,\? tag: / /g'); do
+ runtime_commits[$commit]=1
+ done
+
list_missing_vimpatches | while read -r vim_commit; do
- if [ -n "$(git -C "$VIM_SOURCE_DIR" diff-tree --no-commit-id --name-only "${vim_commit}" -- runtime)" ]; then
+ if [[ "${runtime_commits[$vim_commit]-}" ]]; then
printf ' • %s (+runtime)\n' "${vim_commit}"
else
printf ' • %s\n' "${vim_commit}"
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 5c77b9ddfc..54c469fabf 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -4284,7 +4284,7 @@ static int eval7(
// Stop the expression evaluation when immediately
// aborting on error, or when an interrupt occurred or
// an exception was thrown but not caught.
- if (aborting()) {
+ if (evaluate && aborting()) {
if (ret == OK) {
tv_clear(rettv);
}
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index e2b77d9605..f2a664288b 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -3363,7 +3363,7 @@ restore_backup:
if (p_fs && (error = os_fsync(fd)) != 0 && !device
// fsync not supported on this storage.
&& error != UV_ENOTSUP) {
- SET_ERRMSG_ARG(_("E667: Fsync failed: %s"), error);
+ SET_ERRMSG_ARG(e_fsync, error);
end = 0;
}
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 78409267a4..40184a4bb9 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -958,6 +958,7 @@ EXTERN char_u e_streamkey[] INIT(= N_(
"E5210: dict key '%s' already set for buffered stream in channel %"
PRIu64));
EXTERN char_u e_libcall[] INIT(= N_("E364: Library call failed for \"%s()\""));
+EXTERN char e_fsync[] INIT(= N_("E667: Fsync failed: %s"));
EXTERN char_u e_mkdir[] INIT(= N_("E739: Cannot create directory %s: %s"));
EXTERN char_u e_markinval[] INIT(= N_("E19: Mark has invalid line number"));
EXTERN char_u e_marknotset[] INIT(= N_("E20: Mark not set"));
diff --git a/src/nvim/testdir/test_debugger.vim b/src/nvim/testdir/test_debugger.vim
index db18f7695d..c923b22836 100644
--- a/src/nvim/testdir/test_debugger.vim
+++ b/src/nvim/testdir/test_debugger.vim
@@ -38,10 +38,13 @@ func Test_Debugger()
\ ' return var2',
\ 'endfunc',
\ 'func Bazz(var)',
- \ ' let var1 = 3 + a:var',
- \ ' let var3 = "another var"',
- \ ' let var3 = "value2"',
- \ ' let var3 = "value3"',
+ \ ' try',
+ \ ' let var1 = 3 + a:var',
+ \ ' let var3 = "another var"',
+ \ ' let var3 = "value2"',
+ \ ' catch',
+ \ ' let var4 = "exception"',
+ \ ' endtry',
\ ' return var1',
\ 'endfunc'], 'Xtest.vim')
@@ -58,13 +61,14 @@ func Test_Debugger()
call RunDbgCmd(buf, 'step')
call RunDbgCmd(buf, 'step')
call RunDbgCmd(buf, 'step')
+ call RunDbgCmd(buf, 'step')
" check backtrace
call RunDbgCmd(buf, 'backtrace', [
\ ' 2 function Foo[2]',
\ ' 1 Bar[2]',
\ '->0 Bazz',
- \ 'line 2: let var3 = "another var"'])
+ \ 'line 3: let var3 = "another var"'])
" Check variables in different stack frames
call RunDbgCmd(buf, 'echo var1', ['6'])
@@ -74,7 +78,7 @@ func Test_Debugger()
\ ' 2 function Foo[2]',
\ '->1 Bar[2]',
\ ' 0 Bazz',
- \ 'line 2: let var3 = "another var"'])
+ \ 'line 3: let var3 = "another var"'])
call RunDbgCmd(buf, 'echo var1', ['3'])
call RunDbgCmd(buf, 'u')
@@ -82,7 +86,7 @@ func Test_Debugger()
\ '->2 function Foo[2]',
\ ' 1 Bar[2]',
\ ' 0 Bazz',
- \ 'line 2: let var3 = "another var"'])
+ \ 'line 3: let var3 = "another var"'])
call RunDbgCmd(buf, 'echo var1', ['1'])
" Undefined variables
@@ -90,7 +94,7 @@ func Test_Debugger()
call RunDbgCmd(buf, 'frame 2')
call RunDbgCmd(buf, 'echo var3', [
\ 'Error detected while processing function Foo[2]..Bar[2]..Bazz:',
- \ 'line 3:',
+ \ 'line 4:',
\ 'E121: Undefined variable: var3'])
" var3 is defined in this level with some other value
@@ -98,9 +102,10 @@ func Test_Debugger()
call RunDbgCmd(buf, 'echo var3', ['another var'])
call RunDbgCmd(buf, 'step')
- call RunDbgCmd(buf, 'step')
- call RunDbgCmd(buf, 'step')
- call RunDbgCmd(buf, 'step')
+ call RunDbgCmd(buf, '')
+ call RunDbgCmd(buf, '')
+ call RunDbgCmd(buf, '')
+ call RunDbgCmd(buf, '')
call RunDbgCmd(buf, 'step', [
\ 'function Foo[2]..Bar',
\ 'line 3: End of function'])
@@ -189,7 +194,7 @@ func Test_Debugger()
call RunDbgCmd(buf, 'cont', [
\ 'Breakpoint in "Bazz" line 3',
\ 'function Foo[2]..Bar[2]..Bazz',
- \ 'line 3: let var3 = "value2"'])
+ \ 'line 3: let var3 = "another var"'])
" Delete the breakpoints
call RunDbgCmd(buf, 'breakd 1')
@@ -207,23 +212,100 @@ func Test_Debugger()
" Expression breakpoint
call RunDbgCmd(buf, ':breakadd func 2 Bazz')
- call RunDbgCmd(buf, ':echo Bazz(1)')
+ call RunDbgCmd(buf, ':echo Bazz(1)', [
+ \ 'Entering Debug mode. Type "cont" to continue.',
+ \ 'function Bazz',
+ \ 'line 2: let var1 = 3 + a:var'])
+ call RunDbgCmd(buf, 'step')
call RunDbgCmd(buf, 'step')
call RunDbgCmd(buf, 'breaka expr var3')
- call RunDbgCmd(buf, 'breakl', [' 4 expr var3'])
- call RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 4',
+ call RunDbgCmd(buf, 'breakl', [' 3 func Bazz line 2',
+ \ ' 4 expr var3'])
+ call RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 5',
\ 'Oldval = "''another var''"',
\ 'Newval = "''value2''"',
\ 'function Bazz',
- \ 'line 4: let var3 = "value3"'])
+ \ 'line 5: catch'])
call RunDbgCmd(buf, 'breakdel *')
call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
+ " Check for error cases
+ call RunDbgCmd(buf, 'breakadd abcd', [
+ \ 'Error detected while processing function Bazz:',
+ \ 'line 5:',
+ \ 'E475: Invalid argument: abcd'])
+ call RunDbgCmd(buf, 'breakadd func', ['E475: Invalid argument: func'])
+ call RunDbgCmd(buf, 'breakadd func 2', ['E475: Invalid argument: func 2'])
+ call RunDbgCmd(buf, 'breaka func a()', ['E475: Invalid argument: func a()'])
+ call RunDbgCmd(buf, 'breakd abcd', ['E475: Invalid argument: abcd'])
+ call RunDbgCmd(buf, 'breakd func', ['E475: Invalid argument: func'])
+ call RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()'])
+ call RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a'])
+ call RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr'])
+ call RunDbgCmd(buf, 'breakd expr x', [
+ \ 'E121: Undefined variable: x',
+ \ 'E161: Breakpoint not found: expr x'])
+
" finish the current function
call RunDbgCmd(buf, 'finish', [
\ 'function Bazz',
- \ 'line 5: End of function'])
+ \ 'line 8: End of function'])
+ call RunDbgCmd(buf, 'cont')
+
+ " Test for :next
+ call RunDbgCmd(buf, ':debug echo Bar(1)')
+ call RunDbgCmd(buf, 'step')
+ call RunDbgCmd(buf, 'next')
+ call RunDbgCmd(buf, '', [
+ \ 'function Bar',
+ \ 'line 3: return var2'])
+ call RunDbgCmd(buf, 'c')
+
+ " Test for :interrupt
+ call RunDbgCmd(buf, ':debug echo Bazz(1)')
+ call RunDbgCmd(buf, 'step')
+ call RunDbgCmd(buf, 'step')
+ call RunDbgCmd(buf, 'interrupt', [
+ \ 'Exception thrown: Vim:Interrupt',
+ \ 'function Bazz',
+ \ 'line 5: catch'])
+ call RunDbgCmd(buf, 'c')
+
+ " Test for :quit
+ call RunDbgCmd(buf, ':debug echo Foo()')
+ call RunDbgCmd(buf, 'breakdel *')
+ call RunDbgCmd(buf, 'breakadd func 3 Foo')
+ call RunDbgCmd(buf, 'breakadd func 3 Bazz')
+ call RunDbgCmd(buf, 'cont', [
+ \ 'Breakpoint in "Bazz" line 3',
+ \ 'function Foo[2]..Bar[2]..Bazz',
+ \ 'line 3: let var3 = "another var"'])
+ call RunDbgCmd(buf, 'quit', [
+ \ 'Breakpoint in "Foo" line 3',
+ \ 'function Foo',
+ \ 'line 3: return var2'])
+ call RunDbgCmd(buf, 'breakdel *')
+ call RunDbgCmd(buf, 'quit')
+ call RunDbgCmd(buf, 'enew! | only!')
+
+ call StopVimInTerminal(buf)
+
+ " Tests for :breakadd file and :breakadd here
+ " Breakpoints should be set before sourcing the file
+
+ call writefile([
+ \ 'let var1 = 10',
+ \ 'let var2 = 20',
+ \ 'let var3 = 30',
+ \ 'let var4 = 40'], 'Xtest.vim')
+
+ " Start Vim in a terminal
+ let buf = RunVimInTerminal('Xtest.vim', {})
+ call RunDbgCmd(buf, ':breakadd file 2 Xtest.vim')
+ call RunDbgCmd(buf, ':4 | breakadd here')
+ call RunDbgCmd(buf, ':source Xtest.vim', ['line 2: let var2 = 20'])
+ call RunDbgCmd(buf, 'cont', ['line 4: let var4 = 40'])
call RunDbgCmd(buf, 'cont')
call StopVimInTerminal(buf)
diff --git a/src/nvim/testdir/test_eval_stuff.vim b/src/nvim/testdir/test_eval_stuff.vim
index ff8f2e5fc7..4b54a0d39f 100644
--- a/src/nvim/testdir/test_eval_stuff.vim
+++ b/src/nvim/testdir/test_eval_stuff.vim
@@ -99,3 +99,12 @@ func Test_let_errmsg()
call assert_fails('let v:errmsg = []', 'E730:')
let v:errmsg = ''
endfunc
+
+" Test fix for issue #4507
+func Test_skip_after_throw()
+ try
+ throw 'something'
+ let x = wincol() || &ts
+ catch /something/
+ endtry
+endfunc
diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim
index 3bc9eaf756..873f2e8731 100644
--- a/src/nvim/testdir/test_startup.vim
+++ b/src/nvim/testdir/test_startup.vim
@@ -196,12 +196,12 @@ func Test_o_arg()
" Open 2 windows split vertically. Expect:
" - 2 windows
" - both windows should have the same or almost the same width
- " - sum of both windows width (+ 1 separator) should be equal to the
- " number of columns
+ " - sum of both windows width (+ 1 for the separator) should be equal to
+ " the number of columns
" - both windows should have the same height
" - window height (+ 2 for the statusline and Ex command) should be equal
" to the number of lines
- " - buffer of both windowns should have no name
+ " - buffer of both windows should have no name
let [wn, wh1, wh2, ln, ww1, ww2, cn, bn1, bn2] = readfile('Xtestout')
call assert_equal('2', wn)
call assert_inrange(0, 1, ww1 - ww2)
@@ -227,6 +227,118 @@ func Test_o_arg()
call delete('Xtestout')
endfunc
+" Test the -p[N] argument to open N tabpages.
+func Test_p_arg()
+ let after = [
+ \ 'call writefile(split(execute("tabs"), "\n"), "Xtestout")',
+ \ 'qall',
+ \ ]
+ if RunVim([], after, '-p2')
+ let lines = readfile('Xtestout')
+ call assert_equal(4, len(lines))
+ call assert_equal('Tab page 1', lines[0])
+ call assert_equal('> [No Name]', lines[1])
+ call assert_equal('Tab page 2', lines[2])
+ call assert_equal(' [No Name]', lines[3])
+ endif
+
+ if RunVim([], after, '-p foo bar')
+ let lines = readfile('Xtestout')
+ call assert_equal(4, len(lines))
+ call assert_equal('Tab page 1', lines[0])
+ call assert_equal('> foo', lines[1])
+ call assert_equal('Tab page 2', lines[2])
+ call assert_equal(' bar', lines[3])
+ endif
+
+ call delete('Xtestout')
+endfunc
+
+" Test the -V[N] argument to set the 'verbose' option to [N]
+func Test_V_arg()
+ if has('gui_running')
+ " Can't catch the output of gvim.
+ return
+ endif
+ let out = system(GetVimCommand() . ' --clean -es -X -V0 -c "set verbose?" -cq')
+ call assert_equal(" verbose=0\n", out)
+
+ let out = system(GetVimCommand() . ' --clean -es -X -V2 -c "set verbose?" -cq')
+ " call assert_match("sourcing \"$VIMRUNTIME[\\/]defaults\.vim\"\r\nSearching for \"filetype\.vim\".*\n", out)
+ call assert_match(" verbose=2\n", out)
+
+ let out = system(GetVimCommand() . ' --clean -es -X -V15 -c "set verbose?" -cq')
+ " call assert_match("sourcing \"$VIMRUNTIME[\\/]defaults\.vim\"\r\nline 1: \" The default vimrc file\..* verbose=15\n", out)
+endfunc
+
+" Test the -V[N]{filename} argument to set the 'verbose' option to N
+" and set 'verbosefile' to filename.
+func Test_V_file_arg()
+ if RunVim([], [], ' --clean -V2Xverbosefile -c "set verbose? verbosefile?" -cq')
+ let out = join(readfile('Xverbosefile'), "\n")
+ " call assert_match("sourcing \"$VIMRUNTIME[\\/]defaults\.vim\"\n", out)
+ call assert_match("\n verbose=2\n", out)
+ call assert_match("\n verbosefile=Xverbosefile", out)
+ endif
+
+ call delete('Xverbosefile')
+endfunc
+
+" Test the -m, -M and -R arguments:
+" -m resets 'write'
+" -M resets 'modifiable' and 'write'
+" -R sets 'readonly'
+func Test_m_M_R()
+ let after = [
+ \ 'call writefile([&write, &modifiable, &readonly, &updatecount], "Xtestout")',
+ \ 'qall',
+ \ ]
+ if RunVim([], after, '')
+ let lines = readfile('Xtestout')
+ call assert_equal(['1', '1', '0', '200'], lines)
+ endif
+ if RunVim([], after, '-m')
+ let lines = readfile('Xtestout')
+ call assert_equal(['0', '1', '0', '200'], lines)
+ endif
+ if RunVim([], after, '-M')
+ let lines = readfile('Xtestout')
+ call assert_equal(['0', '0', '0', '200'], lines)
+ endif
+ if RunVim([], after, '-R')
+ let lines = readfile('Xtestout')
+ call assert_equal(['1', '1', '1', '10000'], lines)
+ endif
+
+ call delete('Xtestout')
+endfunc
+
+" Test the -A, -F and -H arguments (Arabic, Farsi and Hebrew modes).
+func Test_A_F_H_arg()
+ let after = [
+ \ 'call writefile([&rightleft, &arabic, 0, &hkmap], "Xtestout")',
+ \ 'qall',
+ \ ]
+ " Use silent Ex mode to avoid the hit-Enter prompt for the warning that
+ " 'encoding' is not utf-8.
+ if has('arabic') && &encoding == 'utf-8' && RunVim([], after, '-e -s -A')
+ let lines = readfile('Xtestout')
+ call assert_equal(['1', '1', '0', '0'], lines)
+ endif
+
+ if has('farsi') && RunVim([], after, '-F')
+ let lines = readfile('Xtestout')
+ call assert_equal(['1', '0', '1', '0'], lines)
+ endif
+
+ if has('rightleft') && RunVim([], after, '-H')
+ let lines = readfile('Xtestout')
+ call assert_equal(['1', '0', '0', '1'], lines)
+ endif
+
+ call delete('Xtestout')
+endfunc
+
func Test_file_args()
let after = [
\ 'call writefile(argv(), "Xtestout")',
@@ -347,7 +459,7 @@ func Test_zzz_startinsert()
call writefile(['123456'], 'Xtestout')
let after = [
\ ':startinsert',
- \ 'call feedkeys("foobar\<c-o>:wq\<cr>","t")'
+ \ 'call feedkeys("foobar\<c-o>:wq\<cr>","t")'
\ ]
if RunVim([], after, 'Xtestout')
let lines = readfile('Xtestout')
@@ -357,7 +469,7 @@ func Test_zzz_startinsert()
call writefile(['123456'], 'Xtestout')
let after = [
\ ':startinsert!',
- \ 'call feedkeys("foobar\<c-o>:wq\<cr>","t")'
+ \ 'call feedkeys("foobar\<c-o>:wq\<cr>","t")'
\ ]
if RunVim([], after, 'Xtestout')
let lines = readfile('Xtestout')
diff --git a/src/nvim/testdir/test_suspend.vim b/src/nvim/testdir/test_suspend.vim
index a9964b0400..e569e49055 100644
--- a/src/nvim/testdir/test_suspend.vim
+++ b/src/nvim/testdir/test_suspend.vim
@@ -45,7 +45,11 @@ func Test_suspend()
call term_sendkeys(buf, "fg\<CR>")
call WaitForAssert({-> assert_equal(' 1 foo', term_getline(buf, '.'))})
+ " Quit gracefully to dump coverage information.
+ call term_sendkeys(buf, ":qall!\<CR>")
+ call term_wait(buf)
+ call Stop_shell_in_terminal(buf)
+
exe buf . 'bwipe!'
call delete('Xfoo')
- set autowrite&
endfunc
diff --git a/src/nvim/testdir/test_writefile.vim b/src/nvim/testdir/test_writefile.vim
index 9c9e051bc9..9da9df2150 100644
--- a/src/nvim/testdir/test_writefile.vim
+++ b/src/nvim/testdir/test_writefile.vim
@@ -167,3 +167,10 @@ func Test_writefile_sync_dev_stdout()
throw 'Skipped: /dev/stdout is not writable'
endif
endfunc
+
+func Test_writefile_sync_arg()
+ " This doesn't check if fsync() works, only that the argument is accepted.
+ call writefile(['one'], 'Xtest', 's')
+ call writefile(['two'], 'Xtest', 'S')
+ call delete('Xtest')
+endfunc