aboutsummaryrefslogtreecommitdiff
path: root/test/old
diff options
context:
space:
mode:
Diffstat (limited to 'test/old')
-rw-r--r--test/old/testdir/load.vim2
-rw-r--r--test/old/testdir/setup.vim6
-rw-r--r--test/old/testdir/test.sh2
-rw-r--r--test/old/testdir/test_autocmd.vim376
-rw-r--r--test/old/testdir/test_buffer.vim27
-rw-r--r--test/old/testdir/test_cmdline.vim24
-rw-r--r--test/old/testdir/test_comments.vim6
-rw-r--r--test/old/testdir/test_compiler.vim4
-rw-r--r--test/old/testdir/test_conceal.vim399
-rw-r--r--test/old/testdir/test_diffmode.vim129
-rw-r--r--test/old/testdir/test_digraph.vim16
-rw-r--r--test/old/testdir/test_edit.vim156
-rw-r--r--test/old/testdir/test_excmd.vim16
-rw-r--r--test/old/testdir/test_execute_func.vim46
-rw-r--r--test/old/testdir/test_expand.vim17
-rw-r--r--test/old/testdir/test_expr.vim16
-rw-r--r--test/old/testdir/test_filechanged.vim40
-rw-r--r--test/old/testdir/test_filetype.vim261
-rw-r--r--test/old/testdir/test_format.vim168
-rw-r--r--test/old/testdir/test_functions.vim125
-rw-r--r--test/old/testdir/test_global.vim11
-rw-r--r--test/old/testdir/test_highlight.vim18
-rw-r--r--test/old/testdir/test_history.vim56
-rw-r--r--test/old/testdir/test_ins_complete.vim82
-rw-r--r--test/old/testdir/test_let.vim132
-rw-r--r--test/old/testdir/test_listdict.vim6
-rw-r--r--test/old/testdir/test_mapping.vim70
-rw-r--r--test/old/testdir/test_match.vim5
-rw-r--r--test/old/testdir/test_matchparen.vim25
-rw-r--r--test/old/testdir/test_mksession.vim4
-rw-r--r--test/old/testdir/test_normal.vim119
-rw-r--r--test/old/testdir/test_perl.vim2
-rw-r--r--test/old/testdir/test_put.vim17
-rw-r--r--test/old/testdir/test_quickfix.vim70
-rw-r--r--test/old/testdir/test_recover.vim2
-rw-r--r--test/old/testdir/test_regexp_latin.vim14
-rw-r--r--test/old/testdir/test_regexp_utf8.vim2
-rw-r--r--test/old/testdir/test_registers.vim69
-rw-r--r--test/old/testdir/test_scroll_opt.vim236
-rw-r--r--test/old/testdir/test_spellrare.vim61
-rw-r--r--test/old/testdir/test_stat.vim2
-rw-r--r--test/old/testdir/test_substitute.vim10
-rw-r--r--test/old/testdir/test_syntax.vim6
-rw-r--r--test/old/testdir/test_tabpage.vim8
-rw-r--r--test/old/testdir/test_tagjump.vim24
-rw-r--r--test/old/testdir/test_termdebug.vim107
-rw-r--r--test/old/testdir/test_user_func.vim19
-rw-r--r--test/old/testdir/test_utf8.vim215
-rw-r--r--test/old/testdir/test_virtualedit.vim22
-rw-r--r--test/old/testdir/test_visual.vim697
-rw-r--r--test/old/testdir/test_window_cmd.vim348
-rw-r--r--test/old/testdir/test_winfixbuf.vim3358
-rw-r--r--test/old/testdir/vim9.vim136
53 files changed, 7127 insertions, 662 deletions
diff --git a/test/old/testdir/load.vim b/test/old/testdir/load.vim
index 5697ee7304..58ec0b1356 100644
--- a/test/old/testdir/load.vim
+++ b/test/old/testdir/load.vim
@@ -1,4 +1,4 @@
-" Also used by: test/functional/helpers.lua
+" Also used by: test/functional/testnvim.lua
function! s:load_factor() abort
let timeout = 200
diff --git a/test/old/testdir/setup.vim b/test/old/testdir/setup.vim
index 091fb95806..7313a0a162 100644
--- a/test/old/testdir/setup.vim
+++ b/test/old/testdir/setup.vim
@@ -44,12 +44,16 @@ if exists('s:did_load')
endif
let s:did_load = 1
-" Clear Nvim default mappings and menus.
+" Clear Nvim default user commands, mappings and menus.
+comclear
mapclear
mapclear!
aunmenu *
tlunmenu *
+" Undo the 'grepprg' and 'grepformat' setting in _defaults.lua.
+set grepprg& grepformat&
+
" roughly equivalent to test_setmouse() in Vim
func Ntest_setmouse(row, col)
call nvim_input_mouse('move', '', '', 0, a:row - 1, a:col - 1)
diff --git a/test/old/testdir/test.sh b/test/old/testdir/test.sh
index 6e7fa9db18..cb6feb4e68 100644
--- a/test/old/testdir/test.sh
+++ b/test/old/testdir/test.sh
@@ -58,7 +58,7 @@ check_core_dumps() {
}
check_logs() {
- # Iterate through each log to remove an useless warning.
+ # Iterate through each log to remove a useless warning.
# shellcheck disable=SC2044
for log in $(find "${1}" -type f -name "${2}"); do
sed -i "${log}" \
diff --git a/test/old/testdir/test_autocmd.vim b/test/old/testdir/test_autocmd.vim
index 4d88573a1f..cdcd68f3d6 100644
--- a/test/old/testdir/test_autocmd.vim
+++ b/test/old/testdir/test_autocmd.vim
@@ -740,6 +740,27 @@ func Test_WinClosed_switch_tab()
%bwipe!
endfunc
+" This used to trigger WinClosed twice for the same window, and the window's
+" buffer was NULL in the second autocommand.
+func Test_WinClosed_BufUnload_close_other()
+ tabnew
+ let g:tab = tabpagenr()
+ let g:buf = bufnr()
+ new
+ setlocal bufhidden=wipe
+ augroup test-WinClosed
+ autocmd BufUnload * ++once exe g:buf .. 'bwipe!'
+ autocmd WinClosed * call tabpagebuflist(g:tab)
+ augroup END
+ close
+
+ unlet g:tab
+ unlet g:buf
+ autocmd! test-WinClosed
+ augroup! test-WinClosed
+ %bwipe!
+endfunc
+
func s:AddAnAutocmd()
augroup vimBarTest
au BufReadCmd * echo 'hello'
@@ -3476,74 +3497,6 @@ func Test_autocmd_vimgrep()
augroup END
endfunc
-" Test TextChangedI and TextChanged
-func Test_Changed_ChangedI()
- throw 'Skipped: use test/functional/autocmd/textchanged_spec.lua'
- new
- call test_override("char_avail", 1)
- let [g:autocmd_i, g:autocmd_n] = ['','']
-
- func! TextChangedAutocmdI(char)
- let g:autocmd_{tolower(a:char)} = a:char .. b:changedtick
- endfunc
-
- augroup Test_TextChanged
- au!
- au TextChanged <buffer> :call TextChangedAutocmdI('N')
- au TextChangedI <buffer> :call TextChangedAutocmdI('I')
- augroup END
-
- call feedkeys("ifoo\<esc>", 'tnix')
- " TODO: Test test does not seem to trigger TextChanged autocommand, this
- " requires running Vim in a terminal window.
- " call assert_equal('N3', g:autocmd_n)
- call assert_equal('I3', g:autocmd_i)
-
- call feedkeys("yyp", 'tnix')
- " TODO: Test test does not seem to trigger TextChanged autocommand.
- " call assert_equal('N4', g:autocmd_n)
- call assert_equal('I3', g:autocmd_i)
-
- " TextChangedI should only trigger if change was done in Insert mode
- let g:autocmd_i = ''
- call feedkeys("yypi\<esc>", 'tnix')
- call assert_equal('', g:autocmd_i)
-
- " TextChanged should only trigger if change was done in Normal mode
- let g:autocmd_n = ''
- call feedkeys("ibar\<esc>", 'tnix')
- call assert_equal('', g:autocmd_n)
-
- " If change is a mix of Normal and Insert modes, TextChangedI should trigger
- func s:validate_mixed_textchangedi(keys)
- call feedkeys("ifoo\<esc>", 'tnix')
- let g:autocmd_i = ''
- let g:autocmd_n = ''
- call feedkeys(a:keys, 'tnix')
- call assert_notequal('', g:autocmd_i)
- call assert_equal('', g:autocmd_n)
- endfunc
-
- call s:validate_mixed_textchangedi("o\<esc>")
- call s:validate_mixed_textchangedi("O\<esc>")
- call s:validate_mixed_textchangedi("ciw\<esc>")
- call s:validate_mixed_textchangedi("cc\<esc>")
- call s:validate_mixed_textchangedi("C\<esc>")
- call s:validate_mixed_textchangedi("s\<esc>")
- call s:validate_mixed_textchangedi("S\<esc>")
-
-
- " CleanUp
- call test_override("char_avail", 0)
- au! TextChanged <buffer>
- au! TextChangedI <buffer>
- augroup! Test_TextChanged
- delfu TextChangedAutocmdI
- unlet! g:autocmd_i g:autocmd_n
-
- bw!
-endfunc
-
func Test_closing_autocmd_window()
let lines =<< trim END
edit Xa.txt
@@ -3569,6 +3522,49 @@ func Test_switch_window_in_autocmd_window()
call assert_false(bufexists('Xb.txt'))
endfunc
+" Test that using the autocommand window doesn't change current directory.
+func Test_autocmd_window_cwd()
+ let saveddir = getcwd()
+ call mkdir('Xcwd/a/b/c/d', 'pR')
+
+ new Xa.txt
+ tabnew
+ new Xb.txt
+
+ tabprev
+ cd Xcwd
+ call assert_match('/Xcwd$', getcwd())
+ call assert_match('\[global\] .*/Xcwd$', trim(execute('verbose pwd')))
+
+ autocmd BufEnter Xb.txt lcd ./a/b/c/d
+ doautoall BufEnter
+ au! BufEnter
+ call assert_match('/Xcwd$', getcwd())
+ call assert_match('\[global\] .*/Xcwd$', trim(execute('verbose pwd')))
+
+ tabnext
+ cd ./a
+ tcd ./b
+ lcd ./c
+ call assert_match('/Xcwd/a/b/c$', getcwd())
+ call assert_match('\[window\] .*/Xcwd/a/b/c$', trim(execute('verbose pwd')))
+
+ autocmd BufEnter Xa.txt call assert_match('Xcwd/a/b/c$', getcwd())
+ doautoall BufEnter
+ au! BufEnter
+ call assert_match('/Xcwd/a/b/c$', getcwd())
+ call assert_match('\[window\] .*/Xcwd/a/b/c$', trim(execute('verbose pwd')))
+ bwipe!
+ call assert_match('/Xcwd/a/b$', getcwd())
+ call assert_match('\[tabpage\] .*/Xcwd/a/b$', trim(execute('verbose pwd')))
+ bwipe!
+ call assert_match('/Xcwd/a$', getcwd())
+ call assert_match('\[global\] .*/Xcwd/a$', trim(execute('verbose pwd')))
+ bwipe!
+
+ call chdir(saveddir)
+endfunc
+
func Test_bufwipeout_changes_window()
" This should not crash, but we don't have any expectations about what
" happens, changing window in BufWipeout has unpredictable results.
@@ -3880,4 +3876,248 @@ func Test_autocmd_creates_new_buffer_on_bufleave()
bw c.txt
endfunc
+" Ensure `expected` was just recently written as a Vim session
+func s:assert_session_path(expected)
+ call assert_equal(a:expected, v:this_session)
+endfunc
+
+" Check for `expected` after a session is written to-disk.
+func s:watch_for_session_path(expected)
+ execute 'autocmd SessionWritePost * ++once execute "call s:assert_session_path(\"'
+ \ . a:expected
+ \ . '\")"'
+endfunc
+
+" Ensure v:this_session gets the full session path, if explicitly stated
+func Test_explicit_session_absolute_path()
+ %bwipeout!
+
+ let directory = getcwd()
+
+ let v:this_session = ""
+ let name = "some_file.vim"
+ let expected = fnamemodify(name, ":p")
+ call s:watch_for_session_path(expected)
+ execute "mksession! " .. expected
+
+ call delete(expected)
+endfunc
+
+" Ensure v:this_session gets the full session path, if explicitly stated
+func Test_explicit_session_relative_path()
+ %bwipeout!
+
+ let directory = getcwd()
+
+ let v:this_session = ""
+ let name = "some_file.vim"
+ let expected = fnamemodify(name, ":p")
+ call s:watch_for_session_path(expected)
+ execute "mksession! " .. name
+
+ call delete(expected)
+endfunc
+
+" Ensure v:this_session gets the full session path, if not specified
+func Test_implicit_session()
+ %bwipeout!
+
+ let directory = getcwd()
+
+ let v:this_session = ""
+ let expected = fnamemodify("Session.vim", ":p")
+ call s:watch_for_session_path(expected)
+ mksession!
+
+ call delete(expected)
+endfunc
+
+" Test TextChangedI and TextChanged
+func Test_Changed_ChangedI()
+ " Run this test in a terminal because it requires running the main loop.
+ " Don't use CheckRunVimInTerminal as that will skip the test on Windows.
+ CheckFeature terminal
+ CheckNotGui
+ " Starting a terminal to run Vim is always considered flaky.
+ let g:test_is_flaky = 1
+
+ call writefile(['one', 'two', 'three'], 'XTextChangedI2', 'D')
+ let before =<< trim END
+ set ttimeout ttimeoutlen=10
+ let [g:autocmd_n, g:autocmd_i] = ['','']
+
+ func TextChangedAutocmd(char)
+ let g:autocmd_{tolower(a:char)} = a:char .. b:changedtick
+ call writefile([$'{g:autocmd_n},{g:autocmd_i}'], 'XTextChangedI3')
+ endfunc
+
+ au TextChanged <buffer> :call TextChangedAutocmd('N')
+ au TextChangedI <buffer> :call TextChangedAutocmd('I')
+
+ nnoremap <CR> o<Esc>
+ autocmd SafeState * ++once call writefile([''], 'XTextChangedI3')
+ END
+
+ call writefile(before, 'Xinit', 'D')
+ let buf = term_start(
+ \ GetVimCommandCleanTerm() .. '-n -S Xinit XTextChangedI2',
+ \ {'term_rows': 10})
+ call assert_equal('running', term_getstatus(buf))
+ call WaitForAssert({-> assert_true(filereadable('XTextChangedI3'))})
+ defer delete('XTextChangedI3')
+ call WaitForAssert({-> assert_equal([''], readfile('XTextChangedI3'))})
+
+ " TextChanged should trigger if a mapping enters and leaves Insert mode.
+ call term_sendkeys(buf, "\<CR>")
+ call WaitForAssert({-> assert_equal('N4,', readfile('XTextChangedI3')->join("\n"))})
+
+ call term_sendkeys(buf, "i")
+ call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
+ call WaitForAssert({-> assert_equal('N4,', readfile('XTextChangedI3')->join("\n"))})
+ " TextChangedI should trigger if change is done in Insert mode.
+ call term_sendkeys(buf, "f")
+ call WaitForAssert({-> assert_equal('N4,I5', readfile('XTextChangedI3')->join("\n"))})
+ call term_sendkeys(buf, "o")
+ call WaitForAssert({-> assert_equal('N4,I6', readfile('XTextChangedI3')->join("\n"))})
+ call term_sendkeys(buf, "o")
+ call WaitForAssert({-> assert_equal('N4,I7', readfile('XTextChangedI3')->join("\n"))})
+ " TextChanged shouldn't trigger when leaving Insert mode and TextChangedI
+ " has been triggered.
+ call term_sendkeys(buf, "\<Esc>")
+ call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))})
+ call WaitForAssert({-> assert_equal('N4,I7', readfile('XTextChangedI3')->join("\n"))})
+
+ " TextChanged should trigger if change is done in Normal mode.
+ call term_sendkeys(buf, "yyp")
+ call WaitForAssert({-> assert_equal('N8,I7', readfile('XTextChangedI3')->join("\n"))})
+
+ " TextChangedI shouldn't trigger if change isn't done in Insert mode.
+ call term_sendkeys(buf, "i")
+ call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
+ call WaitForAssert({-> assert_equal('N8,I7', readfile('XTextChangedI3')->join("\n"))})
+ call term_sendkeys(buf, "\<Esc>")
+ call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))})
+ call WaitForAssert({-> assert_equal('N8,I7', readfile('XTextChangedI3')->join("\n"))})
+
+ " TextChangedI should trigger if change is a mix of Normal and Insert modes.
+ func! s:validate_mixed_textchangedi(buf, keys)
+ let buf = a:buf
+ call term_sendkeys(buf, "ifoo")
+ call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
+ call term_sendkeys(buf, "\<Esc>")
+ call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))})
+ call term_sendkeys(buf, ":let [g:autocmd_n, g:autocmd_i] = ['', '']\<CR>")
+ call writefile([], 'XTextChangedI3')
+ call term_sendkeys(buf, a:keys)
+ call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
+ call WaitForAssert({-> assert_match('^,I\d\+', readfile('XTextChangedI3')->join("\n"))})
+ call term_sendkeys(buf, "\<Esc>")
+ call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))})
+ call WaitForAssert({-> assert_match('^,I\d\+', readfile('XTextChangedI3')->join("\n"))})
+ endfunc
+
+ call s:validate_mixed_textchangedi(buf, "o")
+ call s:validate_mixed_textchangedi(buf, "O")
+ call s:validate_mixed_textchangedi(buf, "ciw")
+ call s:validate_mixed_textchangedi(buf, "cc")
+ call s:validate_mixed_textchangedi(buf, "C")
+ call s:validate_mixed_textchangedi(buf, "s")
+ call s:validate_mixed_textchangedi(buf, "S")
+
+ " clean up
+ bwipe!
+endfunc
+
+" Test that filetype detection still works when SwapExists autocommand sets
+" filetype in another buffer.
+func Test_SwapExists_set_other_buf_filetype()
+ let lines =<< trim END
+ set nocompatible directory=.
+ filetype on
+
+ let g:buf = bufnr()
+ new
+
+ func SwapExists()
+ let v:swapchoice = 'o'
+ call setbufvar(g:buf, '&filetype', 'text')
+ endfunc
+
+ func SafeState()
+ edit <script>
+ redir! > XftSwapExists.out
+ set readonly? filetype?
+ redir END
+ qall!
+ endfunc
+
+ autocmd SwapExists * ++nested call SwapExists()
+ autocmd SafeState * ++nested ++once call SafeState()
+ END
+ call writefile(lines, 'XftSwapExists.vim', 'D')
+
+ new XftSwapExists.vim
+ if RunVim('', '', ' -S XftSwapExists.vim')
+ call assert_equal(
+ \ ['', ' readonly', ' filetype=vim'],
+ \ readfile('XftSwapExists.out'))
+ call delete('XftSwapExists.out')
+ endif
+
+ bwipe!
+endfunc
+
+" Test that file is not marked as modified when SwapExists autocommand sets
+" 'modified' in another buffer.
+func Test_SwapExists_set_other_buf_modified()
+ let lines =<< trim END
+ set nocompatible directory=.
+
+ let g:buf = bufnr()
+ new
+
+ func SwapExists()
+ let v:swapchoice = 'o'
+ call setbufvar(g:buf, '&modified', 1)
+ endfunc
+
+ func SafeState()
+ edit <script>
+ redir! > XmodSwapExists.out
+ set readonly? modified?
+ redir END
+ qall!
+ endfunc
+
+ autocmd SwapExists * ++nested call SwapExists()
+ autocmd SafeState * ++nested ++once call SafeState()
+ END
+ call writefile(lines, 'XmodSwapExists.vim', 'D')
+
+ new XmodSwapExists.vim
+ if RunVim('', '', ' -S XmodSwapExists.vim')
+ call assert_equal(
+ \ ['', ' readonly', 'nomodified'],
+ \ readfile('XmodSwapExists.out'))
+ call delete('XmodSwapExists.out')
+ endif
+
+ bwipe!
+endfunc
+
+func Test_BufEnter_botline()
+ set hidden
+ call writefile(range(10), 'Xxx1', 'D')
+ call writefile(range(20), 'Xxx2', 'D')
+ edit Xxx1
+ edit Xxx2
+ au BufEnter Xxx1 call assert_true(line('w$') > 1)
+ edit Xxx1
+
+ bwipe! Xxx1
+ bwipe! Xxx2
+ au! BufEnter Xxx1
+ set hidden&vim
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_buffer.vim b/test/old/testdir/test_buffer.vim
index b0b9f4f24b..bc8e5eaf7b 100644
--- a/test/old/testdir/test_buffer.vim
+++ b/test/old/testdir/test_buffer.vim
@@ -133,7 +133,7 @@ func Test_bdelete_cmd()
call assert_fails('1,1bdelete 1 2', 'E488:')
call assert_fails('bdelete \)', 'E55:')
- " Deleting a unlisted and unloaded buffer
+ " Deleting an unlisted and unloaded buffer
edit Xbdelfile1
let bnr = bufnr()
set nobuflisted
@@ -232,8 +232,6 @@ endfunc
" Test for deleting a modified buffer with :confirm
func Test_bdel_with_confirm()
- " requires a UI to be active
- throw 'Skipped: use test/functional/legacy/buffer_spec.lua'
CheckUnix
CheckNotGui
CheckFeature dialog_con
@@ -251,26 +249,33 @@ endfunc
" Test for editing another buffer from a modified buffer with :confirm
func Test_goto_buf_with_confirm()
- " requires a UI to be active
- throw 'Skipped: use test/functional/legacy/buffer_spec.lua'
CheckUnix
CheckNotGui
CheckFeature dialog_con
+ " When dialog_con_gui is defined, Vim is compiled with GUI support
+ " and FEAT_BROWSE will be defined, which causes :confirm :b to
+ " call do_browse(), which will try to use a GUI file browser,
+ " which aborts if a GUI is not available.
+ CheckNotFeature dialog_con_gui
new XgotoConf
enew
call setline(1, 'test')
call assert_fails('b XgotoConf', 'E37:')
call feedkeys('c', 'L')
call assert_fails('confirm b XgotoConf', 'E37:')
- call assert_equal(1, &modified)
- call assert_equal('', @%)
+ call assert_true(&modified)
+ call assert_true(empty(bufname('%')))
call feedkeys('y', 'L')
- call assert_fails('confirm b XgotoConf', ['', 'E37:'])
- call assert_equal(1, &modified)
- call assert_equal('', @%)
+ confirm b XgotoConf
+ call assert_equal('XgotoConf', bufname('%'))
+ call assert_equal(['test'], readfile('Untitled'))
+ e Untitled
+ call setline(2, 'test2')
call feedkeys('n', 'L')
confirm b XgotoConf
- call assert_equal('XgotoConf', @%)
+ call assert_equal('XgotoConf', bufname('%'))
+ call assert_equal(['test'], readfile('Untitled'))
+ call delete('Untitled')
close!
endfunc
diff --git a/test/old/testdir/test_cmdline.vim b/test/old/testdir/test_cmdline.vim
index b8eb9a2b8b..443539fbfd 100644
--- a/test/old/testdir/test_cmdline.vim
+++ b/test/old/testdir/test_cmdline.vim
@@ -3907,9 +3907,9 @@ func Test_custom_completion()
call assert_fails("call getcompletion('', 'custom')", 'E475:')
call assert_fails("call getcompletion('', 'customlist')", 'E475:')
- call assert_equal(getcompletion('', 'custom,CustomComplete1'), ['a', 'b', 'c'])
- call assert_equal(getcompletion('', 'customlist,CustomComplete2'), ['a', 'b'])
- call assert_equal(getcompletion('b', 'customlist,CustomComplete2'), ['b'])
+ call assert_equal(['a', 'b', 'c'], getcompletion('', 'custom,CustomComplete1'))
+ call assert_equal(['a', 'b'], getcompletion('', 'customlist,CustomComplete2'))
+ call assert_equal(['b'], getcompletion('b', 'customlist,CustomComplete2'))
delcom Test1
delcom Test2
@@ -3966,4 +3966,22 @@ func Test_buffer_completion()
call assert_equal("\"b Xbuf_complete/Foobar.c Xbuf_complete/MyFoobar.c AFoobar.h", @:)
endfunc
+" :set t_??
+func Test_term_option()
+ throw 'Skipped: Nvim does not support termcap options'
+ set wildoptions&
+ let _cpo = &cpo
+ set cpo-=C
+ " There may be more, test only until t_xo
+ let expected='"set t_AB t_AF t_AU t_AL t_al t_bc t_BE t_BD t_cd t_ce t_Ce t_CF t_cl t_cm'
+ \ .. ' t_Co t_CS t_Cs t_cs t_CV t_da t_db t_DL t_dl t_ds t_Ds t_EC t_EI t_fs t_fd t_fe'
+ \ .. ' t_GP t_IE t_IS t_ke t_ks t_le t_mb t_md t_me t_mr t_ms t_nd t_op t_RF t_RB t_RC'
+ \ .. ' t_RI t_Ri t_RK t_RS t_RT t_RV t_Sb t_SC t_se t_Sf t_SH t_SI t_Si t_so t_SR t_sr'
+ \ .. ' t_ST t_Te t_te t_TE t_ti t_TI t_Ts t_ts t_u7 t_ue t_us t_Us t_ut t_vb t_ve t_vi'
+ \ .. ' t_VS t_vs t_WP t_WS t_XM t_xn t_xs t_ZH t_ZR t_8f t_8b t_8u t_xo .*'
+ call feedkeys(":set t_\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_match(expected, @:)
+ let &cpo = _cpo
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_comments.vim b/test/old/testdir/test_comments.vim
index c34b85c42d..67454f477e 100644
--- a/test/old/testdir/test_comments.vim
+++ b/test/old/testdir/test_comments.vim
@@ -237,6 +237,12 @@ func Test_comment_autoformat()
call feedkeys("aone\ntwo\n", 'xt')
call assert_equal(['one', 'two', ''], getline(1, '$'))
+ set backspace=indent,eol,start
+ %d
+ call feedkeys("aone \n\<BS>", 'xt')
+ call assert_equal(['one'], getline(1, '$'))
+ set backspace&
+
close!
endfunc
diff --git a/test/old/testdir/test_compiler.vim b/test/old/testdir/test_compiler.vim
index 0b22bafabb..69420b4b7f 100644
--- a/test/old/testdir/test_compiler.vim
+++ b/test/old/testdir/test_compiler.vim
@@ -62,10 +62,10 @@ func Test_compiler_completion()
call assert_match('^"compiler ' .. clist .. '$', @:)
call feedkeys(":compiler p\<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_match('"compiler pbx perl\( p[a-z]\+\)\+ pylint pyunit', @:)
+ call assert_match('"compiler pandoc pbx perl\( p[a-z_]\+\)\+ pylint pyunit', @:)
call feedkeys(":compiler! p\<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_match('"compiler! pbx perl\( p[a-z]\+\)\+ pylint pyunit', @:)
+ call assert_match('"compiler! pandoc pbx perl\( p[a-z_]\+\)\+ pylint pyunit', @:)
endfunc
func Test_compiler_error()
diff --git a/test/old/testdir/test_conceal.vim b/test/old/testdir/test_conceal.vim
index a679061544..df20654f12 100644
--- a/test/old/testdir/test_conceal.vim
+++ b/test/old/testdir/test_conceal.vim
@@ -169,6 +169,58 @@ func Test_conceal_with_cursorcolumn()
call StopVimInTerminal(buf)
endfunc
+" Check that 'cursorline' and 'wincolor' apply to the whole line in presence
+" of wrapped lines containing concealed text.
+func Test_conceal_wrapped_cursorline_wincolor()
+ CheckScreendump
+
+ let code =<< trim [CODE]
+ call setline(1, 'one one one |hidden| one one one one one one one one')
+ syntax match test /|hidden|/ conceal
+ set conceallevel=2 concealcursor=n cursorline
+ normal! g$
+ [CODE]
+
+ call writefile(code, 'XTest_conceal_cul_wcr', 'D')
+ let buf = RunVimInTerminal('-S XTest_conceal_cul_wcr', {'rows': 4, 'cols': 40})
+ call VerifyScreenDump(buf, 'Test_conceal_cul_wcr_01', {})
+
+ call term_sendkeys(buf, ":set wincolor=ErrorMsg\n")
+ call VerifyScreenDump(buf, 'Test_conceal_cul_wcr_02', {})
+
+ call term_sendkeys(buf, ":set nocursorline\n")
+ call VerifyScreenDump(buf, 'Test_conceal_cul_wcr_03', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+endfunc
+
+" Same as Test_conceal_wrapped_cursorline_wincolor(), but with 'rightleft'.
+func Test_conceal_wrapped_cursorline_wincolor_rightleft()
+ CheckFeature rightleft
+ CheckScreendump
+
+ let code =<< trim [CODE]
+ call setline(1, 'one one one |hidden| one one one one one one one one')
+ syntax match test /|hidden|/ conceal
+ set conceallevel=2 concealcursor=n cursorline rightleft
+ normal! g$
+ [CODE]
+
+ call writefile(code, 'XTest_conceal_cul_wcr_rl', 'D')
+ let buf = RunVimInTerminal('-S XTest_conceal_cul_wcr_rl', {'rows': 4, 'cols': 40})
+ call VerifyScreenDump(buf, 'Test_conceal_cul_wcr_rl_01', {})
+
+ call term_sendkeys(buf, ":set wincolor=ErrorMsg\n")
+ call VerifyScreenDump(buf, 'Test_conceal_cul_wcr_rl_02', {})
+
+ call term_sendkeys(buf, ":set nocursorline\n")
+ call VerifyScreenDump(buf, 'Test_conceal_cul_wcr_rl_03', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+endfunc
+
func Test_conceal_resize_term()
CheckScreendump
@@ -336,77 +388,290 @@ func Test_conceal_eol()
endfunc
func Test_conceal_mouse_click()
- enew!
+ call NewWindow(10, 40)
set mouse=a
setlocal conceallevel=2 concealcursor=nc
syn match Concealed "this" conceal
hi link Concealed Search
- call setline(1, 'conceal this click here')
- redraw
- call assert_equal(['conceal click here '], ScreenLines(1, 20))
-
- " click on the space between "this" and "click" puts cursor there
- call Ntest_setmouse(1, 9)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 13, 0, 13], getcurpos())
- " click on 'h' of "here" puts cursor there
- call Ntest_setmouse(1, 16)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 20, 0, 20], getcurpos())
- " click on 'e' of "here" puts cursor there
- call Ntest_setmouse(1, 19)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 23, 0, 23], getcurpos())
- " click after end of line puts cursor on 'e' without 'virtualedit'
- call Ntest_setmouse(1, 20)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 23, 0, 24], getcurpos())
- call Ntest_setmouse(1, 21)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 23, 0, 25], getcurpos())
- call Ntest_setmouse(1, 22)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 23, 0, 26], getcurpos())
- call Ntest_setmouse(1, 31)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 23, 0, 35], getcurpos())
- call Ntest_setmouse(1, 32)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 23, 0, 36], getcurpos())
-
- set virtualedit=all
- redraw
- " click on the space between "this" and "click" puts cursor there
- call Ntest_setmouse(1, 9)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 13, 0, 13], getcurpos())
- " click on 'h' of "here" puts cursor there
- call Ntest_setmouse(1, 16)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 20, 0, 20], getcurpos())
- " click on 'e' of "here" puts cursor there
- call Ntest_setmouse(1, 19)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 23, 0, 23], getcurpos())
- " click after end of line puts cursor there without 'virtualedit'
- call Ntest_setmouse(1, 20)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 24, 0, 24], getcurpos())
- call Ntest_setmouse(1, 21)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 24, 1, 25], getcurpos())
- call Ntest_setmouse(1, 22)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 24, 2, 26], getcurpos())
- call Ntest_setmouse(1, 31)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 24, 11, 35], getcurpos())
- call Ntest_setmouse(1, 32)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 24, 12, 36], getcurpos())
-
- bwipe!
- set mouse& virtualedit&
+
+ " Test with both 'nocursorline' and 'cursorline', as they use two different
+ " code paths to set virtual columns for the cells to clear.
+ for cul in [v:false, v:true]
+ let &l:cursorline = cul
+
+ call setline(1, 'conceal this click here')
+ call assert_equal([
+ \ 'conceal click here ',
+ \ ], ScreenLines(1, 40))
+
+ " Click on the space between "this" and "click" puts cursor there.
+ call Ntest_setmouse(1, 9)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 13, 0, 13], getcurpos())
+ " Click on 'h' of "here" puts cursor there.
+ call Ntest_setmouse(1, 16)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 20, 0, 20], getcurpos())
+ " Click on 'e' of "here" puts cursor there.
+ call Ntest_setmouse(1, 19)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 23, 0, 23], getcurpos())
+ " Click after end of line puts cursor on 'e' without 'virtualedit'.
+ call Ntest_setmouse(1, 20)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 23, 0, 24], getcurpos())
+ call Ntest_setmouse(1, 21)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 23, 0, 25], getcurpos())
+ call Ntest_setmouse(1, 22)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 23, 0, 26], getcurpos())
+ call Ntest_setmouse(1, 31)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 23, 0, 35], getcurpos())
+ call Ntest_setmouse(1, 32)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 23, 0, 36], getcurpos())
+
+ set virtualedit=all
+ redraw
+ " Click on the space between "this" and "click" puts cursor there.
+ call Ntest_setmouse(1, 9)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 13, 0, 13], getcurpos())
+ " Click on 'h' of "here" puts cursor there.
+ call Ntest_setmouse(1, 16)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 20, 0, 20], getcurpos())
+ " Click on 'e' of "here" puts cursor there.
+ call Ntest_setmouse(1, 19)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 23, 0, 23], getcurpos())
+ " Click after end of line puts cursor there with 'virtualedit'.
+ call Ntest_setmouse(1, 20)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 0, 24], getcurpos())
+ call Ntest_setmouse(1, 21)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 1, 25], getcurpos())
+ call Ntest_setmouse(1, 22)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 2, 26], getcurpos())
+ call Ntest_setmouse(1, 31)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 11, 35], getcurpos())
+ call Ntest_setmouse(1, 32)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 12, 36], getcurpos())
+ " Behavior should also be the same with 'colorcolumn'.
+ setlocal colorcolumn=30
+ redraw
+ call Ntest_setmouse(1, 31)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 11, 35], getcurpos())
+ call Ntest_setmouse(1, 32)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 12, 36], getcurpos())
+ setlocal colorcolumn&
+
+ if has('rightleft')
+ setlocal rightleft
+ call assert_equal([
+ \ ' ereh kcilc laecnoc',
+ \ ], ScreenLines(1, 40))
+ " Click on the space between "this" and "click" puts cursor there.
+ call Ntest_setmouse(1, 41 - 9)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 13, 0, 13], getcurpos())
+ " Click on 'h' of "here" puts cursor there.
+ call Ntest_setmouse(1, 41 - 16)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 20, 0, 20], getcurpos())
+ " Click on 'e' of "here" puts cursor there.
+ call Ntest_setmouse(1, 41 - 19)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 23, 0, 23], getcurpos())
+ " Click after end of line puts cursor there with 'virtualedit'.
+ call Ntest_setmouse(1, 41 - 20)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 0, 24], getcurpos())
+ call Ntest_setmouse(1, 41 - 21)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 1, 25], getcurpos())
+ call Ntest_setmouse(1, 41 - 22)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 2, 26], getcurpos())
+ call Ntest_setmouse(1, 41 - 31)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 11, 35], getcurpos())
+ call Ntest_setmouse(1, 41 - 32)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 12, 36], getcurpos())
+ setlocal rightleft&
+ endif
+
+ set virtualedit&
+
+ " Test with a wrapped line.
+ call setline(1, ['conceal this click here']->repeat(3)->join())
+ call assert_equal([
+ \ 'conceal click here conceal cli ',
+ \ 'ck here conceal click here ',
+ \ ], ScreenLines([1, 2], 40))
+ " Click on boguscols puts cursor on the last char of a screen line.
+ for col in range(33, 40)
+ call Ntest_setmouse(1, col)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 40, 0, 40], getcurpos())
+ endfor
+
+ " Also test with the last char of a screen line concealed.
+ setlocal number signcolumn=yes
+ call assert_equal([
+ \ ' 1 conceal click here conceal ',
+ \ ' click here conceal click h ',
+ \ ' ere ',
+ \ ], ScreenLines([1, 3], 40))
+ call Ntest_setmouse(1, 34)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 32, 0, 32], getcurpos())
+ call Ntest_setmouse(2, 7)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 37, 0, 37], getcurpos())
+ " Click on boguscols puts cursor on the last char of a screen line.
+ for col in range(35, 40)
+ call Ntest_setmouse(1, col)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 34, 0, 34], getcurpos())
+ call Ntest_setmouse(2, col)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 68, 0, 68], getcurpos())
+ endfor
+ setlocal number& signcolumn&
+ endfor
+
+ call CloseWindow()
+ set mouse&
+endfunc
+
+" Test that cursor is drawn at the correct column when it is after end of the
+" line with 'virtualedit' and concealing.
+func Run_test_conceal_virtualedit_after_eol(wrap)
+ let code =<< trim eval [CODE]
+ let &wrap = {a:wrap}
+ call setline(1, 'abcdefgh|hidden|ijklmnpop')
+ syntax match test /|hidden|/ conceal
+ set conceallevel=2 concealcursor=n virtualedit=all
+ normal! $
+ [CODE]
+ call writefile(code, 'XTest_conceal_ve_after_eol', 'D')
+ let buf = RunVimInTerminal('-S XTest_conceal_ve_after_eol', {'rows': 3})
+ call VerifyScreenDump(buf, 'Test_conceal_ve_after_eol_1', {})
+ call term_sendkeys(buf, "l")
+ call VerifyScreenDump(buf, 'Test_conceal_ve_after_eol_2', {})
+ call term_sendkeys(buf, "l")
+ call VerifyScreenDump(buf, 'Test_conceal_ve_after_eol_3', {})
+ call term_sendkeys(buf, "l")
+ call VerifyScreenDump(buf, 'Test_conceal_ve_after_eol_4', {})
+ call term_sendkeys(buf, "rr")
+ call VerifyScreenDump(buf, 'Test_conceal_ve_after_eol_5', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+endfunc
+
+func Test_conceal_virtualedit_after_eol()
+ CheckScreendump
+
+ call Run_test_conceal_virtualedit_after_eol(1)
+ call Run_test_conceal_virtualedit_after_eol(0)
+endfunc
+
+" Same as Run_test_conceal_virtualedit_after_eol(), but with 'rightleft'.
+func Run_test_conceal_virtualedit_after_eol_rightleft(wrap)
+ let code =<< trim eval [CODE]
+ let &wrap = {a:wrap}
+ call setline(1, 'abcdefgh|hidden|ijklmnpop')
+ syntax match test /|hidden|/ conceal
+ set conceallevel=2 concealcursor=n virtualedit=all rightleft
+ normal! $
+ [CODE]
+ call writefile(code, 'XTest_conceal_ve_after_eol_rl', 'D')
+ let buf = RunVimInTerminal('-S XTest_conceal_ve_after_eol_rl', {'rows': 3})
+ call VerifyScreenDump(buf, 'Test_conceal_ve_after_eol_rl_1', {})
+ call term_sendkeys(buf, "h")
+ call VerifyScreenDump(buf, 'Test_conceal_ve_after_eol_rl_2', {})
+ call term_sendkeys(buf, "h")
+ call VerifyScreenDump(buf, 'Test_conceal_ve_after_eol_rl_3', {})
+ call term_sendkeys(buf, "h")
+ call VerifyScreenDump(buf, 'Test_conceal_ve_after_eol_rl_4', {})
+ call term_sendkeys(buf, "rr")
+ call VerifyScreenDump(buf, 'Test_conceal_ve_after_eol_rl_5', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+endfunc
+
+func Test_conceal_virtualedit_after_eol_rightleft()
+ CheckFeature rightleft
+ CheckScreendump
+
+ call Run_test_conceal_virtualedit_after_eol_rightleft(1)
+ call Run_test_conceal_virtualedit_after_eol_rightleft(0)
+endfunc
+
+" Test that cursor position is correct when double-width chars are concealed.
+func Run_test_conceal_double_width(wrap)
+ let code =<< trim eval [CODE]
+ let &wrap = {a:wrap}
+ call setline(1, ['aaaaa口=口bbbbb口=口ccccc', 'foobar'])
+ syntax match test /口=口/ conceal cchar=β
+ set conceallevel=2 concealcursor=n colorcolumn=30
+ normal! $
+ [CODE]
+ call writefile(code, 'XTest_conceal_double_width', 'D')
+ let buf = RunVimInTerminal('-S XTest_conceal_double_width', {'rows': 4})
+ call VerifyScreenDump(buf, 'Test_conceal_double_width_1', {})
+ call term_sendkeys(buf, "gM")
+ call VerifyScreenDump(buf, 'Test_conceal_double_width_2', {})
+ call term_sendkeys(buf, ":set conceallevel=3\<CR>")
+ call VerifyScreenDump(buf, 'Test_conceal_double_width_3', {})
+ call term_sendkeys(buf, "$")
+ call VerifyScreenDump(buf, 'Test_conceal_double_width_4', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+endfunc
+
+func Test_conceal_double_width()
+ CheckScreendump
+
+ call Run_test_conceal_double_width(1)
+ call Run_test_conceal_double_width(0)
+endfunc
+
+" Test that line wrapping is correct when double-width chars are concealed.
+func Test_conceal_double_width_wrap()
+ CheckScreendump
+
+ let code =<< trim [CODE]
+ call setline(1, 'aaaaaaaaaa口=口bbbbbbbbbb口=口cccccccccc')
+ syntax match test /口=口/ conceal cchar=β
+ set conceallevel=2 concealcursor=n
+ normal! $
+ [CODE]
+ call writefile(code, 'XTest_conceal_double_width_wrap', 'D')
+ let buf = RunVimInTerminal('-S XTest_conceal_double_width_wrap', {'rows': 4, 'cols': 20})
+ call VerifyScreenDump(buf, 'Test_conceal_double_width_wrap_1', {})
+ call term_sendkeys(buf, "gM")
+ call VerifyScreenDump(buf, 'Test_conceal_double_width_wrap_2', {})
+ call term_sendkeys(buf, ":set conceallevel=3\<CR>")
+ call VerifyScreenDump(buf, 'Test_conceal_double_width_wrap_3', {})
+ call term_sendkeys(buf, "$")
+ call VerifyScreenDump(buf, 'Test_conceal_double_width_wrap_4', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_diffmode.vim b/test/old/testdir/test_diffmode.vim
index 9a3e006430..71483b7469 100644
--- a/test/old/testdir/test_diffmode.vim
+++ b/test/old/testdir/test_diffmode.vim
@@ -3,6 +3,7 @@
source shared.vim
source screendump.vim
source check.vim
+source view_util.vim
func Test_diff_fold_sync()
enew!
@@ -1631,36 +1632,39 @@ endfunc
func Test_diff_scroll_many_filler()
20new
vnew
- call setline(1, ['^^^', '^^^', '$$$', '$$$'])
+ call setline(1, range(1, 40))
diffthis
setlocal scrolloff=0
wincmd p
- call setline(1, ['^^^', '^^^'] + repeat(['###'], 41) + ['$$$', '$$$'])
+ call setline(1, range(1, 20)->reverse() + ['###']->repeat(41) + range(21, 40)->reverse())
diffthis
setlocal scrolloff=0
wincmd p
redraw
" Note: need a redraw after each scroll, otherwise the test always passes.
- normal! G
- redraw
- call assert_equal(3, winsaveview().topline)
- call assert_equal(18, winsaveview().topfill)
- exe "normal! \<C-B>"
- redraw
- call assert_equal(3, winsaveview().topline)
- call assert_equal(19, winsaveview().topfill)
- exe "normal! \<C-B>"
- redraw
- call assert_equal(2, winsaveview().topline)
- call assert_equal(0, winsaveview().topfill)
- exe "normal! \<C-B>"
- redraw
- call assert_equal(1, winsaveview().topline)
- call assert_equal(0, winsaveview().topfill)
+ for _ in range(2)
+ normal! G
+ redraw
+ call assert_equal(40, winsaveview().topline)
+ call assert_equal(19, winsaveview().topfill)
+ exe "normal! \<C-B>"
+ redraw
+ call assert_equal(22, winsaveview().topline)
+ call assert_equal(0, winsaveview().topfill)
+ exe "normal! \<C-B>"
+ redraw
+ call assert_equal(4, winsaveview().topline)
+ call assert_equal(0, winsaveview().topfill)
+ exe "normal! \<C-B>"
+ redraw
+ call assert_equal(1, winsaveview().topline)
+ call assert_equal(0, winsaveview().topfill)
+ set smoothscroll
+ endfor
- bwipe!
- bwipe!
+ set smoothscroll&
+ %bwipe!
endfunc
" This was trying to update diffs for a buffer being closed
@@ -1702,4 +1706,89 @@ func Test_diff_put_and_undo()
endfunc
+func Test_diff_toggle_wrap_skipcol_leftcol()
+ 61vnew
+ call setline(1, 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.')
+ 30vnew
+ call setline(1, 'ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.')
+ let win1 = win_getid()
+ setlocal smoothscroll
+ exe "normal! $\<C-E>"
+ wincmd l
+ let win2 = win_getid()
+ setlocal smoothscroll
+ exe "normal! $\<C-E>"
+ call assert_equal([
+ \ '<<<sadipscing elitr, sed diam |<<<tetur sadipscing elitr, sed|',
+ \ 'nonumy eirmod tempor invidunt | diam nonumy eirmod tempor inv|',
+ \ 'ut labore et dolore magna aliq|idunt ut labore et dolore magn|',
+ \ 'uyam erat, sed diam voluptua. |a aliquyam erat, sed diam volu|',
+ \ '~ |ptua. |',
+ \ ], ScreenLines([1, 5], 62))
+ call assert_equal({'col': 29, 'row': 4, 'endcol': 29, 'curscol': 29},
+ \ screenpos(win1, line('.', win1), col('.', win1)))
+ call assert_equal({'col': 36, 'row': 5, 'endcol': 36, 'curscol': 36},
+ \ screenpos(win2, line('.', win2), col('.', win2)))
+
+ wincmd h
+ diffthis
+ wincmd l
+ diffthis
+ normal! 0
+ call assert_equal([
+ \ ' ipsum dolor sit amet, conset| Lorem ipsum dolor sit amet, |',
+ \ '~ |~ |',
+ \ ], ScreenLines([1, 2], 62))
+ call assert_equal({'col': 3, 'row': 1, 'endcol': 3, 'curscol': 3},
+ \ screenpos(win1, line('.', win1), col('.', win1)))
+ call assert_equal({'col': 34, 'row': 1, 'endcol': 34, 'curscol': 34},
+ \ screenpos(win2, line('.', win2), col('.', win2)))
+
+ normal! $
+ call assert_equal([
+ \ ' voluptua. | diam voluptua. |',
+ \ '~ |~ |',
+ \ ], ScreenLines([1, 2], 62))
+ call assert_equal({'col': 11, 'row': 1, 'endcol': 11, 'curscol': 11},
+ \ screenpos(win1, line('.', win1), col('.', win1)))
+ call assert_equal({'col': 48, 'row': 1, 'endcol': 48, 'curscol': 48},
+ \ screenpos(win2, line('.', win2), col('.', win2)))
+
+ diffoff!
+ call assert_equal([
+ \ 'ipsum dolor sit amet, consetet|Lorem ipsum dolor sit amet, co|',
+ \ 'ur sadipscing elitr, sed diam |nsetetur sadipscing elitr, sed|',
+ \ 'nonumy eirmod tempor invidunt | diam nonumy eirmod tempor inv|',
+ \ 'ut labore et dolore magna aliq|idunt ut labore et dolore magn|',
+ \ 'uyam erat, sed diam voluptua. |a aliquyam erat, sed diam volu|',
+ \ '~ |ptua. |',
+ \ ], ScreenLines([1, 6], 62))
+ call assert_equal({'col': 29, 'row': 5, 'endcol': 29, 'curscol': 29},
+ \ screenpos(win1, line('.', win1), col('.', win1)))
+ call assert_equal({'col': 36, 'row': 6, 'endcol': 36, 'curscol': 36},
+ \ screenpos(win2, line('.', win2), col('.', win2)))
+
+ bwipe!
+ bwipe!
+endfunc
+
+" Ctrl-D reveals filler lines below the last line in the buffer.
+func Test_diff_eob_halfpage()
+ new
+ call setline(1, ['']->repeat(10) + ['a'])
+ diffthis
+ new
+ call setline(1, ['']->repeat(3) + ['a', 'b'])
+ diffthis
+ resize 5
+ wincmd j
+ resize 5
+ norm G
+ call assert_equal(7, line('w0'))
+ exe "norm! \<C-D>"
+ call assert_equal(8, line('w0'))
+
+ %bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_digraph.vim b/test/old/testdir/test_digraph.vim
index 8229248f7f..8fbcd4d8ca 100644
--- a/test/old/testdir/test_digraph.vim
+++ b/test/old/testdir/test_digraph.vim
@@ -539,6 +539,8 @@ func Test_digraph_set_function()
call assert_fails('call digraph_set("あ", "あ")', 'E1214: Digraph must be just two characters: あ')
call assert_fails('call digraph_set("aa", "ああ")', 'E1215: Digraph must be one character: ああ')
call assert_fails('call digraph_set("aa", "か" .. nr2char(0x3099))', 'E1215: Digraph must be one character: か' .. nr2char(0x3099))
+ call assert_fails('call digraph_set(v:_null_string, "い")', 'E1214: Digraph must be just two characters')
+ call assert_fails('call digraph_set("aa", 0z10)', 'E976: Using a Blob as a String')
bwipe!
endfunc
@@ -556,6 +558,8 @@ func Test_digraph_get_function()
call assert_equal('う', digraph_get(' '))
call assert_fails('call digraph_get("aaa")', 'E1214: Digraph must be just two characters: aaa')
call assert_fails('call digraph_get("b")', 'E1214: Digraph must be just two characters: b')
+ call assert_fails('call digraph_get(v:_null_string)', 'E1214: Digraph must be just two characters:')
+ call assert_fails('call digraph_get(0z10)', 'E976: Using a Blob as a String')
endfunc
func Test_digraph_get_function_encode()
@@ -580,8 +584,12 @@ func Test_digraph_setlist_function()
call assert_equal('く', digraph_get('bb'))
call assert_fails('call digraph_setlist([[]])', 'E1216:')
- call assert_fails('call digraph_setlist([["aa", "b", "cc"]])', '1216:')
+ call assert_fails('call digraph_setlist([["aa", "b", "cc"]])', 'E1216:')
call assert_fails('call digraph_setlist([["あ", "あ"]])', 'E1214: Digraph must be just two characters: あ')
+ call assert_fails('call digraph_setlist([v:_null_list])', 'E1216:')
+ call assert_fails('call digraph_setlist({})', 'E1216:')
+ call assert_fails('call digraph_setlist([{}])', 'E1216:')
+ call assert_true(digraph_setlist(v:_null_list))
endfunc
func Test_digraph_getlist_function()
@@ -589,13 +597,15 @@ func Test_digraph_getlist_function()
call digraph_setlist([['aa', 'き'], ['bb', 'く']])
for pair in digraph_getlist(1)
- call assert_equal(digraph_get(pair[0]), pair[1])
+ call assert_equal(pair[1], digraph_get(pair[0]))
endfor
" We don't know how many digraphs are registered before, so check the number
" of digraphs returned.
call assert_equal(digraph_getlist()->len(), digraph_getlist(0)->len())
- call assert_notequal((digraph_getlist()->len()), digraph_getlist(1)->len())
+ call assert_notequal(digraph_getlist()->len(), digraph_getlist(1)->len())
+
+ call assert_fails('call digraph_getlist(0z12)', 'E974: Using a Blob as a Number')
endfunc
diff --git a/test/old/testdir/test_edit.vim b/test/old/testdir/test_edit.vim
index 67143ab524..57ff63f26d 100644
--- a/test/old/testdir/test_edit.vim
+++ b/test/old/testdir/test_edit.vim
@@ -6,8 +6,6 @@ endif
source check.vim
source screendump.vim
-
-" Needed for testing basic rightleft: Test_edit_rightleft
source view_util.vim
" Needs to come first until the bug in getchar() is
@@ -1320,9 +1318,9 @@ func Test_edit_PAGEUP_PAGEDOWN()
call feedkeys("A\<PageUp>\<esc>", 'tnix')
call assert_equal([0, 13, 1, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix')
- call assert_equal([0, 5, 1, 0], getpos('.'))
+ call assert_equal([0, 10, 1, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix')
- call assert_equal([0, 5, 11, 0], getpos('.'))
+ call assert_equal([0, 10, 11, 0], getpos('.'))
" <S-Up> is the same as <PageUp>
" <S-Down> is the same as <PageDown>
call cursor(1, 1)
@@ -1343,9 +1341,9 @@ func Test_edit_PAGEUP_PAGEDOWN()
call feedkeys("A\<S-Up>\<esc>", 'tnix')
call assert_equal([0, 13, 1, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix')
- call assert_equal([0, 5, 1, 0], getpos('.'))
+ call assert_equal([0, 10, 1, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix')
- call assert_equal([0, 5, 11, 0], getpos('.'))
+ call assert_equal([0, 10, 11, 0], getpos('.'))
set nostartofline
call cursor(30, 11)
norm! zt
@@ -1356,9 +1354,9 @@ func Test_edit_PAGEUP_PAGEDOWN()
call feedkeys("A\<PageUp>\<esc>", 'tnix')
call assert_equal([0, 13, 11, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix')
- call assert_equal([0, 5, 11, 0], getpos('.'))
+ call assert_equal([0, 10, 11, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix')
- call assert_equal([0, 5, 11, 0], getpos('.'))
+ call assert_equal([0, 10, 11, 0], getpos('.'))
call cursor(1, 1)
call feedkeys("A\<PageDown>\<esc>", 'tnix')
call assert_equal([0, 9, 11, 0], getpos('.'))
@@ -1381,9 +1379,9 @@ func Test_edit_PAGEUP_PAGEDOWN()
call feedkeys("A\<S-Up>\<esc>", 'tnix')
call assert_equal([0, 13, 11, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix')
- call assert_equal([0, 5, 11, 0], getpos('.'))
+ call assert_equal([0, 10, 11, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix')
- call assert_equal([0, 5, 11, 0], getpos('.'))
+ call assert_equal([0, 10, 11, 0], getpos('.'))
call cursor(1, 1)
call feedkeys("A\<S-Down>\<esc>", 'tnix')
call assert_equal([0, 9, 11, 0], getpos('.'))
@@ -1985,8 +1983,8 @@ func Test_edit_ctrl_r_failed()
let buf = RunVimInTerminal('', #{rows: 6, cols: 60})
- " trying to insert a dictionary produces an error
- call term_sendkeys(buf, "i\<C-R>={}\<CR>")
+ " trying to insert a blob produces an error
+ call term_sendkeys(buf, "i\<C-R>=0z\<CR>")
" ending Insert mode should put the cursor back on the ':'
call term_sendkeys(buf, ":\<Esc>")
@@ -2067,7 +2065,10 @@ func Test_edit_revins()
call setline(1, 'one two three')
exe "normal! wi\nfour"
call assert_equal(['one two three', 'ruof'], getline(1, '$'))
- set revins&
+ set backspace=indent,eol,start
+ exe "normal! ggA\<BS>:"
+ call assert_equal(['one two three:ruof'], getline(1, '$'))
+ set revins& backspace&
bw!
endfunc
@@ -2153,4 +2154,133 @@ func Test_edit_Ctrl_RSB()
bwipe!
endfunc
+func s:check_backspace(expected)
+ let g:actual = []
+ inoremap <buffer> <F2> <Cmd>let g:actual += [getline('.')]<CR>
+ set backspace=indent,eol,start
+
+ exe "normal i" .. repeat("\<BS>\<F2>", len(a:expected))
+ call assert_equal(a:expected, g:actual)
+
+ set backspace&
+ iunmap <buffer> <F2>
+ unlet g:actual
+endfunc
+
+" Test that backspace works with 'smarttab' and mixed Tabs and spaces.
+func Test_edit_backspace_smarttab_mixed()
+ set smarttab
+ call NewWindow(1, 30)
+ setlocal tabstop=4 shiftwidth=4
+
+ call setline(1, "\t \t \t a")
+ normal! $
+ call s:check_backspace([
+ \ "\t \t \ta",
+ \ "\t \t a",
+ \ "\t \t a",
+ \ "\t \ta",
+ \ "\t a",
+ \ "\ta",
+ \ "a",
+ \ ])
+
+ call CloseWindow()
+ set smarttab&
+endfunc
+
+" Test that backspace works with 'smarttab' and 'varsofttabstop'.
+func Test_edit_backspace_smarttab_varsofttabstop()
+ CheckFeature vartabs
+
+ set smarttab
+ call NewWindow(1, 30)
+ setlocal tabstop=8 varsofttabstop=6,2,5,3
+
+ call setline(1, "a\t \t a")
+ normal! $
+ call s:check_backspace([
+ \ "a\t \ta",
+ \ "a\t a",
+ \ "a\ta",
+ \ "a a",
+ \ "aa",
+ \ "a",
+ \ ])
+
+ call CloseWindow()
+ set smarttab&
+endfunc
+
+" Test that backspace works with 'smarttab' when a Tab is shown as "^I".
+func Test_edit_backspace_smarttab_list()
+ set smarttab
+ call NewWindow(1, 30)
+ setlocal tabstop=4 shiftwidth=4 list listchars=
+
+ call setline(1, "\t \t \t a")
+ normal! $
+ call s:check_backspace([
+ \ "\t \t a",
+ \ "\t \t a",
+ \ "\t \ta",
+ \ "\t a",
+ \ "a",
+ \ ])
+
+ call CloseWindow()
+ set smarttab&
+endfunc
+
+" Test that backspace works with 'smarttab' and 'breakindent'.
+func Test_edit_backspace_smarttab_breakindent()
+ CheckFeature linebreak
+
+ set smarttab
+ call NewWindow(3, 17)
+ setlocal tabstop=4 shiftwidth=4 breakindent breakindentopt=min:5
+
+ call setline(1, "\t \t \t a")
+ normal! $
+ call s:check_backspace([
+ \ "\t \t \ta",
+ \ "\t \t a",
+ \ "\t \t a",
+ \ "\t \ta",
+ \ "\t a",
+ \ "\ta",
+ \ "a",
+ \ ])
+
+ call CloseWindow()
+ set smarttab&
+endfunc
+
+" Test that backspace works with 'smarttab' and virtual text.
+func Test_edit_backspace_smarttab_virtual_text()
+ CheckFeature textprop
+
+ set smarttab
+ call NewWindow(1, 50)
+ setlocal tabstop=4 shiftwidth=4
+
+ call setline(1, "\t \t \t a")
+ call prop_type_add('theprop', {})
+ call prop_add(1, 3, {'type': 'theprop', 'text': 'text'})
+ normal! $
+ call s:check_backspace([
+ \ "\t \t \ta",
+ \ "\t \t a",
+ \ "\t \t a",
+ \ "\t \ta",
+ \ "\t a",
+ \ "\ta",
+ \ "a",
+ \ ])
+
+ call CloseWindow()
+ call prop_type_delete('theprop')
+ set smarttab&
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_excmd.vim b/test/old/testdir/test_excmd.vim
index b7356c22fa..4a780078fd 100644
--- a/test/old/testdir/test_excmd.vim
+++ b/test/old/testdir/test_excmd.vim
@@ -3,6 +3,7 @@
source check.vim
source shared.vim
source term_util.vim
+source screendump.vim
func Test_ex_delete()
new
@@ -758,4 +759,19 @@ func Test_ex_address_range_overflow()
call assert_fails(':--+foobar', 'E492:')
endfunc
+func Test_drop_modified_file()
+ CheckScreendump
+ let lines =<< trim END
+ call setline(1, 'The quick brown fox jumped over the lazy dogs')
+ END
+ call writefile([''], 'Xdrop_modified.txt', 'D')
+ call writefile(lines, 'Xtest_drop_modified', 'D')
+ let buf = RunVimInTerminal('-S Xtest_drop_modified Xdrop_modified.txt', {'rows': 10,'columns': 40})
+ call term_sendkeys(buf, ":drop Xdrop_modified.txt\<CR>")
+ call VerifyScreenDump(buf, 'Test_drop_modified_1', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_execute_func.vim b/test/old/testdir/test_execute_func.vim
index 2edae39b8f..ec8ed160c3 100644
--- a/test/old/testdir/test_execute_func.vim
+++ b/test/old/testdir/test_execute_func.vim
@@ -3,6 +3,7 @@
source view_util.vim
source check.vim
source vim9.vim
+source term_util.vim
func NestedEval()
let nested = execute('echo "nested\nlines"')
@@ -177,6 +178,27 @@ func Test_win_execute_visual_redraw()
bwipe!
endfunc
+func Test_win_execute_on_startup()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ vim9script
+ [repeat('x', &columns)]->writefile('Xfile1')
+ silent tabedit Xfile2
+ var id = win_getid()
+ silent tabedit Xfile3
+ autocmd VimEnter * win_execute(id, 'close')
+ END
+ call writefile(lines, 'XwinExecute')
+ let buf = RunVimInTerminal('-p Xfile1 -Nu XwinExecute', {})
+
+ " this was crashing on exit with EXITFREE defined
+ call StopVimInTerminal(buf)
+
+ call delete('XwinExecute')
+ call delete('Xfile1')
+endfunc
+
func Test_execute_cmd_with_null()
call assert_equal("", execute(v:_null_string))
call assert_equal("", execute(v:_null_list))
@@ -190,4 +212,28 @@ func Test_execute_cmd_with_null()
endif
endfunc
+func Test_win_execute_tabpagewinnr()
+ belowright split
+ tab split
+ belowright split
+ call assert_equal(2, tabpagewinnr(1))
+
+ tabprevious
+ wincmd p
+ call assert_equal(1, tabpagenr())
+ call assert_equal(1, tabpagewinnr(1))
+ call assert_equal(2, tabpagewinnr(2))
+
+ call win_execute(win_getid(1, 2),
+ \ 'call assert_equal(2, tabpagenr())'
+ \ .. '| call assert_equal(1, tabpagewinnr(1))'
+ \ .. '| call assert_equal(1, tabpagewinnr(2))')
+
+ call assert_equal(1, tabpagenr())
+ call assert_equal(1, tabpagewinnr(1))
+ call assert_equal(2, tabpagewinnr(2))
+
+ %bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_expand.vim b/test/old/testdir/test_expand.vim
index cd537f4ea1..24df156386 100644
--- a/test/old/testdir/test_expand.vim
+++ b/test/old/testdir/test_expand.vim
@@ -45,12 +45,25 @@ endfunc
func Test_expand_tilde_filename()
split ~
- call assert_equal('~', expand('%'))
+ call assert_equal('~', expand('%'))
call assert_notequal(expand('%:p'), expand('~/'))
- call assert_match('\~', expand('%:p'))
+ call assert_match('\~', expand('%:p'))
bwipe!
endfunc
+func Test_expand_env_pathsep()
+ let $FOO = './foo'
+ call assert_equal('./foo/bar', expand('$FOO/bar'))
+ let $FOO = './foo/'
+ call assert_equal('./foo/bar', expand('$FOO/bar'))
+ let $FOO = 'C:'
+ call assert_equal('C:/bar', expand('$FOO/bar'))
+ let $FOO = 'C:/'
+ call assert_equal('C:/bar', expand('$FOO/bar'))
+
+ unlet $FOO
+endfunc
+
func Test_expandcmd()
let $FOO = 'Test'
call assert_equal('e x/Test/y', expandcmd('e x/$FOO/y'))
diff --git a/test/old/testdir/test_expr.vim b/test/old/testdir/test_expr.vim
index d316e63818..8871e7e7d7 100644
--- a/test/old/testdir/test_expr.vim
+++ b/test/old/testdir/test_expr.vim
@@ -904,6 +904,22 @@ func Test_string_interp()
endif
call assert_equal(0, tmp)
+ #" Dict interpolation
+ VAR d = {'a': 10, 'b': [1, 2]}
+ call assert_equal("{'a': 10, 'b': [1, 2]}", $'{d}')
+ VAR emptydict = {}
+ call assert_equal("a{}b", $'a{emptydict}b')
+ VAR nulldict = v:_null_dict
+ call assert_equal("a{}b", $'a{nulldict}b')
+
+ #" List interpolation
+ VAR l = ['a', 'b', 'c']
+ call assert_equal("['a', 'b', 'c']", $'{l}')
+ VAR emptylist = []
+ call assert_equal("a[]b", $'a{emptylist}b')
+ VAR nulllist = v:_null_list
+ call assert_equal("a[]b", $'a{nulllist}b')
+
#" Stray closing brace.
call assert_fails('echo $"moo}"', 'E1278:')
#" Undefined variable in expansion.
diff --git a/test/old/testdir/test_filechanged.vim b/test/old/testdir/test_filechanged.vim
index fef0eb732f..a8fc78ff90 100644
--- a/test/old/testdir/test_filechanged.vim
+++ b/test/old/testdir/test_filechanged.vim
@@ -11,8 +11,12 @@ func Test_FileChangedShell_reload()
new Xchanged_r
call setline(1, 'reload this')
write
- " Need to wait until the timestamp would change by at least a second.
- sleep 2
+ " Need to wait until the timestamp would change.
+ if has('nanotime')
+ sleep 10m
+ else
+ sleep 2
+ endif
silent !echo 'extra line' >>Xchanged_r
checktime
call assert_equal('changed', g:reason)
@@ -50,7 +54,11 @@ func Test_FileChangedShell_reload()
call assert_equal('new line', getline(1))
" Only time changed
- sleep 2
+ if has('nanotime')
+ sleep 10m
+ else
+ sleep 2
+ endif
silent !touch Xchanged_r
let g:reason = ''
checktime
@@ -65,7 +73,11 @@ func Test_FileChangedShell_reload()
call setline(2, 'before write')
write
call setline(2, 'after write')
- sleep 2
+ if has('nanotime')
+ sleep 10m
+ else
+ sleep 2
+ endif
silent !echo 'different line' >>Xchanged_r
let g:reason = ''
checktime
@@ -140,8 +152,6 @@ func Test_FileChangedShell_edit()
endfunc
func Test_FileChangedShell_edit_dialog()
- " requires a UI to be active
- throw 'Skipped: use test/functional/legacy/filechanged_spec.lua'
CheckNotGui
CheckUnix " Using low level feedkeys() does not work on MS-Windows.
@@ -156,6 +166,7 @@ func Test_FileChangedShell_edit_dialog()
au FileChangedShell Xchanged_r let g:reason = v:fcs_reason | let v:fcs_choice = 'ask'
augroup END
call assert_equal(&fileformat, 'unix')
+ sleep 10m " make the test less flaky in Nvim
call writefile(["line1\r", "line2\r"], 'Xchanged_r')
let g:reason = ''
call feedkeys('L', 'L') " load file content only
@@ -173,6 +184,7 @@ func Test_FileChangedShell_edit_dialog()
au FileChangedShell Xchanged_r let g:reason = v:fcs_reason | let v:fcs_choice = 'ask'
augroup END
call assert_equal(&fileformat, 'unix')
+ sleep 10m " make the test less flaky in Nvim
call writefile(["line1\r", "line2\r"], 'Xchanged_r')
let g:reason = ''
call feedkeys('a', 'L') " load file content and options
@@ -191,8 +203,6 @@ func Test_FileChangedShell_edit_dialog()
endfunc
func Test_file_changed_dialog()
- " requires a UI to be active
- throw 'Skipped: use test/functional/legacy/filechanged_spec.lua'
CheckUnix
CheckNotGui
au! FileChangedShell
@@ -200,8 +210,12 @@ func Test_file_changed_dialog()
new Xchanged_d
call setline(1, 'reload this')
write
- " Need to wait until the timestamp would change by at least a second.
- sleep 2
+ " Need to wait until the timestamp would change.
+ if has('nanotime')
+ sleep 10m
+ else
+ sleep 2
+ endif
silent !echo 'extra line' >>Xchanged_d
call feedkeys('L', 'L')
checktime
@@ -236,7 +250,11 @@ func Test_file_changed_dialog()
call assert_equal('new line', getline(1))
" Only time changed, no prompt
- sleep 2
+ if has('nanotime')
+ sleep 10m
+ else
+ sleep 2
+ endif
silent !touch Xchanged_d
let v:warningmsg = ''
checktime Xchanged_d
diff --git a/test/old/testdir/test_filetype.vim b/test/old/testdir/test_filetype.vim
index 303b1585e2..34fe93fd55 100644
--- a/test/old/testdir/test_filetype.vim
+++ b/test/old/testdir/test_filetype.vim
@@ -1,5 +1,16 @@
" Test :setfiletype
+func Test_backup_strip()
+ filetype on
+ let fname = 'Xdetect.js~~~~~~~~~~~'
+ call writefile(['one', 'two', 'three'], fname, 'D')
+ exe 'edit ' .. fname
+ call assert_equal('javascript', &filetype)
+
+ bwipe!
+ filetype off
+endfunc
+
func Test_detection()
filetype on
augroup filetypedetect
@@ -97,7 +108,7 @@ func s:GetFilenameChecks() abort
\ 'asterisk': ['asterisk/file.conf', 'asterisk/file.conf-file', 'some-asterisk/file.conf', 'some-asterisk/file.conf-file'],
\ 'astro': ['file.astro'],
\ 'atlas': ['file.atl', 'file.as'],
- \ 'authzed': ['file.zed'],
+ \ 'authzed': ['schema.zed'],
\ 'autohotkey': ['file.ahk'],
\ 'autoit': ['file.au3'],
\ 'automake': ['GNUmakefile.am', 'makefile.am', 'Makefile.am'],
@@ -116,11 +127,12 @@ func s:GetFilenameChecks() abort
\ 'blade': ['file.blade.php'],
\ 'blank': ['file.bl'],
\ 'blueprint': ['file.blp'],
+ \ 'bp': ['Android.bp'],
\ 'bsdl': ['file.bsd', 'file.bsdl'],
\ 'bst': ['file.bst'],
\ 'bzl': ['file.bazel', 'file.bzl', 'WORKSPACE', 'WORKSPACE.bzlmod'],
\ 'bzr': ['bzr_log.any', 'bzr_log.file'],
- \ 'c': ['enlightenment/file.cfg', 'file.qc', 'file.c', 'some-enlightenment/file.cfg'],
+ \ 'c': ['enlightenment/file.cfg', 'file.qc', 'file.c', 'some-enlightenment/file.cfg', 'file.mdh', 'file.epro'],
\ 'cabal': ['file.cabal'],
\ 'cabalconfig': ['cabal.config', expand("$HOME/.config/cabal/config")] + s:WhenConfigHome('$XDG_CONFIG_HOME/cabal/config'),
\ 'cabalproject': ['cabal.project', 'cabal.project.local'],
@@ -134,6 +146,7 @@ func s:GetFilenameChecks() abort
\ 'cf': ['file.cfm', 'file.cfi', 'file.cfc'],
\ 'cfengine': ['cfengine.conf'],
\ 'cfg': ['file.hgrc', 'filehgrc', 'hgrc', 'some-hgrc'],
+ \ 'cgdbrc': ['cgdbrc'],
\ 'ch': ['file.chf'],
\ 'chaiscript': ['file.chai'],
\ 'chaskell': ['file.chs'],
@@ -143,16 +156,17 @@ func s:GetFilenameChecks() abort
\ 'chuck': ['file.ck'],
\ 'cl': ['file.eni'],
\ 'clean': ['file.dcl', 'file.icl'],
- \ 'clojure': ['file.clj', 'file.cljs', 'file.cljx', 'file.cljc'],
+ \ 'clojure': ['file.clj', 'file.cljs', 'file.cljx', 'file.cljc', 'init.trans', 'any/etc/translate-shell', '.trans'],
\ 'cmake': ['CMakeLists.txt', 'file.cmake', 'file.cmake.in'],
+ \ 'cmakecache': ['CMakeCache.txt'],
\ 'cmod': ['file.cmod'],
\ 'cmusrc': ['any/.cmus/autosave', 'any/.cmus/rc', 'any/.cmus/command-history', 'any/.cmus/file.theme', 'any/cmus/rc', 'any/cmus/file.theme', '/.cmus/autosave', '/.cmus/command-history', '/.cmus/file.theme', '/.cmus/rc', '/cmus/file.theme', '/cmus/rc'],
\ 'cobol': ['file.cbl', 'file.cob', 'file.lib'],
\ 'coco': ['file.atg'],
\ 'conaryrecipe': ['file.recipe'],
- \ 'conf': ['auto.master', 'file.conf'],
+ \ 'conf': ['auto.master', 'file.conf', 'texdoc.cnf', '.x11vncrc', '.chktexrc', '.ripgreprc', 'ripgreprc', 'file.ctags', '.mbsyncrc'],
\ 'config': ['configure.in', 'configure.ac', '/etc/hostname.file', 'any/etc/hostname.file'],
- \ 'confini': ['/etc/pacman.conf', 'any/etc/pacman.conf', 'mpv.conf', 'any/.aws/config', 'any/.aws/credentials', 'file.nmconnection'],
+ \ 'confini': ['pacman.conf', 'paru.conf', 'mpv.conf', 'any/.aws/config', 'any/.aws/credentials', 'file.nmconnection'],
\ 'context': ['tex/context/any/file.tex', 'file.mkii', 'file.mkiv', 'file.mkvi', 'file.mkxl', 'file.mklx'],
\ 'cook': ['file.cook'],
\ 'corn': ['file.corn'],
@@ -179,6 +193,7 @@ func s:GetFilenameChecks() abort
\ 'cynpp': ['file.cyn'],
\ 'cypher': ['file.cypher'],
\ 'd': ['file.d'],
+ \ 'dafny': ['file.dfy'],
\ 'dart': ['file.dart', 'file.drt'],
\ 'datascript': ['file.ds'],
\ 'dcd': ['file.dcd'],
@@ -199,16 +214,24 @@ func s:GetFilenameChecks() abort
\ 'dnsmasq': ['/etc/dnsmasq.conf', '/etc/dnsmasq.d/file', 'any/etc/dnsmasq.conf', 'any/etc/dnsmasq.d/file'],
\ 'dockerfile': ['Containerfile', 'Dockerfile', 'dockerfile', 'file.Dockerfile', 'file.dockerfile', 'Dockerfile.debian', 'Containerfile.something'],
\ 'dosbatch': ['file.bat'],
- \ 'dosini': ['/etc/yum.conf', 'file.ini', 'npmrc', '.npmrc', 'php.ini', 'php.ini-5', 'php.ini-file', '/etc/yum.repos.d/file', 'any/etc/yum.conf', 'any/etc/yum.repos.d/file', 'file.wrap', 'file.vbp', 'ja2.ini', 'JA2.INI'],
+ \ 'dosini': ['/etc/yum.conf', '/etc/nfs.conf', '/etc/nfsmount.conf', 'file.ini',
+ \ 'npmrc', '.npmrc', 'php.ini', 'php.ini-5', 'php.ini-file',
+ \ '/etc/yum.repos.d/file', 'any/etc/yum.conf', 'any/etc/yum.repos.d/file', 'file.wrap',
+ \ 'file.vbp', 'ja2.ini', 'JA2.INI', 'mimeapps.list', 'pip.conf', 'setup.cfg', 'pudb.cfg',
+ \ '.coveragerc', '.pypirc', '.gitlint', '.oelint.cfg', 'pylintrc', '.pylintrc',
+ \ '/home/user/.config/bpython/config', '/home/user/.config/mypy/config', '.wakatime.cfg', '.replyrc',
+ \ 'psprint.conf', 'sofficerc', 'any/.config/lxqt/globalkeyshortcuts.conf', 'any/.config/screengrab/screengrab.conf',
+ \ 'any/.local/share/flatpak/repo/config', '.notmuch-config'],
\ 'dot': ['file.dot', 'file.gv'],
\ 'dracula': ['file.drac', 'file.drc', 'filelvs', 'filelpe', 'drac.file', 'lpe', 'lvs', 'some-lpe', 'some-lvs'],
\ 'dtd': ['file.dtd'],
\ 'dtrace': ['/usr/lib/dtrace/io.d'],
- \ 'dts': ['file.dts', 'file.dtsi', 'file.dtso', 'file.its'],
+ \ 'dts': ['file.dts', 'file.dtsi', 'file.dtso', 'file.its', 'file.keymap'],
\ 'dune': ['jbuild', 'dune', 'dune-project', 'dune-workspace'],
\ 'dylan': ['file.dylan'],
\ 'dylanintr': ['file.intr'],
\ 'dylanlid': ['file.lid'],
+ \ 'earthfile': ['Earthfile'],
\ 'ecd': ['file.ecd'],
\ 'edif': ['file.edf', 'file.edif', 'file.edo'],
\ 'editorconfig': ['.editorconfig'],
@@ -272,7 +295,7 @@ func s:GetFilenameChecks() abort
\ 'glsl': ['file.glsl'],
\ 'gn': ['file.gn', 'file.gni'],
\ 'gnash': ['gnashrc', '.gnashrc', 'gnashpluginrc', '.gnashpluginrc'],
- \ 'gnuplot': ['file.gpi', '.gnuplot'],
+ \ 'gnuplot': ['file.gpi', '.gnuplot', 'file.gnuplot', '.gnuplot_history'],
\ 'go': ['file.go'],
\ 'gomod': ['go.mod'],
\ 'gosum': ['go.sum', 'go.work.sum'],
@@ -301,7 +324,7 @@ func s:GetFilenameChecks() abort
\ 'hcl': ['file.hcl'],
\ 'heex': ['file.heex'],
\ 'hercules': ['file.vc', 'file.ev', 'file.sum', 'file.errsum'],
- \ 'hex': ['file.hex', 'file.h32'],
+ \ 'hex': ['file.hex', 'file.ihex', 'file.ihe', 'file.ihx', 'file.int', 'file.mcs', 'file.h32', 'file.h80', 'file.h86', 'file.a43', 'file.a90'],
\ 'hgcommit': ['hg-editor-file.txt'],
\ 'hjson': ['file.hjson'],
\ 'hlsplaylist': ['file.m3u', 'file.m3u8'],
@@ -314,6 +337,7 @@ func s:GetFilenameChecks() abort
\ 'htmlm4': ['file.html.m4'],
\ 'httest': ['file.htt', 'file.htb'],
\ 'hurl': ['file.hurl'],
+ \ 'hyprlang': ['hyprlock.conf', 'hyprland.conf', 'hypridle.conf', 'hyprpaper.conf'],
\ 'i3config': ['/home/user/.i3/config', '/home/user/.config/i3/config', '/etc/i3/config', '/etc/xdg/i3/config'],
\ 'ibasic': ['file.iba', 'file.ibi'],
\ 'icemenu': ['/.icewm/menu', 'any/.icewm/menu'],
@@ -322,6 +346,7 @@ func s:GetFilenameChecks() abort
\ 'inform': ['file.inf', 'file.INF'],
\ 'initng': ['/etc/initng/any/file.i', 'file.ii', 'any/etc/initng/any/file.i'],
\ 'inittab': ['inittab'],
+ \ 'inko': ['file.inko'],
\ 'ipfilter': ['ipf.conf', 'ipf6.conf', 'ipf.rules'],
\ 'iss': ['file.iss'],
\ 'ist': ['file.ist', 'file.mst'],
@@ -331,17 +356,18 @@ func s:GetFilenameChecks() abort
\ 'janet': ['file.janet'],
\ 'java': ['file.java', 'file.jav'],
\ 'javacc': ['file.jj', 'file.jjt'],
- \ 'javascript': ['file.js', 'file.jsm', 'file.javascript', 'file.es', 'file.mjs', 'file.cjs'],
+ \ 'javascript': ['file.js', 'file.jsm', 'file.javascript', 'file.es', 'file.mjs', 'file.cjs', '.node_repl_history'],
\ 'javascript.glimmer': ['file.gjs'],
\ 'javascriptreact': ['file.jsx'],
\ 'jess': ['file.clp'],
\ 'jgraph': ['file.jgr'],
+ \ 'jj': ['file.jjdescription'],
\ 'jq': ['file.jq'],
\ 'jovial': ['file.jov', 'file.j73', 'file.jovial'],
\ 'jproperties': ['file.properties', 'file.properties_xx', 'file.properties_xx_xx', 'some.properties_xx_xx_file', 'org.eclipse.xyz.prefs'],
- \ 'json': ['file.json', 'file.jsonp', 'file.json-patch', 'file.geojson', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb', '.prettierrc', '.firebaserc', '.stylelintrc', 'file.slnf'],
+ \ 'json': ['file.json', 'file.jsonp', 'file.json-patch', 'file.geojson', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb', 'file.jupyterlab-settings', '.prettierrc', '.firebaserc', '.stylelintrc', 'file.slnf', 'file.sublime-project', 'file.sublime-settings', 'file.sublime-workspace', 'file.bd', 'file.bda', 'file.xci', 'flake.lock'],
\ 'json5': ['file.json5'],
- \ 'jsonc': ['file.jsonc', '.babelrc', '.eslintrc', '.jsfmtrc', '.jshintrc', '.hintrc', '.swrc', 'jsconfig.json', 'tsconfig.json', 'tsconfig.test.json', 'tsconfig-test.json', '.luaurc'],
+ \ 'jsonc': ['file.jsonc', '.babelrc', '.eslintrc', '.jsfmtrc', '.jshintrc', '.jscsrc', '.vsconfig', '.hintrc', '.swrc', 'jsconfig.json', 'tsconfig.json', 'tsconfig.test.json', 'tsconfig-test.json', '.luaurc'],
\ 'jsonl': ['file.jsonl'],
\ 'jsonnet': ['file.jsonnet', 'file.libsonnet'],
\ 'jsp': ['file.jsp'],
@@ -357,7 +383,7 @@ func s:GetFilenameChecks() abort
\ 'kwt': ['file.k'],
\ 'lace': ['file.ace', 'file.ACE'],
\ 'latte': ['file.latte', 'file.lte'],
- \ 'ld': ['file.ld'],
+ \ 'ld': ['file.ld', 'any/usr/lib/aarch64-xilinx-linux/ldscripts/aarch64elf32b.x'],
\ 'ldif': ['file.ldif'],
\ 'lean': ['file.lean'],
\ 'ledger': ['file.ldg', 'file.ledger', 'file.journal'],
@@ -372,7 +398,7 @@ func s:GetFilenameChecks() abort
\ 'limits': ['/etc/limits', '/etc/anylimits.conf', '/etc/anylimits.d/file.conf', '/etc/limits.conf', '/etc/limits.d/file.conf', '/etc/some-limits.conf', '/etc/some-limits.d/file.conf', 'any/etc/limits', 'any/etc/limits.conf', 'any/etc/limits.d/file.conf', 'any/etc/some-limits.conf', 'any/etc/some-limits.d/file.conf'],
\ 'liquidsoap': ['file.liq'],
\ 'liquid': ['file.liquid'],
- \ 'lisp': ['file.lsp', 'file.lisp', 'file.asd', 'file.el', 'file.cl', '.emacs', '.sawfishrc', 'sbclrc', '.sbclrc'],
+ \ 'lisp': ['file.lsp', 'file.lisp', 'file.asd', 'file.el', 'file.cl', '.emacs', '.sawfishrc', 'sbclrc', '.sbclrc', 'file.stsg', 'any/local/share/supertux2/config'],
\ 'lite': ['file.lite', 'file.lt'],
\ 'litestep': ['/LiteStep/any/file.rc', 'any/LiteStep/any/file.rc'],
\ 'logcheck': ['/etc/logcheck/file.d-some/file', '/etc/logcheck/file.d/file', 'any/etc/logcheck/file.d-some/file', 'any/etc/logcheck/file.d/file'],
@@ -385,17 +411,17 @@ func s:GetFilenameChecks() abort
\ 'lpc': ['file.lpc', 'file.ulpc'],
\ 'lsl': ['file.lsl'],
\ 'lss': ['file.lss'],
- \ 'lua': ['file.lua', 'file.rockspec', 'file.nse', '.luacheckrc', '.busted'],
+ \ 'lua': ['file.lua', 'file.tlu', 'file.rockspec', 'file.nse', '.lua_history', '.luacheckrc', '.busted', 'rock_manifest', 'config.ld'],
\ 'luau': ['file.luau'],
\ 'lynx': ['lynx.cfg'],
\ 'lyrics': ['file.lrc'],
\ 'm3build': ['m3makefile', 'm3overrides'],
\ 'm3quake': ['file.quake', 'cm3.cfg'],
- \ 'm4': ['file.at'],
+ \ 'm4': ['file.at', '.m4_history'],
\ 'mail': ['snd.123', '.letter', '.letter.123', '.followup', '.article', '.article.123', 'pico.123', 'mutt-xx-xxx', 'muttng-xx-xxx', 'ae123.txt', 'file.eml', 'reportbug-file'],
\ 'mailaliases': ['/etc/mail/aliases', '/etc/aliases', 'any/etc/aliases', 'any/etc/mail/aliases'],
\ 'mailcap': ['.mailcap', 'mailcap'],
- \ 'make': ['file.mk', 'file.mak', 'file.dsp', 'makefile', 'Makefile', 'makefile-file', 'Makefile-file', 'some-makefile', 'some-Makefile'],
+ \ 'make': ['file.mk', 'file.mak', 'file.dsp', 'makefile', 'Makefile', 'makefile-file', 'Makefile-file', 'some-makefile', 'some-Makefile', 'Kbuild'],
\ 'mallard': ['file.page'],
"\ 'man': ['file.man'],
\ 'manconf': ['/etc/man.conf', 'man.config', 'any/etc/man.conf'],
@@ -410,13 +436,32 @@ func s:GetFilenameChecks() abort
\ 'mel': ['file.mel'],
\ 'mermaid': ['file.mmd', 'file.mmdc', 'file.mermaid'],
\ 'meson': ['meson.build', 'meson.options', 'meson_options.txt'],
- \ 'messages': ['/log/auth', '/log/cron', '/log/daemon', '/log/debug', '/log/kern', '/log/lpr', '/log/mail', '/log/messages', '/log/news/news', '/log/syslog', '/log/user',
- \ '/log/auth.log', '/log/cron.log', '/log/daemon.log', '/log/debug.log', '/log/kern.log', '/log/lpr.log', '/log/mail.log', '/log/messages.log', '/log/news/news.log', '/log/syslog.log', '/log/user.log',
- \ '/log/auth.err', '/log/cron.err', '/log/daemon.err', '/log/debug.err', '/log/kern.err', '/log/lpr.err', '/log/mail.err', '/log/messages.err', '/log/news/news.err', '/log/syslog.err', '/log/user.err',
- \ '/log/auth.info', '/log/cron.info', '/log/daemon.info', '/log/debug.info', '/log/kern.info', '/log/lpr.info', '/log/mail.info', '/log/messages.info', '/log/news/news.info', '/log/syslog.info', '/log/user.info',
- \ '/log/auth.warn', '/log/cron.warn', '/log/daemon.warn', '/log/debug.warn', '/log/kern.warn', '/log/lpr.warn', '/log/mail.warn', '/log/messages.warn', '/log/news/news.warn', '/log/syslog.warn', '/log/user.warn',
- \ '/log/auth.crit', '/log/cron.crit', '/log/daemon.crit', '/log/debug.crit', '/log/kern.crit', '/log/lpr.crit', '/log/mail.crit', '/log/messages.crit', '/log/news/news.crit', '/log/syslog.crit', '/log/user.crit',
- \ '/log/auth.notice', '/log/cron.notice', '/log/daemon.notice', '/log/debug.notice', '/log/kern.notice', '/log/lpr.notice', '/log/mail.notice', '/log/messages.notice', '/log/news/news.notice', '/log/syslog.notice', '/log/user.notice'],
+ \ 'messages': ['/log/auth', '/log/cron', '/log/daemon', '/log/debug',
+ \ '/log/kern', '/log/lpr', '/log/mail', '/log/messages',
+ \ '/log/news/news', '/log/syslog', '/log/user', '/log/auth.log',
+ \ '/log/cron.log', '/log/daemon.log', '/log/debug.log',
+ \ '/log/kern.log', '/log/lpr.log', '/log/mail.log',
+ \ '/log/messages.log', '/log/news/news.log', '/log/syslog.log',
+ \ '/log/user.log', '/log/auth.err', '/log/cron.err',
+ \ '/log/daemon.err', '/log/debug.err', '/log/kern.err',
+ \ '/log/lpr.err', '/log/mail.err', '/log/messages.err',
+ \ '/log/news/news.err', '/log/syslog.err', '/log/user.err',
+ \ '/log/auth.info', '/log/cron.info', '/log/daemon.info',
+ \ '/log/debug.info', '/log/kern.info', '/log/lpr.info',
+ \ '/log/mail.info', '/log/messages.info', '/log/news/news.info',
+ \ '/log/syslog.info', '/log/user.info', '/log/auth.warn',
+ \ '/log/cron.warn', '/log/daemon.warn', '/log/debug.warn',
+ \ '/log/kern.warn', '/log/lpr.warn', '/log/mail.warn',
+ \ '/log/messages.warn', '/log/news/news.warn',
+ \ '/log/syslog.warn', '/log/user.warn', '/log/auth.crit',
+ \ '/log/cron.crit', '/log/daemon.crit', '/log/debug.crit',
+ \ '/log/kern.crit', '/log/lpr.crit', '/log/mail.crit',
+ \ '/log/messages.crit', '/log/news/news.crit',
+ \ '/log/syslog.crit', '/log/user.crit', '/log/auth.notice',
+ \ '/log/cron.notice', '/log/daemon.notice', '/log/debug.notice',
+ \ '/log/kern.notice', '/log/lpr.notice', '/log/mail.notice',
+ \ '/log/messages.notice', '/log/news/news.notice',
+ \ '/log/syslog.notice', '/log/user.notice'],
\ 'mf': ['file.mf'],
\ 'mgl': ['file.mgl'],
\ 'mgp': ['file.mgp'],
@@ -436,11 +481,23 @@ func s:GetFilenameChecks() abort
\ 'msidl': ['file.odl', 'file.mof'],
\ 'msql': ['file.msql'],
\ 'mojo': ['file.mojo', 'file.🔥'],
+ \ 'msmtp': ['.msmtprc'],
\ 'mupad': ['file.mu'],
\ 'mush': ['file.mush'],
\ 'mustache': ['file.mustache'],
- \ 'muttrc': ['Muttngrc', 'Muttrc', '.muttngrc', '.muttngrc-file', '.muttrc', '.muttrc-file', '/.mutt/muttngrc', '/.mutt/muttngrc-file', '/.mutt/muttrc', '/.mutt/muttrc-file', '/.muttng/muttngrc', '/.muttng/muttngrc-file', '/.muttng/muttrc', '/.muttng/muttrc-file', '/etc/Muttrc.d/file', '/etc/Muttrc.d/file.rc', 'Muttngrc-file', 'Muttrc-file', 'any/.mutt/muttngrc', 'any/.mutt/muttngrc-file', 'any/.mutt/muttrc', 'any/.mutt/muttrc-file', 'any/.muttng/muttngrc', 'any/.muttng/muttngrc-file', 'any/.muttng/muttrc', 'any/.muttng/muttrc-file', 'any/etc/Muttrc.d/file', 'muttngrc', 'muttngrc-file', 'muttrc', 'muttrc-file'],
- \ 'mysql': ['file.mysql'],
+ \ 'muttrc': ['Muttngrc', 'Muttrc', '.muttngrc', '.muttngrc-file', '.muttrc',
+ \ '.muttrc-file', '/.mutt/muttngrc', '/.mutt/muttngrc-file',
+ \ '/.mutt/muttrc', '/.mutt/muttrc-file', '/.muttng/muttngrc',
+ \ '/.muttng/muttngrc-file', '/.muttng/muttrc',
+ \ '/.muttng/muttrc-file', '/etc/Muttrc.d/file',
+ \ '/etc/Muttrc.d/file.rc', 'Muttngrc-file', 'Muttrc-file',
+ \ 'any/.mutt/muttngrc', 'any/.mutt/muttngrc-file',
+ \ 'any/.mutt/muttrc', 'any/.mutt/muttrc-file',
+ \ 'any/.muttng/muttngrc', 'any/.muttng/muttngrc-file',
+ \ 'any/.muttng/muttrc', 'any/.muttng/muttrc-file',
+ \ 'any/etc/Muttrc.d/file', 'muttngrc', 'muttngrc-file', 'muttrc',
+ \ 'muttrc-file'],
+ \ 'mysql': ['file.mysql', '.mysql_history'],
\ 'n1ql': ['file.n1ql', 'file.nql'],
\ 'named': ['namedfile.conf', 'rndcfile.conf', 'named-file.conf', 'named.conf', 'rndc-file.conf', 'rndc-file.key', 'rndc.conf', 'rndc.key'],
\ 'nanorc': ['/etc/nanorc', 'file.nanorc', 'any/etc/nanorc'],
@@ -462,9 +519,10 @@ func s:GetFilenameChecks() abort
\ 'obse': ['file.obl', 'file.obse', 'file.oblivion', 'file.obscript'],
\ 'ocaml': ['file.ml', 'file.mli', 'file.mll', 'file.mly', '.ocamlinit', 'file.mlt', 'file.mlp', 'file.mlip', 'file.mli.cppo', 'file.ml.cppo'],
\ 'occam': ['file.occ'],
- \ 'octave': ['octaverc', '.octaverc', 'octave.conf'],
+ \ 'octave': ['octaverc', '.octaverc', 'octave.conf', 'any/.local/share/octave/history'],
\ 'odin': ['file.odin'],
\ 'omnimark': ['file.xom', 'file.xin'],
+ \ 'ondir': ['.ondirrc'],
\ 'opam': ['opam', 'file.opam', 'file.opam.template'],
\ 'openroad': ['file.or'],
\ 'openscad': ['file.scad'],
@@ -475,10 +533,11 @@ func s:GetFilenameChecks() abort
\ 'pacmanlog': ['pacman.log'],
\ 'pamconf': ['/etc/pam.conf', '/etc/pam.d/file', 'any/etc/pam.conf', 'any/etc/pam.d/file'],
\ 'pamenv': ['/etc/security/pam_env.conf', '/home/user/.pam_environment', '.pam_environment', 'pam_env.conf'],
+ \ 'pandoc': ['file.pandoc', 'file.pdk', 'file.pd', 'file.pdc'],
\ 'papp': ['file.papp', 'file.pxml', 'file.pxsl'],
\ 'pascal': ['file.pas', 'file.dpr', 'file.lpr'],
\ 'passwd': ['any/etc/passwd', 'any/etc/passwd-', 'any/etc/passwd.edit', 'any/etc/shadow', 'any/etc/shadow-', 'any/etc/shadow.edit', 'any/var/backups/passwd.bak', 'any/var/backups/shadow.bak', '/etc/passwd', '/etc/passwd-', '/etc/passwd.edit', '/etc/shadow', '/etc/shadow-', '/etc/shadow.edit', '/var/backups/passwd.bak', '/var/backups/shadow.bak'],
- \ 'pbtxt': ['file.pbtxt'],
+ \ 'pbtxt': ['file.txtpb', 'file.textproto', 'file.textpb', 'file.pbtxt'],
\ 'pccts': ['file.g'],
\ 'pcmk': ['file.pcmk'],
\ 'pdf': ['file.pdf'],
@@ -519,16 +578,17 @@ func s:GetFilenameChecks() abort
\ 'psl': ['file.psl'],
\ 'pug': ['file.pug'],
\ 'puppet': ['file.pp'],
+ \ 'purescript': ['file.purs'],
\ 'pymanifest': ['MANIFEST.in'],
\ 'pyret': ['file.arr'],
\ 'pyrex': ['file.pyx', 'file.pxd'],
- \ 'python': ['file.py', 'file.pyw', '.pythonstartup', '.pythonrc', 'file.ptl', 'file.pyi', 'SConstruct'],
+ \ 'python': ['file.py', 'file.pyw', '.pythonstartup', '.pythonrc', '.python_history', '.jline-jython.history', 'file.ptl', 'file.pyi', 'SConstruct'],
\ 'ql': ['file.ql', 'file.qll'],
\ 'qml': ['file.qml', 'file.qbs'],
\ 'qmldir': ['qmldir'],
\ 'quake': ['anybaseq2/file.cfg', 'anyid1/file.cfg', 'quake3/file.cfg', 'baseq2/file.cfg', 'id1/file.cfg', 'quake1/file.cfg', 'some-baseq2/file.cfg', 'some-id1/file.cfg', 'some-quake1/file.cfg'],
\ 'quarto': ['file.qmd'],
- \ 'r': ['file.r', '.Rprofile', 'Rprofile', 'Rprofile.site'],
+ \ 'r': ['file.r', '.Rhistory', '.Rprofile', 'Rprofile', 'Rprofile.site'],
\ 'racket': ['file.rkt', 'file.rktd', 'file.rktl'],
\ 'radiance': ['file.rad', 'file.mat'],
\ 'raku': ['file.pm6', 'file.p6', 'file.t6', 'file.pod6', 'file.raku', 'file.rakumod', 'file.rakudoc', 'file.rakutest'],
@@ -540,7 +600,7 @@ func s:GetFilenameChecks() abort
\ 'readline': ['.inputrc', 'inputrc'],
\ 'rego': ['file.rego'],
\ 'remind': ['.reminders', 'file.remind', 'file.rem', '.reminders-file'],
- \ 'requirements': ['file.pip', 'requirements.txt'],
+ \ 'requirements': ['file.pip', 'requirements.txt', 'dev-requirements.txt', 'constraints.txt', 'requirements.in', 'requirements/dev.txt', 'requires/dev.txt'],
\ 'rescript': ['file.res', 'file.resi'],
\ 'resolv': ['resolv.conf'],
\ 'reva': ['file.frt'],
@@ -554,6 +614,7 @@ func s:GetFilenameChecks() abort
\ 'rpgle': ['file.rpgle', 'file.rpgleinc'],
\ 'robot': ['file.robot', 'file.resource'],
\ 'robots': ['robots.txt'],
+ \ 'roc': ['file.roc'],
\ 'ron': ['file.ron'],
\ 'routeros': ['file.rsc'],
\ 'rpcgen': ['file.x'],
@@ -561,7 +622,7 @@ func s:GetFilenameChecks() abort
\ 'rrst': ['file.rrst', 'file.srst'],
\ 'rst': ['file.rst'],
\ 'rtf': ['file.rtf'],
- \ 'ruby': ['.irbrc', 'irbrc', 'file.rb', 'file.rbw', 'file.gemspec', 'file.ru', 'Gemfile', 'file.builder', 'file.rxml', 'file.rjs', 'file.rant', 'file.rake', 'rakefile', 'Rakefile', 'rantfile', 'Rantfile', 'rakefile-file', 'Rakefile-file', 'Puppetfile', 'Vagrantfile'],
+ \ 'ruby': ['.irbrc', 'irbrc', '.irb_history', 'irb_history', 'file.rb', 'file.rbw', 'file.gemspec', 'file.ru', 'Gemfile', 'file.builder', 'file.rxml', 'file.rjs', 'file.rant', 'file.rake', 'rakefile', 'Rakefile', 'rantfile', 'Rantfile', 'rakefile-file', 'Rakefile-file', 'Puppetfile', 'Vagrantfile'],
\ 'rust': ['file.rs'],
\ 'samba': ['smb.conf'],
\ 'sas': ['file.sas'],
@@ -581,7 +642,10 @@ func s:GetFilenameChecks() abort
\ 'services': ['/etc/services', 'any/etc/services'],
\ 'setserial': ['/etc/serial.conf', 'any/etc/serial.conf'],
\ 'sexplib': ['file.sexp'],
- \ 'sh': ['.bashrc', '.bash_profile', '.bash-profile', '.bash_logout', '.bash-logout', '.bash_aliases', '.bash-aliases', '/tmp/bash-fc-3Ozjlw', '/tmp/bash-fc.3Ozjlw', 'PKGBUILD', 'APKBUILD', 'file.bash', '/usr/share/doc/bash-completion/filter.sh', '/etc/udev/cdsymlinks.conf', 'any/etc/udev/cdsymlinks.conf', 'file.bats'],
+ \ 'sh': ['.bashrc', '.bash_profile', '.bash-profile', '.bash_logout', '.bash-logout', '.bash_aliases', '.bash-aliases', '.bash_history', '.bash-history',
+ \ '/tmp/bash-fc-3Ozjlw', '/tmp/bash-fc.3Ozjlw', 'PKGBUILD', 'APKBUILD', 'file.bash', '/usr/share/doc/bash-completion/filter.sh',
+ \ '/etc/udev/cdsymlinks.conf', 'any/etc/udev/cdsymlinks.conf', 'file.bats', '.ash_history', 'any/etc/neofetch/config.conf', '.xprofile',
+ \ 'user-dirs.defaults', 'user-dirs.dirs', 'makepkg.conf', '.makepkg.conf', 'file.mdd', 'file.cygport'],
\ 'sieve': ['file.siv', 'file.sieve'],
\ 'sil': ['file.sil'],
\ 'simula': ['file.sim'],
@@ -592,6 +656,7 @@ func s:GetFilenameChecks() abort
\ 'slang': ['file.sl'],
\ 'sage': ['file.sage'],
\ 'slice': ['file.ice'],
+ \ 'slint': ['file.slint'],
\ 'slpconf': ['/etc/slp.conf', 'any/etc/slp.conf'],
\ 'slpreg': ['/etc/slp.reg', 'any/etc/slp.reg'],
\ 'slpspi': ['/etc/slp.spi', 'any/etc/slp.spi'],
@@ -612,7 +677,7 @@ func s:GetFilenameChecks() abort
\ 'spice': ['file.sp', 'file.spice'],
\ 'spup': ['file.speedup', 'file.spdata', 'file.spd'],
\ 'spyce': ['file.spy', 'file.spi'],
- \ 'sql': ['file.tyb', 'file.tyc', 'file.pkb', 'file.pks'],
+ \ 'sql': ['file.tyb', 'file.tyc', 'file.pkb', 'file.pks', '.sqlite_history'],
\ 'sqlj': ['file.sqlj'],
\ 'prql': ['file.prql'],
\ 'sqr': ['file.sqr', 'file.sqi'],
@@ -627,6 +692,7 @@ func s:GetFilenameChecks() abort
\ 'starlark': ['file.ipd', 'file.star', 'file.starlark'],
\ 'stata': ['file.ado', 'file.do', 'file.imata', 'file.mata'],
\ 'stp': ['file.stp'],
+ \ 'stylus': ['a.styl', 'file.stylus'],
\ 'sudoers': ['any/etc/sudoers', 'sudoers.tmp', '/etc/sudoers', 'any/etc/sudoers.d/file'],
\ 'supercollider': ['file.quark'],
\ 'surface': ['file.sface'],
@@ -638,7 +704,45 @@ func s:GetFilenameChecks() abort
\ 'swiftgyb': ['file.swift.gyb'],
\ 'swig': ['file.swg', 'file.swig'],
\ 'sysctl': ['/etc/sysctl.conf', '/etc/sysctl.d/file.conf', 'any/etc/sysctl.conf', 'any/etc/sysctl.d/file.conf'],
- \ 'systemd': ['any/systemd/file.automount', 'any/systemd/file.dnssd', 'any/systemd/file.link', 'any/systemd/file.mount', 'any/systemd/file.netdev', 'any/systemd/file.network', 'any/systemd/file.nspawn', 'any/systemd/file.path', 'any/systemd/file.service', 'any/systemd/file.slice', 'any/systemd/file.socket', 'any/systemd/file.swap', 'any/systemd/file.target', 'any/systemd/file.timer', '/etc/systemd/some.conf.d/file.conf', '/etc/systemd/system/some.d/file.conf', '/etc/systemd/system/some.d/.#file', '/etc/systemd/system/.#otherfile', '/home/user/.config/systemd/user/some.d/mine.conf', '/home/user/.config/systemd/user/some.d/.#file', '/home/user/.config/systemd/user/.#otherfile', '/.config/systemd/user/.#', '/.config/systemd/user/.#-file', '/.config/systemd/user/file.d/.#', '/.config/systemd/user/file.d/.#-file', '/.config/systemd/user/file.d/file.conf', '/etc/systemd/file.conf.d/file.conf', '/etc/systemd/system/.#', '/etc/systemd/system/.#-file', '/etc/systemd/system/file.d/.#', '/etc/systemd/system/file.d/.#-file', '/etc/systemd/system/file.d/file.conf', '/systemd/file.automount', '/systemd/file.dnssd', '/systemd/file.link', '/systemd/file.mount', '/systemd/file.netdev', '/systemd/file.network', '/systemd/file.nspawn', '/systemd/file.path', '/systemd/file.service', '/systemd/file.slice', '/systemd/file.socket', '/systemd/file.swap', '/systemd/file.target', '/systemd/file.timer', 'any/.config/systemd/user/.#', 'any/.config/systemd/user/.#-file', 'any/.config/systemd/user/file.d/.#', 'any/.config/systemd/user/file.d/.#-file', 'any/.config/systemd/user/file.d/file.conf', 'any/etc/systemd/file.conf.d/file.conf', 'any/etc/systemd/system/.#', 'any/etc/systemd/system/.#-file', 'any/etc/systemd/system/file.d/.#', 'any/etc/systemd/system/file.d/.#-file', 'any/etc/systemd/system/file.d/file.conf'],
+ \ 'systemd': ['any/systemd/file.automount', 'any/systemd/file.dnssd',
+ \ 'any/systemd/file.link', 'any/systemd/file.mount',
+ \ 'any/systemd/file.netdev', 'any/systemd/file.network',
+ \ 'any/systemd/file.nspawn', 'any/systemd/file.path',
+ \ 'any/systemd/file.service', 'any/systemd/file.slice',
+ \ 'any/systemd/file.socket', 'any/systemd/file.swap',
+ \ 'any/systemd/file.target', 'any/systemd/file.timer',
+ \ '/etc/systemd/some.conf.d/file.conf',
+ \ '/etc/systemd/system/some.d/file.conf',
+ \ '/etc/systemd/system/some.d/.#file',
+ \ '/etc/systemd/system/.#otherfile',
+ \ '/home/user/.config/systemd/user/some.d/mine.conf',
+ \ '/home/user/.config/systemd/user/some.d/.#file',
+ \ '/home/user/.config/systemd/user/.#otherfile',
+ \ '/.config/systemd/user/.#', '/.config/systemd/user/.#-file',
+ \ '/.config/systemd/user/file.d/.#',
+ \ '/.config/systemd/user/file.d/.#-file',
+ \ '/.config/systemd/user/file.d/file.conf',
+ \ '/etc/systemd/file.conf.d/file.conf', '/etc/systemd/system/.#',
+ \ '/etc/systemd/system/.#-file', '/etc/systemd/system/file.d/.#',
+ \ '/etc/systemd/system/file.d/.#-file',
+ \ '/etc/systemd/system/file.d/file.conf',
+ \ '/systemd/file.automount', '/systemd/file.dnssd',
+ \ '/systemd/file.link', '/systemd/file.mount',
+ \ '/systemd/file.netdev', '/systemd/file.network',
+ \ '/systemd/file.nspawn', '/systemd/file.path',
+ \ '/systemd/file.service', '/systemd/file.slice',
+ \ '/systemd/file.socket', '/systemd/file.swap',
+ \ '/systemd/file.target', '/systemd/file.timer',
+ \ 'any/.config/systemd/user/.#',
+ \ 'any/.config/systemd/user/.#-file',
+ \ 'any/.config/systemd/user/file.d/.#',
+ \ 'any/.config/systemd/user/file.d/.#-file',
+ \ 'any/.config/systemd/user/file.d/file.conf',
+ \ 'any/etc/systemd/file.conf.d/file.conf',
+ \ 'any/etc/systemd/system/.#', 'any/etc/systemd/system/.#-file',
+ \ 'any/etc/systemd/system/file.d/.#',
+ \ 'any/etc/systemd/system/file.d/.#-file',
+ \ 'any/etc/systemd/system/file.d/file.conf'],
\ 'systemverilog': ['file.sv', 'file.svh'],
\ 'trace32': ['file.cmm', 'file.t32'],
\ 'tags': ['tags'],
@@ -646,14 +750,15 @@ func s:GetFilenameChecks() abort
\ 'tal': ['file.tal'],
\ 'taskdata': ['pending.data', 'completed.data', 'undo.data'],
\ 'taskedit': ['file.task'],
- \ 'tcl': ['file.tcl', 'file.tm', 'file.tk', 'file.itcl', 'file.itk', 'file.jacl', '.tclshrc', 'tclsh.rc', '.wishrc'],
+ \ 'tcl': ['file.tcl', 'file.tm', 'file.tk', 'file.itcl', 'file.itk', 'file.jacl', '.tclshrc', 'tclsh.rc', '.wishrc', '.tclsh-history', '.xsctcmdhistory', '.xsdbcmdhistory'],
\ 'tablegen': ['file.td'],
\ 'teal': ['file.tl'],
+ \ 'templ': ['file.templ'],
\ 'template': ['file.tmpl'],
\ 'teraterm': ['file.ttl'],
\ 'terminfo': ['file.ti'],
\ 'terraform-vars': ['file.tfvars'],
- \ 'tex': ['file.latex', 'file.sty', 'file.dtx', 'file.ltx', 'file.bbl'],
+ \ 'tex': ['file.latex', 'file.sty', 'file.dtx', 'file.ltx', 'file.bbl', 'any/.texlive/texmf-config/tex/latex/file/file.cfg', 'file.pgf', 'file.nlo', 'file.nls', 'file.thm', 'file.eps_tex', 'file.pygtex', 'file.pygstyle', 'file.clo', 'file.aux', 'file.brf', 'file.ind', 'file.lof', 'file.loe', 'file.nav', 'file.vrb', 'file.ins', 'file.tikz', 'file.bbx', 'file.cbx', 'file.beamer'],
\ 'texinfo': ['file.texinfo', 'file.texi', 'file.txi'],
\ 'texmf': ['texmf.cnf'],
\ 'text': ['file.text', 'file.txt', 'README', 'LICENSE', 'COPYING', 'AUTHORS', '/usr/share/doc/bash-completion/AUTHORS', '/etc/apt/apt.conf.d/README', '/etc/Muttrc.d/README'],
@@ -664,7 +769,7 @@ func s:GetFilenameChecks() abort
\ 'tla': ['file.tla'],
\ 'tli': ['file.tli'],
\ 'tmux': ['tmuxfile.conf', '.tmuxfile.conf', '.tmux-file.conf', '.tmux.conf', 'tmux-file.conf', 'tmux.conf', 'tmux.conf.local'],
- \ 'toml': ['file.toml', 'Gopkg.lock', 'Pipfile', '/home/user/.cargo/config'],
+ \ 'toml': ['file.toml', 'Gopkg.lock', 'Pipfile', '/home/user/.cargo/config', '.black'],
\ 'tpp': ['file.tpp'],
\ 'treetop': ['file.treetop'],
\ 'trustees': ['trustees.conf'],
@@ -674,9 +779,10 @@ func s:GetFilenameChecks() abort
\ 'tssop': ['file.tssop'],
\ 'tsv': ['file.tsv'],
\ 'twig': ['file.twig'],
- \ 'typescript': ['file.mts', 'file.cts'],
+ \ 'typescript': ['file.mts', 'file.cts', '.ts_node_repl_history'],
\ 'typescript.glimmer': ['file.gts'],
\ 'typescriptreact': ['file.tsx'],
+ \ 'typespec': ['file.tsp'],
\ 'ungrammar': ['file.ungram'],
\ 'uc': ['file.uc'],
\ 'udevconf': ['/etc/udev/udev.conf', 'any/etc/udev/udev.conf'],
@@ -700,12 +806,13 @@ func s:GetFilenameChecks() abort
\ 'vdmpp': ['file.vpp', 'file.vdmpp'],
\ 'vdmrt': ['file.vdmrt'],
\ 'vdmsl': ['file.vdm', 'file.vdmsl'],
+ \ 'vento': ['file.vto'],
\ 'vera': ['file.vr', 'file.vri', 'file.vrh'],
\ 'verilogams': ['file.va', 'file.vams'],
\ 'vgrindefs': ['vgrindefs'],
\ 'vhdl': ['file.hdl', 'file.vhd', 'file.vhdl', 'file.vbe', 'file.vst', 'file.vhdl_123', 'file.vho', 'some.vhdl_1', 'some.vhdl_1-file'],
\ 'vhs': ['file.tape'],
- \ 'vim': ['file.vim', '.exrc', '_exrc', 'some-vimrc', 'some-vimrc-file', 'vimrc', 'vimrc-file'],
+ \ 'vim': ['file.vim', '.exrc', '_exrc', 'some-vimrc', 'some-vimrc-file', 'vimrc', 'vimrc-file', '.netrwhist'],
\ 'viminfo': ['.viminfo', '_viminfo'],
\ 'vmasm': ['file.mar'],
\ 'voscm': ['file.cm'],
@@ -731,7 +838,7 @@ func s:GetFilenameChecks() abort
\ 'xinetd': ['/etc/xinetd.conf', '/etc/xinetd.d/file', 'any/etc/xinetd.conf', 'any/etc/xinetd.d/file'],
\ 'xkb': ['/usr/share/X11/xkb/compat/pc', '/usr/share/X11/xkb/geometry/pc', '/usr/share/X11/xkb/keycodes/evdev', '/usr/share/X11/xkb/symbols/pc', '/usr/share/X11/xkb/types/pc'],
\ 'xmath': ['file.msc', 'file.msf'],
- \ 'xml': ['/etc/blkid.tab', '/etc/blkid.tab.old', 'file.xmi', 'file.csproj', 'file.csproj.user', 'file.fsproj', 'file.fsproj.user', 'file.vbproj', 'file.vbproj.user', 'file.ui', 'file.tpm', '/etc/xdg/menus/file.menu', 'fglrxrc', 'file.xlf', 'file.xliff', 'file.xul', 'file.wsdl', 'file.wpl', 'any/etc/blkid.tab', 'any/etc/blkid.tab.old', 'any/etc/xdg/menus/file.menu', 'file.atom', 'file.rss', 'file.cdxml', 'file.psc1', 'file.mpd'],
+ \ 'xml': ['/etc/blkid.tab', '/etc/blkid.tab.old', 'file.xmi', 'file.csproj', 'file.csproj.user', 'file.fsproj', 'file.fsproj.user', 'file.vbproj', 'file.vbproj.user', 'file.ui', 'file.tpm', '/etc/xdg/menus/file.menu', 'fglrxrc', 'file.xlf', 'file.xliff', 'file.xul', 'file.wsdl', 'file.wpl', 'any/etc/blkid.tab', 'any/etc/blkid.tab.old', 'any/etc/xdg/menus/file.menu', 'file.atom', 'file.rss', 'file.cdxml', 'file.psc1', 'file.mpd', 'fonts.conf', 'file.xcu', 'file.xlb', 'file.xlc', 'file.xba', 'file.xpr', 'file.xpfm', 'file.spfm', 'file.bxml'],
\ 'xmodmap': ['anyXmodmap', 'Xmodmap', 'some-Xmodmap', 'some-xmodmap', 'some-xmodmap-file', 'xmodmap', 'xmodmap-file'],
\ 'xpm': ['file.xpm'],
\ 'xpm2': ['file.xpm2'],
@@ -740,24 +847,30 @@ func s:GetFilenameChecks() abort
\ 'xsd': ['file.xsd'],
\ 'xslt': ['file.xsl', 'file.xslt'],
\ 'yacc': ['file.yy', 'file.yxx', 'file.y++'],
- \ 'yaml': ['file.yaml', 'file.yml', 'file.eyaml', '.clangd', '.clang-format', '.clang-tidy'],
+ \ 'yaml': ['file.yaml', 'file.yml', 'file.eyaml', 'any/.bundle/config', '.clangd', '.clang-format', '.clang-tidy', 'file.mplstyle', 'matplotlibrc', 'yarn.lock'],
\ 'yang': ['file.yang'],
\ 'yuck': ['file.yuck'],
\ 'z8a': ['file.z8a'],
+ \ 'zathurarc': ['zathurarc'],
\ 'zig': ['file.zig', 'build.zig.zon'],
\ 'zimbu': ['file.zu'],
\ 'zimbutempl': ['file.zut'],
\ 'zserio': ['file.zs'],
- \ 'zsh': ['.zprofile', '/etc/zprofile', '.zfbfmarks', 'file.zsh', '.zcompdump', '.zlogin', '.zlogout', '.zshenv', '.zshrc', '.zcompdump-file', '.zlog', '.zlog-file', '.zsh', '.zsh-file', 'any/etc/zprofile', 'zlog', 'zlog-file', 'zsh', 'zsh-file'],
+ \ 'zsh': ['.zprofile', '/etc/zprofile', '.zfbfmarks', 'file.zsh', 'file.zsh-theme', 'file.zunit',
+ \ '.zcompdump', '.zlogin', '.zlogout', '.zshenv', '.zshrc', '.zsh_history',
+ \ '.zcompdump-file', '.zlog', '.zlog-file', '.zsh', '.zsh-file',
+ \ 'any/etc/zprofile', 'zlog', 'zlog-file', 'zsh', 'zsh-file'],
\
- \ 'help': [$VIMRUNTIME . '/doc/help.txt'],
+ \ 'help': [$VIMRUNTIME .. '/doc/help.txt'],
\ }
endfunc
-let s:filename_case_checks = {
+func s:GetFilenameCaseChecks() abort
+ return {
\ 'modula2': ['file.DEF'],
\ 'bzl': ['file.BUILD', 'BUILD', 'BUCK'],
\ }
+endfunc
func CheckItems(checks)
set noswapfile
@@ -792,26 +905,29 @@ func Test_filetype_detection()
filetype on
call CheckItems(s:GetFilenameChecks())
if has('fname_case')
- call CheckItems(s:filename_case_checks)
+ call CheckItems(s:GetFilenameCaseChecks())
endif
filetype off
endfunc
" Content lines that should not result in filetype detection
-let s:false_positive_checks = {
+func s:GetFalsePositiveChecks() abort
+ return {
\ '': [['test execve("/usr/bin/pstree", ["pstree"], 0x7ff0 /* 63 vars */) = 0']],
\ }
+endfunc
" Filetypes detected from the file contents by scripts.vim
-let s:script_checks = {
+func s:GetScriptChecks() abort
+ return {
\ 'virata': [['% Virata'],
- \ ['', '% Virata'],
- \ ['', '', '% Virata'],
- \ ['', '', '', '% Virata'],
- \ ['', '', '', '', '% Virata']],
+ \ ['', '% Virata'],
+ \ ['', '', '% Virata'],
+ \ ['', '', '', '% Virata'],
+ \ ['', '', '', '', '% Virata']],
\ 'strace': [['execve("/usr/bin/pstree", ["pstree"], 0x7ff0 /* 63 vars */) = 0'],
- \ ['15:17:47 execve("/usr/bin/pstree", ["pstree"], ... "_=/usr/bin/strace"]) = 0'],
- \ ['__libc_start_main and something']],
+ \ ['15:17:47 execve("/usr/bin/pstree", ["pstree"], ... "_=/usr/bin/strace"]) = 0'],
+ \ ['__libc_start_main and something']],
\ 'clojure': [['#!/path/clojure']],
\ 'scala': [['#!/path/scala']],
\ 'sh': [['#!/path/sh'],
@@ -875,9 +991,11 @@ let s:script_checks = {
\ 'janet': [['#!/path/janet']],
\ 'dart': [['#!/path/dart']],
\ }
+endfunc
" Various forms of "env" optional arguments.
-let s:script_env_checks = {
+func s:GetScriptEnvChecks() abort
+ return {
\ 'perl': [['#!/usr/bin/env VAR=val perl']],
\ 'scala': [['#!/usr/bin/env VAR=val VVAR=vval scala']],
\ 'awk': [['#!/usr/bin/env VAR=val -i awk']],
@@ -887,6 +1005,7 @@ let s:script_env_checks = {
\ 'wml': [['#!/usr/bin/env VAR=val --split-string wml']],
\ 'nix': [['#!/usr/bin/env nix-shell']],
\ }
+endfunc
func Run_script_detection(test_dict)
filetype on
@@ -902,9 +1021,9 @@ func Run_script_detection(test_dict)
endfunc
func Test_script_detection()
- call Run_script_detection(s:false_positive_checks)
- call Run_script_detection(s:script_checks)
- call Run_script_detection(s:script_env_checks)
+ call Run_script_detection(s:GetFalsePositiveChecks())
+ call Run_script_detection(s:GetScriptChecks())
+ call Run_script_detection(s:GetScriptEnvChecks())
endfunc
func Test_setfiletype_completion()
@@ -1570,14 +1689,14 @@ func Test_mod_file()
call assert_equal('pim', b:modula2.dialect)
bwipe!
- " Modula-2 program MODULE with priorty (and uppercase extension)
+ " Modula-2 program MODULE with priority (and uppercase extension)
call writefile(['MODULE Module2Mod [42];'], 'Xfile.MOD')
split Xfile.MOD
call assert_equal('modula2', &filetype)
call assert_equal('pim', b:modula2.dialect)
bwipe!
- " Modula-2 implementation MODULE with priorty (and uppercase extension)
+ " Modula-2 implementation MODULE with priority (and uppercase extension)
call writefile(['IMPLEMENTATION MODULE Module2Mod [42];'], 'Xfile.MOD')
split Xfile.MOD
call assert_equal('modula2', &filetype)
@@ -2328,4 +2447,26 @@ func Test_def_file()
filetype off
endfunc
+func Test_uci_file()
+ filetype on
+
+ call mkdir('any/etc/config', 'pR')
+ call writefile(['config firewall'], 'any/etc/config/firewall', 'D')
+ split any/etc/config/firewall
+ call assert_equal('uci', &filetype)
+ bwipe!
+
+ call writefile(['# config for nginx here'], 'any/etc/config/firewall', 'D')
+ split any/etc/config/firewall
+ call assert_notequal('uci', &filetype)
+ bwipe!
+
+ call writefile(['# Copyright Cool Cats 1997', 'config firewall'], 'any/etc/config/firewall', 'D')
+ split any/etc/config/firewall
+ call assert_equal('uci', &filetype)
+ bwipe!
+
+ filetype off
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_format.vim b/test/old/testdir/test_format.vim
index d3578e7165..36795c87ea 100644
--- a/test/old/testdir/test_format.vim
+++ b/test/old/testdir/test_format.vim
@@ -105,67 +105,6 @@ func Test_printf_pos_misc()
END
call CheckLegacyAndVim9Success(lines)
- call CheckLegacyAndVim9Failure(["call printf('%1$d%2$d', 1, 3, 4)"], "E767:")
-
- call CheckLegacyAndVim9Failure(["call printf('%2$d%d', 1, 3)"], "E1500:")
- call CheckLegacyAndVim9Failure(["call printf('%d%2$d', 1, 3)"], "E1500:")
- call CheckLegacyAndVim9Failure(["call printf('%2$*1$d%d', 1, 3)"], "E1500:")
- call CheckLegacyAndVim9Failure(["call printf('%d%2$*1$d', 1, 3)"], "E1500:")
- call CheckLegacyAndVim9Failure(["call printf('%2$.*1$d%d', 1, 3)"], "E1500:")
- call CheckLegacyAndVim9Failure(["call printf('%d%2$.*1$d', 1, 3)"], "E1500:")
- call CheckLegacyAndVim9Failure(["call printf('%1$%')"], "E1500:")
- call CheckLegacyAndVim9Failure(["call printf('%1$')"], "E1500:")
- call CheckLegacyAndVim9Failure(["call printf('%1$_')"], "E1500:")
- call CheckLegacyAndVim9Failure(["call printf('%1$*3$.*d', 3)"], "E1500:")
- call CheckLegacyAndVim9Failure(["call printf('%1$*.*2$d', 3)"], "E1500:")
- call CheckLegacyAndVim9Failure(["call printf('%1$*.*d', 3)"], "E1500:")
- call CheckLegacyAndVim9Failure(["call printf('%*.*1$d', 3)"], "E1500:")
- call CheckLegacyAndVim9Failure(["call printf('%*1$.*d', 3)"], "E1500:")
- call CheckLegacyAndVim9Failure(["call printf('%*1$.*1$d', 3)"], "E1500:")
-
- call CheckLegacyAndVim9Failure(["call printf('%2$d', 3, 3)"], "E1501:")
-
- call CheckLegacyAndVim9Failure(["call printf('%2$*1$d %1$ld', 3, 3)"], "E1502:")
- call CheckLegacyAndVim9Failure(["call printf('%1$s %1$*1$d', 3)"], "E1502:")
- call CheckLegacyAndVim9Failure(["call printf('%1$p %1$*1$d', 3)"], "E1502:")
- call CheckLegacyAndVim9Failure(["call printf('%1$f %1$*1$d', 3)"], "E1502:")
- call CheckLegacyAndVim9Failure(["call printf('%1$lud %1$*1$d', 3)"], "E1502:")
- call CheckLegacyAndVim9Failure(["call printf('%1$llud %1$*1$d', 3)"], "E1502:")
- call CheckLegacyAndVim9Failure(["call printf('%1$lld %1$*1$d', 3)"], "E1502:")
- call CheckLegacyAndVim9Failure(["call printf('%1$s %1$*1$d', 3)"], "E1502:")
- call CheckLegacyAndVim9Failure(["call printf('%1$c %1$*1$d', 3)"], "E1502:")
- call CheckLegacyAndVim9Failure(["call printf('%1$ld %1$*1$d', 3)"], "E1502:")
- call CheckLegacyAndVim9Failure(["call printf('%1$ld %2$*1$d', 3, 3)"], "E1502:")
- call CheckLegacyAndVim9Failure(["call printf('%1$*1$ld', 3)"], "E1502:")
- call CheckLegacyAndVim9Failure(["call printf('%1$*1$.*1$ld', 3)"], "E1502:")
-
- call CheckLegacyAndVim9Failure(["call printf('%1$d%2$d', 3)"], "E1503:")
-
- call CheckLegacyAndVim9Failure(["call printf('%1$d %1$s', 3)"], "E1504:")
- call CheckLegacyAndVim9Failure(["call printf('%1$ld %1$s', 3)"], "E1504:")
- call CheckLegacyAndVim9Failure(["call printf('%1$ud %1$d', 3)"], "E1504:")
- call CheckLegacyAndVim9Failure(["call printf('%1$s %1$f', 3.0)"], "E1504:")
- call CheckLegacyAndVim9Failure(["call printf('%1$*1$d %1$ld', 3)"], "E1504:")
- call CheckLegacyAndVim9Failure(["call printf('%1$s %1$d', 3)"], "E1504:")
- call CheckLegacyAndVim9Failure(["call printf('%1$p %1$d', 3)"], "E1504:")
- call CheckLegacyAndVim9Failure(["call printf('%1$f %1$d', 3)"], "E1504:")
- call CheckLegacyAndVim9Failure(["call printf('%1$lud %1$d', 3)"], "E1504:")
- call CheckLegacyAndVim9Failure(["call printf('%1$llud %1$d', 3)"], "E1504:")
- call CheckLegacyAndVim9Failure(["call printf('%1$lld %1$d', 3)"], "E1504:")
- call CheckLegacyAndVim9Failure(["call printf('%1$s %1$d', 3)"], "E1504:")
- call CheckLegacyAndVim9Failure(["call printf('%1$c %1$d', 3)"], "E1504:")
- call CheckLegacyAndVim9Failure(["call printf('%1$ld %1$d', 3)"], "E1504:")
-
- call CheckLegacyAndVim9Failure(["call printf('%1$.2$d', 3)"], "E1505:")
- call CheckLegacyAndVim9Failure(["call printf('%01$d', 3)"], "E1505:")
- call CheckLegacyAndVim9Failure(["call printf('%01$0d', 3)"], "E1505:")
- call CheckLegacyAndVim9Failure(["call printf('%1$*2d', 3)"], "E1505:")
- call CheckLegacyAndVim9Failure(["call printf('%1$*3.*2$d', 3)"], "E1505:")
- call CheckLegacyAndVim9Failure(["call printf('%1$*3$.2$d', 3)"], "E1505:")
- call CheckLegacyAndVim9Failure(["call printf('%1$*3$.*2d', 3)"], "E1505:")
- call CheckLegacyAndVim9Failure(["call printf('%1$1$.5d', 5)"], "E1505:")
- call CheckLegacyAndVim9Failure(["call printf('%1$5.1$d', 5)"], "E1505:")
- call CheckLegacyAndVim9Failure(["call printf('%1$1$.1$d', 5)"], "E1505:")
endfunc
func Test_printf_pos_float()
@@ -287,8 +226,6 @@ func Test_printf_pos_float()
call assert_equal("str2float('nan')", printf('%1$S', -0.0 / 0.0))
END
call CheckLegacyAndVim9Success(lines)
-
- call CheckLegacyAndVim9Failure(['echo printf("%f", "a")'], 'E807:')
endfunc
func Test_printf_pos_errors()
@@ -299,6 +236,111 @@ func Test_printf_pos_errors()
call CheckLegacyAndVim9Failure(['echo printf("%1$s")'], 'E1503:')
call CheckLegacyAndVim9Failure(['echo printf("%1$d", 1.2)'], 'E805:')
call CheckLegacyAndVim9Failure(['echo printf("%1$f")'], 'E1503:')
+
+ call CheckLegacyAndVim9Failure(['echo printf("%f", "a")'], 'E807:')
+
+ call CheckLegacyAndVim9Failure(["call printf('%1$d%2$d', 1, 3, 4)"], "E767:")
+
+ call CheckLegacyAndVim9Failure(["call printf('%2$d%d', 1, 3)"], "E1500:")
+ call CheckLegacyAndVim9Failure(["call printf('%d%2$d', 1, 3)"], "E1500:")
+ call CheckLegacyAndVim9Failure(["call printf('%2$*1$d%d', 1, 3)"], "E1500:")
+ call CheckLegacyAndVim9Failure(["call printf('%d%2$*1$d', 1, 3)"], "E1500:")
+ call CheckLegacyAndVim9Failure(["call printf('%2$.*1$d%d', 1, 3)"], "E1500:")
+ call CheckLegacyAndVim9Failure(["call printf('%d%2$.*1$d', 1, 3)"], "E1500:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$%')"], "E1500:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$')"], "E1500:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$_')"], "E1500:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*3$.*d', 3)"], "E1500:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*.*2$d', 3)"], "E1500:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*.*d', 3)"], "E1500:")
+ call CheckLegacyAndVim9Failure(["call printf('%*.*1$d', 3)"], "E1500:")
+ call CheckLegacyAndVim9Failure(["call printf('%*1$.*d', 3)"], "E1500:")
+ call CheckLegacyAndVim9Failure(["call printf('%*1$.*1$d', 3)"], "E1500:")
+
+ call CheckLegacyAndVim9Failure(["call printf('%2$d', 3, 3)"], "E1501:")
+
+ call CheckLegacyAndVim9Failure(["call printf('%2$*1$d %1$ld', 3, 3)"], "E1502:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$s %1$*1$d', 3)"], "E1502:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$p %1$*1$d', 3)"], "E1502:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$f %1$*1$d', 3)"], "E1502:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$lud %1$*1$d', 3)"], "E1502:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$llud %1$*1$d', 3)"], "E1502:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$lld %1$*1$d', 3)"], "E1502:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$s %1$*1$d', 3)"], "E1502:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$c %1$*1$d', 3)"], "E1502:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$ld %1$*1$d', 3)"], "E1502:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$ld %2$*1$d', 3, 3)"], "E1502:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*1$ld', 3)"], "E1502:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*1$.*1$ld', 3)"], "E1502:")
+
+ call CheckLegacyAndVim9Failure(["call printf('%1$d%2$d', 3)"], "E1503:")
+
+ call CheckLegacyAndVim9Failure(["call printf('%1$d %1$s', 3)"], "E1504:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$ld %1$s', 3)"], "E1504:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$ud %1$d', 3)"], "E1504:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$s %1$f', 3.0)"], "E1504:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*1$d %1$ld', 3)"], "E1504:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$s %1$d', 3)"], "E1504:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$p %1$d', 3)"], "E1504:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$f %1$d', 3)"], "E1504:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$lud %1$d', 3)"], "E1504:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$llud %1$d', 3)"], "E1504:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$lld %1$d', 3)"], "E1504:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$s %1$d', 3)"], "E1504:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$c %1$d', 3)"], "E1504:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$ld %1$d', 3)"], "E1504:")
+
+ call CheckLegacyAndVim9Failure(["call printf('%1$.2$d', 3)"], "E1505:")
+ call CheckLegacyAndVim9Failure(["call printf('%01$d', 3)"], "E1505:")
+ call CheckLegacyAndVim9Failure(["call printf('%01$0d', 3)"], "E1505:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*2d', 3)"], "E1505:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*3.*2$d', 3)"], "E1505:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*3$.2$d', 3)"], "E1505:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*3$.*2d', 3)"], "E1505:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$1$.5d', 5)"], "E1505:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$5.1$d', 5)"], "E1505:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$1$.1$d', 5)"], "E1505:")
+
+ call CheckLegacyAndVim9Failure(["call printf('%.123456789$d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%.123456789d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%123456789$d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%123456789d', 5)"], "E1510:")
+
+ call CheckLegacyAndVim9Failure(["call printf('%123456789$5.5d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$123456789.5d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$5.123456789d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%123456789$987654321.5d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$123456789.987654321d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%123456789$5.987654321d', 5)"], "E1510:")
+
+ call CheckLegacyAndVim9Failure(["call printf('%123456789$*1$.5d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*123456789$.5d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*1$.123456789d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%123456789$*987654321$.5d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*123456789$.987654321d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%123456789$*1$.987654321d', 5)"], "E1510:")
+
+ call CheckLegacyAndVim9Failure(["call printf('%123456789$5.*1$d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$123456789.*1$d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$5.*123456789$d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%123456789$987654321.*1$d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$123456789.*987654321$d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%123456789$5.*987654321$d', 5)"], "E1510:")
+
+ call CheckLegacyAndVim9Failure(["call printf('%123456789$*1$.*1$d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*123456789$.*1$d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*1$.*123456789d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%123456789$*987654321$.*1$d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*123456789$.*987654321$d', 5)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%123456789$*1$.*987654321$d', 5)"], "E1510:")
+
+ call CheckLegacyAndVim9Failure(["call printf('%1$*2$.*1$d', 5, 9999)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*1$.*2$d', 5, 9999)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%2$*3$.*1$d', 5, 9123, 9321)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%1$*2$.*3$d', 5, 9123, 9321)"], "E1510:")
+ call CheckLegacyAndVim9Failure(["call printf('%2$*1$.*3$d', 5, 9123, 9312)"], "E1510:")
+
+ call CheckLegacyAndVim9Failure(["call printf('%1$*2$d', 5, 9999)"], "E1510:")
endfunc
func Test_printf_pos_64bit()
diff --git a/test/old/testdir/test_functions.vim b/test/old/testdir/test_functions.vim
index 3f9ac94782..18d0d9aa5d 100644
--- a/test/old/testdir/test_functions.vim
+++ b/test/old/testdir/test_functions.vim
@@ -98,6 +98,11 @@ func Test_err_teapot()
call assert_fails('call err_teapot(expr)', "E503: Coffee is currently not available")
endfunc
+func Test_islocked()
+ call assert_fails('call islocked(99)', 'E475:')
+ call assert_fails('call islocked("s: x")', 'E488:')
+endfunc
+
func Test_len()
call assert_equal(1, len(0))
call assert_equal(2, len(12))
@@ -2590,8 +2595,6 @@ endfunc
" Test confirm({msg} [, {choices} [, {default} [, {type}]]])
func Test_confirm()
- " requires a UI to be active
- throw 'Skipped: use test/functional/vimscript/input_spec.lua'
CheckUnix
CheckNotGui
@@ -3401,6 +3404,73 @@ func Test_getmousepos()
\ column: 8,
\ coladd: 21,
\ }, getmousepos())
+
+ 30vnew
+ setlocal smoothscroll number
+ call setline(1, join(range(100)))
+ exe "normal! \<C-E>"
+ call Ntest_setmouse(1, 5)
+ call assert_equal(#{
+ \ screenrow: 1,
+ \ screencol: 5,
+ \ winid: win_getid(),
+ \ winrow: 1,
+ \ wincol: 5,
+ \ line: 1,
+ \ column: 27,
+ \ coladd: 0,
+ \ }, getmousepos())
+ call Ntest_setmouse(2, 5)
+ call assert_equal(#{
+ \ screenrow: 2,
+ \ screencol: 5,
+ \ winid: win_getid(),
+ \ winrow: 2,
+ \ wincol: 5,
+ \ line: 1,
+ \ column: 53,
+ \ coladd: 0,
+ \ }, getmousepos())
+
+ exe "normal! \<C-E>"
+ call Ntest_setmouse(1, 5)
+ call assert_equal(#{
+ \ screenrow: 1,
+ \ screencol: 5,
+ \ winid: win_getid(),
+ \ winrow: 1,
+ \ wincol: 5,
+ \ line: 1,
+ \ column: 53,
+ \ coladd: 0,
+ \ }, getmousepos())
+ call Ntest_setmouse(2, 5)
+ call assert_equal(#{
+ \ screenrow: 2,
+ \ screencol: 5,
+ \ winid: win_getid(),
+ \ winrow: 2,
+ \ wincol: 5,
+ \ line: 1,
+ \ column: 79,
+ \ coladd: 0,
+ \ }, getmousepos())
+
+ vert resize 4
+ call Ntest_setmouse(2, 2)
+ " This used to crash Vim
+ call assert_equal(#{
+ \ screenrow: 2,
+ \ screencol: 2,
+ \ winid: win_getid(),
+ \ winrow: 2,
+ \ wincol: 2,
+ \ line: 1,
+ \ column: 53,
+ \ coladd: 0,
+ \ }, getmousepos())
+
+ bwipe!
bwipe!
endfunc
@@ -3610,4 +3680,55 @@ func Test_glob_extended_mswin()
call delete('Xtestglob', 'rf')
endfunc
+" Tests for the slice() function.
+func Test_slice()
+ let lines =<< trim END
+ call assert_equal([1, 2, 3, 4, 5], slice(range(6), 1))
+ call assert_equal([2, 3, 4, 5], slice(range(6), 2))
+ call assert_equal([2, 3], slice(range(6), 2, 4))
+ call assert_equal([0, 1, 2, 3], slice(range(6), 0, 4))
+ call assert_equal([1, 2, 3], slice(range(6), 1, 4))
+ call assert_equal([1, 2, 3, 4], slice(range(6), 1, -1))
+ call assert_equal([1, 2], slice(range(6), 1, -3))
+ call assert_equal([1], slice(range(6), 1, -4))
+ call assert_equal([], slice(range(6), 1, -5))
+ call assert_equal([], slice(range(6), 1, -6))
+
+ call assert_equal(0z1122334455, slice(0z001122334455, 1))
+ call assert_equal(0z22334455, slice(0z001122334455, 2))
+ call assert_equal(0z2233, slice(0z001122334455, 2, 4))
+ call assert_equal(0z00112233, slice(0z001122334455, 0, 4))
+ call assert_equal(0z112233, slice(0z001122334455, 1, 4))
+ call assert_equal(0z11223344, slice(0z001122334455, 1, -1))
+ call assert_equal(0z1122, slice(0z001122334455, 1, -3))
+ call assert_equal(0z11, slice(0z001122334455, 1, -4))
+ call assert_equal(0z, slice(0z001122334455, 1, -5))
+ call assert_equal(0z, slice(0z001122334455, 1, -6))
+
+ call assert_equal('12345', slice('012345', 1))
+ call assert_equal('2345', slice('012345', 2))
+ call assert_equal('23', slice('012345', 2, 4))
+ call assert_equal('0123', slice('012345', 0, 4))
+ call assert_equal('123', slice('012345', 1, 4))
+ call assert_equal('1234', slice('012345', 1, -1))
+ call assert_equal('12', slice('012345', 1, -3))
+ call assert_equal('1', slice('012345', 1, -4))
+ call assert_equal('', slice('012345', 1, -5))
+ call assert_equal('', slice('012345', 1, -6))
+
+ #" Composing chars are treated as a part of the preceding base char.
+ call assert_equal('β̳́γ̳̂δ̳̃ε̳̄ζ̳̅', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1))
+ call assert_equal('γ̳̂δ̳̃ε̳̄ζ̳̅', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(2))
+ call assert_equal('γ̳̂δ̳̃', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(2, 4))
+ call assert_equal('ὰ̳β̳́γ̳̂δ̳̃', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(0, 4))
+ call assert_equal('β̳́γ̳̂δ̳̃', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, 4))
+ call assert_equal('β̳́γ̳̂δ̳̃ε̳̄', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -1))
+ call assert_equal('β̳́γ̳̂', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -3))
+ call assert_equal('β̳́', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -4))
+ call assert_equal('', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -5))
+ call assert_equal('', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -6))
+ END
+ call CheckLegacyAndVim9Success(lines)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_global.vim b/test/old/testdir/test_global.vim
index 44a8784348..8c7e7cb26b 100644
--- a/test/old/testdir/test_global.vim
+++ b/test/old/testdir/test_global.vim
@@ -96,7 +96,16 @@ func Test_global_newline()
close!
endfunc
-func Test_wrong_delimiter()
+" Test :g with ? as delimiter.
+func Test_global_question_delimiter()
+ new
+ call setline(1, ['aaaaa', 'b?bbb', 'ccccc', 'ddd?d', 'eeeee'])
+ g?\??delete
+ call assert_equal(['aaaaa', 'ccccc', 'eeeee'], getline(1, '$'))
+ bwipe!
+endfunc
+
+func Test_global_wrong_delimiter()
call assert_fails('g x^bxd', 'E146:')
endfunc
diff --git a/test/old/testdir/test_highlight.vim b/test/old/testdir/test_highlight.vim
index bcaa1dac5d..0a64c63d30 100644
--- a/test/old/testdir/test_highlight.vim
+++ b/test/old/testdir/test_highlight.vim
@@ -825,6 +825,24 @@ func Test_highlight_cmd_errors()
let &t_fo = ""
endfunc
+" Test for User group highlighting used in the statusline
+func Test_highlight_User()
+ CheckNotGui
+ hi User1 ctermfg=12
+ redraw!
+ call assert_equal('12', synIDattr(synIDtrans(hlID('User1')), 'fg'))
+ hi clear
+endfunc
+
+" Test for MsgArea highlighting
+func Test_highlight_MsgArea()
+ CheckNotGui
+ hi MsgArea ctermfg=20
+ redraw!
+ call assert_equal('20', synIDattr(synIDtrans(hlID('MsgArea')), 'fg'))
+ hi clear
+endfunc
+
" Test for using RGB color values in a highlight group
func Test_xxlast_highlight_RGB_color()
CheckCanRunGui
diff --git a/test/old/testdir/test_history.vim b/test/old/testdir/test_history.vim
index 482328ab4a..b288abc3f6 100644
--- a/test/old/testdir/test_history.vim
+++ b/test/old/testdir/test_history.vim
@@ -96,6 +96,60 @@ function Test_History()
call assert_fails('history xyz', 'E488:')
call assert_fails('history ,abc', 'E488:')
call assert_fails('call histdel(":", "\\%(")', 'E53:')
+
+ " Test for filtering the history list
+ let hist_filter = execute(':filter /_\d/ :history all')->split('\n')
+ call assert_equal(20, len(hist_filter))
+ let expected = [' # cmd history',
+ \ ' 2 text_2',
+ \ ' 3 text_3',
+ \ '> 4 text_4',
+ \ ' # search history',
+ \ ' 2 text_2',
+ \ ' 3 text_3',
+ \ '> 4 text_4',
+ \ ' # expr history',
+ \ ' 2 text_2',
+ \ ' 3 text_3',
+ \ '> 4 text_4',
+ \ ' # input history',
+ \ ' 2 text_2',
+ \ ' 3 text_3',
+ \ '> 4 text_4',
+ \ ' # debug history',
+ \ ' 2 text_2',
+ \ ' 3 text_3',
+ \ '> 4 text_4']
+ call assert_equal(expected, hist_filter)
+
+ let cmds = {'c': 'cmd', 's': 'search', 'e': 'expr', 'i': 'input', 'd': 'debug'}
+ for h in sort(keys(cmds))
+ " find some items
+ let hist_filter = execute(':filter /_\d/ :history ' .. h)->split('\n')
+ call assert_equal(4, len(hist_filter))
+
+ let expected = [' # ' .. cmds[h] .. ' history',
+ \ ' 2 text_2',
+ \ ' 3 text_3',
+ \ '> 4 text_4']
+ call assert_equal(expected, hist_filter)
+
+ " Search for an item that is not there
+ let hist_filter = execute(':filter /XXXX/ :history ' .. h)->split('\n')
+ call assert_equal(1, len(hist_filter))
+
+ let expected = [' # ' .. cmds[h] .. ' history']
+ call assert_equal(expected, hist_filter)
+
+ " Invert the filter condition, find non-matches
+ let hist_filter = execute(':filter! /_3$/ :history ' .. h)->split('\n')
+ call assert_equal(3, len(hist_filter))
+
+ let expected = [' # ' .. cmds[h] .. ' history',
+ \ ' 2 text_2',
+ \ '> 4 text_4']
+ call assert_equal(expected, hist_filter)
+ endfor
endfunction
function Test_history_truncates_long_entry()
@@ -254,7 +308,7 @@ func Test_history_crypt_key()
set key& bs& ts&
endfunc
-" The following used to overflow and causing an use-after-free
+" The following used to overflow and causing a use-after-free
func Test_history_max_val()
set history=10
diff --git a/test/old/testdir/test_ins_complete.vim b/test/old/testdir/test_ins_complete.vim
index 917c37c324..3f67a06999 100644
--- a/test/old/testdir/test_ins_complete.vim
+++ b/test/old/testdir/test_ins_complete.vim
@@ -388,6 +388,62 @@ func Test_completefunc_info()
set completefunc&
endfunc
+func CompleteInfoUserDefinedFn(findstart, query)
+ " User defined function (i_CTRL-X_CTRL-U)
+ if a:findstart
+ return col('.')
+ endif
+ return [{'word': 'foo'}, {'word': 'bar'}, {'word': 'baz'}, {'word': 'qux'}]
+endfunc
+
+func CompleteInfoTestUserDefinedFn(mvmt, idx, noselect)
+ new
+ if a:noselect
+ set completeopt=menuone,popup,noinsert,noselect
+ else
+ set completeopt=menu,preview
+ endif
+ set completefunc=CompleteInfoUserDefinedFn
+ call feedkeys("i\<C-X>\<C-U>" . a:mvmt . "\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx")
+ let completed = a:idx != -1 ? ['foo', 'bar', 'baz', 'qux']->get(a:idx) : ''
+ call assert_equal(completed. "{'pum_visible': 1, 'mode': 'function', 'selected': " . a:idx . ", 'items': [" .
+ \ "{'word': 'foo', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, " .
+ \ "{'word': 'bar', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, " .
+ \ "{'word': 'baz', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, " .
+ \ "{'word': 'qux', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}" .
+ \ "]}", getline(1))
+ bwipe!
+ set completeopt&
+ set completefunc&
+endfunc
+
+func Test_complete_info_user_defined_fn()
+ " forward
+ call CompleteInfoTestUserDefinedFn("\<C-N>\<C-N>", 1, v:true)
+ call CompleteInfoTestUserDefinedFn("\<C-N>\<C-N>\<C-N>", 2, v:true)
+ call CompleteInfoTestUserDefinedFn("\<C-N>\<C-N>", 2, v:false)
+ call CompleteInfoTestUserDefinedFn("\<C-N>\<C-N>\<C-N>", 3, v:false)
+ call CompleteInfoTestUserDefinedFn("\<C-N>\<C-N>\<C-N>\<C-N>", -1, v:false)
+ " backward
+ call CompleteInfoTestUserDefinedFn("\<C-P>\<C-P>", 2, v:true)
+ call CompleteInfoTestUserDefinedFn("\<C-P>\<C-P>\<C-P>", 1, v:true)
+ call CompleteInfoTestUserDefinedFn("\<C-P>\<C-P>\<C-P>\<C-P>\<C-P>", -1, v:true)
+ call CompleteInfoTestUserDefinedFn("\<C-P>\<C-P>", 3, v:false)
+ call CompleteInfoTestUserDefinedFn("\<C-P>\<C-P>\<C-P>", 2, v:false)
+ " forward backward
+ call CompleteInfoTestUserDefinedFn("\<C-N>\<C-N>\<C-N>\<C-P>", 1, v:true)
+ call CompleteInfoTestUserDefinedFn("\<C-N>\<C-N>\<C-P>", 0, v:true)
+ call CompleteInfoTestUserDefinedFn("\<C-N>\<C-N>\<C-N>\<C-P>", 2, v:false)
+ call CompleteInfoTestUserDefinedFn("\<C-N>\<C-N>\<C-N>\<C-N>\<C-P>", 3, v:false)
+ call CompleteInfoTestUserDefinedFn("\<C-N>\<C-N>\<C-P>", 1, v:false)
+ " backward forward
+ call CompleteInfoTestUserDefinedFn("\<C-P>\<C-P>\<C-P>\<C-P>\<C-P>\<C-N>", 0, v:true)
+ call CompleteInfoTestUserDefinedFn("\<C-P>\<C-P>\<C-P>\<C-N>", 2, v:true)
+ call CompleteInfoTestUserDefinedFn("\<C-P>\<C-P>\<C-P>\<C-P>\<C-P>\<C-N>", 1, v:false)
+ call CompleteInfoTestUserDefinedFn("\<C-P>\<C-P>\<C-P>\<C-N>", 3, v:false)
+ call CompleteInfoTestUserDefinedFn("\<C-P>\<C-N>\<C-N>", 1, v:false)
+endfunc
+
" Test that mouse scrolling/movement should not interrupt completion.
func Test_mouse_scroll_move_during_completion()
new
@@ -1152,7 +1208,7 @@ func Test_complete_wholeline_unlistedbuf()
edit Xfile1
enew
set complete=U
- " completing from a unloaded buffer should fail
+ " completing from an unloaded buffer should fail
exe "normal! ia\<C-X>\<C-L>\<C-P>"
call assert_equal('a', getline(1))
%d
@@ -2406,7 +2462,7 @@ func Test_complete_info_index()
call assert_equal(-1, g:compl_info['selected'])
call feedkeys("Go\<C-X>\<C-N>\<C-P>\<F5>\<Esc>_dd", 'tx')
- call assert_equal(0, g:compl_info['selected'])
+ call assert_equal(5, g:compl_info['selected'])
call assert_equal(6 , len(g:compl_info['items']))
call assert_equal("fff", g:compl_info['items'][g:compl_info['selected']]['word'])
call feedkeys("Go\<C-X>\<C-N>\<C-N>\<C-N>\<C-N>\<C-N>\<C-N>\<C-N>\<C-N>\<C-N>\<F5>\<Esc>_dd", 'tx')
@@ -2434,4 +2490,26 @@ func Test_complete_changed_complete_info()
call StopVimInTerminal(buf)
endfunc
+func Test_completefunc_first_call_complete_add()
+ new
+
+ func Complete(findstart, base) abort
+ if a:findstart
+ let col = col('.')
+ call complete_add('#')
+ return col - 1
+ else
+ return []
+ endif
+ endfunc
+
+ set completeopt=longest completefunc=Complete
+ " This used to cause heap-buffer-overflow
+ call assert_fails('call feedkeys("ifoo#\<C-X>\<C-U>", "xt")', 'E840:')
+
+ delfunc Complete
+ set completeopt& completefunc&
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab nofoldenable
diff --git a/test/old/testdir/test_let.vim b/test/old/testdir/test_let.vim
index a9cc8a14a4..d37af45aaa 100644
--- a/test/old/testdir/test_let.vim
+++ b/test/old/testdir/test_let.vim
@@ -397,6 +397,45 @@ func Test_let_heredoc_fails()
call assert_report('Caught exception: ' .. v:exception)
endtry
+ try
+ let @- =<< trim TEXT
+ change
+ insert
+ append
+ TEXT
+ call assert_report('No exception thrown')
+ catch /E730:/
+ catch
+ call assert_report('Caught exception: ' .. v:exception)
+ endtry
+
+ try
+ let [] =<< trim TEXT
+ TEXT
+ call assert_report('No exception thrown')
+ catch /E475:/
+ catch
+ call assert_report('Caught exception: ' .. v:exception)
+ endtry
+
+ try
+ let [a b c] =<< trim TEXT
+ TEXT
+ call assert_report('No exception thrown')
+ catch /E475:/
+ catch
+ call assert_report('Caught exception: ' .. v:exception)
+ endtry
+
+ try
+ let [a; b; c] =<< trim TEXT
+ TEXT
+ call assert_report('No exception thrown')
+ catch /E452:/
+ catch
+ call assert_report('Caught exception: ' .. v:exception)
+ endtry
+
let text =<< trim END
func WrongSyntax()
let v =<< that there
@@ -503,6 +542,13 @@ END
XX
call assert_equal(['Line1'], var1)
+ let var1 =<< trim XX " comment
+ Line1
+ Line2
+ Line3
+ XX
+ call assert_equal(['Line1', ' Line2', 'Line3'], var1)
+
" ignore "endfunc"
let var1 =<< END
something
@@ -569,6 +615,22 @@ append
END
call assert_equal(['change', 'insert', 'append'], [a, b, c])
+ " unpack assignment with semicolon
+ let [a; b] =<< END
+change
+insert
+append
+END
+ call assert_equal(['change', ['insert', 'append']], [a, b])
+
+ " unpack assignment with registers
+ let [@/, @", @-] =<< END
+change
+insert
+append
+END
+ call assert_equal(['change', 'insert', 'append'], [@/, @", @-])
+
" curly braces name and list slice assignment
let foo_3_bar = ['', '', '']
let foo_{1 + 2}_bar[ : ] =<< END
@@ -625,6 +687,48 @@ END
END
call assert_equal(['let a = {abc}', 'let b = X', 'let c = {'], code)
+ " Evaluate a dictionary
+ let d1 = #{a: 10, b: 'ss', c: {}}
+ let code =<< eval trim END
+ let d2 = {d1}
+ END
+ call assert_equal(["let d2 = {'a': 10, 'b': 'ss', 'c': {}}"], code)
+
+ " Empty dictionary
+ let d1 = {}
+ let code =<< eval trim END
+ let d2 = {d1}
+ END
+ call assert_equal(["let d2 = {}"], code)
+
+ " null dictionary
+ let d1 = v:_null_dict
+ let code =<< eval trim END
+ let d2 = {d1}
+ END
+ call assert_equal(["let d2 = {}"], code)
+
+ " Evaluate a List
+ let l1 = ['a', 'b', 'c']
+ let code =<< eval trim END
+ let l2 = {l1}
+ END
+ call assert_equal(["let l2 = ['a', 'b', 'c']"], code)
+
+ " Empty List
+ let l1 = []
+ let code =<< eval trim END
+ let l2 = {l1}
+ END
+ call assert_equal(["let l2 = []"], code)
+
+ " Null List
+ let l1 = v:_null_list
+ let code =<< eval trim END
+ let l2 = {l1}
+ END
+ call assert_equal(["let l2 = []"], code)
+
let code = 'xxx'
let code =<< eval trim END
let n = {5 +
@@ -658,6 +762,34 @@ END
LINES
call CheckScriptFailure(lines, 'E15:')
+ " Test for using heredoc in a single string using :execute or execute()
+ for [cmd, res] in items({
+ \ "let x =<< trim END\n one\n two\nEND": ['one', 'two'],
+ \ "let x =<< trim END\n one\n two\nEND": ['one', ' two'],
+ \ " let x =<< trim END\n one\n two\n END": ['one', 'two'],
+ \ " let x =<< trim END\n one\n two\n END": ['one', ' two'],
+ \ "let x =<< END\n one\n two\nEND": [' one', ' two'],
+ \ "let x =<< END\none\ntwo\nEND": ['one', 'two'],
+ \ "let x =<< END \" comment\none\ntwo\nEND": ['one', 'two'],
+ \ })
+ execute cmd
+ call assert_equal(res, x)
+ unlet x
+ call assert_equal($"\n{string(res)}", execute($"{cmd}\necho x"))
+ unlet x
+ endfor
+ for [cmd, err] in items({
+ \ "let x =<<\none\ntwo": "E172:",
+ \ "let x =<< trim\n one\n two": "E172:",
+ \ "let x =<< end\none\ntwo\nend": "E221:",
+ \ "let x =<< END\none\ntwo": "E990: Missing end marker 'END'",
+ \ "let x =<< END !\none\ntwo\nEND": "E488: Trailing characters: !",
+ \ "let x =<< eval END\none\ntwo{y}\nEND": "E121: Undefined variable: y",
+ \ })
+ call assert_fails('execute cmd', err)
+ call assert_fails('call execute(cmd)', err)
+ endfor
+
" skipped heredoc
if 0
let msg =<< trim eval END
diff --git a/test/old/testdir/test_listdict.vim b/test/old/testdir/test_listdict.vim
index 649d5f5c6c..0adc3286f9 100644
--- a/test/old/testdir/test_listdict.vim
+++ b/test/old/testdir/test_listdict.vim
@@ -1441,4 +1441,10 @@ func Test_indexof()
delfunc TestIdx
endfunc
+func Test_extendnew_leak()
+ " This used to leak memory
+ for i in range(100) | silent! call extendnew([], [], []) | endfor
+ for i in range(100) | silent! call extendnew({}, {}, {}) | endfor
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_mapping.vim b/test/old/testdir/test_mapping.vim
index 623228b347..2a4d068dea 100644
--- a/test/old/testdir/test_mapping.vim
+++ b/test/old/testdir/test_mapping.vim
@@ -236,21 +236,25 @@ func Test_map_meta_multibyte()
endfunc
func Test_map_super_quotes()
- if has('gui_gtk') || has('gui_gtk3') || has("macos")
- imap <D-"> foo
- call feedkeys("Go-\<*D-\">-\<Esc>", "xt")
- call assert_equal("-foo-", getline('$'))
- set nomodified
- iunmap <D-">
+ if "\<D-j>"[-1:] == '>'
+ throw 'Skipped: <D- modifier not supported'
endif
+
+ imap <D-"> foo
+ call feedkeys("Go-\<*D-\">-\<Esc>", "xt")
+ call assert_equal("-foo-", getline('$'))
+ set nomodified
+ iunmap <D-">
endfunc
func Test_map_super_multibyte()
- if has('gui_gtk') || has('gui_gtk3') || has("macos")
- imap <D-á> foo
- call assert_match('i <D-á>\s*foo', execute('imap'))
- iunmap <D-á>
+ if "\<D-j>"[-1:] == '>'
+ throw 'Skipped: <D- modifier not supported'
endif
+
+ imap <D-á> foo
+ call assert_match('i <D-á>\s*foo', execute('imap'))
+ iunmap <D-á>
endfunc
func Test_abbr_after_line_join()
@@ -1693,7 +1697,7 @@ func Test_map_after_timed_out_nop()
inoremap ab TEST
inoremap a <Nop>
END
- call writefile(lines, 'Xtest_map_after_timed_out_nop')
+ call writefile(lines, 'Xtest_map_after_timed_out_nop', 'D')
let buf = RunVimInTerminal('-S Xtest_map_after_timed_out_nop', #{rows: 6})
" Enter Insert mode
@@ -1710,7 +1714,49 @@ func Test_map_after_timed_out_nop()
" clean up
call StopVimInTerminal(buf)
- call delete('Xtest_map_after_timed_out_nop')
+endfunc
+
+" Test 'showcmd' behavior with a partial mapping
+func Test_showcmd_part_map()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ set notimeout showcmd
+ nnoremap ,a <Ignore>
+ nnoremap ;a <Ignore>
+ nnoremap Àa <Ignore>
+ nnoremap Ëa <Ignore>
+ nnoremap βa <Ignore>
+ nnoremap ωa <Ignore>
+ nnoremap …a <Ignore>
+ nnoremap <C-W>a <Ignore>
+ END
+ call writefile(lines, 'Xtest_showcmd_part_map', 'D')
+ let buf = RunVimInTerminal('-S Xtest_showcmd_part_map', #{rows: 6})
+
+ call term_sendkeys(buf, ":set noruler | echo\<CR>")
+ call WaitForAssert({-> assert_equal('', term_getline(buf, 6))})
+
+ for c in [',', ';', 'À', 'Ë', 'β', 'ω', '…']
+ call term_sendkeys(buf, c)
+ call WaitForAssert({-> assert_equal(c, trim(term_getline(buf, 6)))})
+ call term_sendkeys(buf, 'a')
+ call WaitForAssert({-> assert_equal('', trim(term_getline(buf, 6)))})
+ endfor
+
+ call term_sendkeys(buf, "\<C-W>")
+ call WaitForAssert({-> assert_equal('^W', trim(term_getline(buf, 6)))})
+ call term_sendkeys(buf, 'a')
+ call WaitForAssert({-> assert_equal('', trim(term_getline(buf, 6)))})
+
+ " Use feedkeys() as terminal buffer cannot forward unsimplified Ctrl-W.
+ " This is like typing Ctrl-W with modifyOtherKeys enabled.
+ call term_sendkeys(buf, ':call feedkeys("\<*C-W>", "m")' .. " | echo\<CR>")
+ call WaitForAssert({-> assert_equal('^W', trim(term_getline(buf, 6)))})
+ call term_sendkeys(buf, 'a')
+ call WaitForAssert({-> assert_equal('', trim(term_getline(buf, 6)))})
+
+ call StopVimInTerminal(buf)
endfunc
func Test_using_past_typeahead()
diff --git a/test/old/testdir/test_match.vim b/test/old/testdir/test_match.vim
index 1cb52b8b2a..ddf032d593 100644
--- a/test/old/testdir/test_match.vim
+++ b/test/old/testdir/test_match.vim
@@ -310,6 +310,7 @@ func Test_matchaddpos_error()
" call assert_fails("call matchaddpos('Error', [{}])", 'E290:')
call assert_fails("call matchaddpos('Error', [{}])", 'E5031:')
call assert_equal(-1, matchaddpos('Error', v:_null_list))
+ call assert_equal(-1, matchaddpos('Error', []))
call assert_fails("call matchaddpos('Error', [1], [], 1)", 'E745:')
endfunc
@@ -427,13 +428,11 @@ func Test_match_tab_with_linebreak()
call setline(1, "\tix")
call matchadd('ErrorMsg', '\t')
END
- call writefile(lines, 'XscriptMatchTabLinebreak')
+ call writefile(lines, 'XscriptMatchTabLinebreak', 'D')
let buf = RunVimInTerminal('-S XscriptMatchTabLinebreak', #{rows: 10})
call VerifyScreenDump(buf, 'Test_match_tab_linebreak', {})
call StopVimInTerminal(buf)
- call delete('XscriptMatchTabLinebreak')
endfunc
-
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_matchparen.vim b/test/old/testdir/test_matchparen.vim
index 3138180c66..ab425b046a 100644
--- a/test/old/testdir/test_matchparen.vim
+++ b/test/old/testdir/test_matchparen.vim
@@ -61,6 +61,31 @@ func Test_matchparen_clear_highlight()
call StopVimInTerminal(buf)
endfunc
+" Test for matchparen highlight when switching buffer in win_execute()
+func Test_matchparen_win_execute()
+ CheckScreendump
+
+ let lines =<< trim END
+ source $VIMRUNTIME/plugin/matchparen.vim
+ let s:win = win_getid()
+ call setline(1, '{}')
+ split
+
+ func SwitchBuf()
+ call win_execute(s:win, 'enew | buffer #')
+ endfunc
+ END
+ call writefile(lines, 'XMatchparenWinExecute', 'D')
+ let buf = RunVimInTerminal('-S XMatchparenWinExecute', #{rows: 5})
+ call VerifyScreenDump(buf, 'Test_matchparen_win_execute_1', {})
+
+ " Switching buffer away and back shouldn't change matchparen highlight.
+ call term_sendkeys(buf, ":call SwitchBuf()\<CR>:\<Esc>")
+ call VerifyScreenDump(buf, 'Test_matchparen_win_execute_1', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
" Test for scrolling that modifies buffer during visual block
func Test_matchparen_pum_clear()
CheckScreendump
diff --git a/test/old/testdir/test_mksession.vim b/test/old/testdir/test_mksession.vim
index d63d10b44c..7e9cd6c8e8 100644
--- a/test/old/testdir/test_mksession.vim
+++ b/test/old/testdir/test_mksession.vim
@@ -631,11 +631,11 @@ endfunc
func Test_mkview_no_file_name()
new
- " :mkview or :mkview {nr} should fail in a unnamed buffer.
+ " :mkview or :mkview {nr} should fail in an unnamed buffer.
call assert_fails('mkview', 'E32:')
call assert_fails('mkview 1', 'E32:')
- " :mkview {file} should succeed in a unnamed buffer.
+ " :mkview {file} should succeed in an unnamed buffer.
mkview Xview
help
source Xview
diff --git a/test/old/testdir/test_normal.vim b/test/old/testdir/test_normal.vim
index 91c058df9e..a2ef07193d 100644
--- a/test/old/testdir/test_normal.vim
+++ b/test/old/testdir/test_normal.vim
@@ -131,7 +131,7 @@ func Test_normal01_keymodel()
call assert_equal([0, 1, 1, 0], getpos("'<"))
call assert_equal([0, 3, 1, 0], getpos("'>"))
call feedkeys("Gz\<CR>8|\<S-PageUp>y", 'xt')
- call assert_equal([0, 2, 1, 0], getpos("'<"))
+ call assert_equal([0, 3, 1, 0], getpos("'<"))
call assert_equal([0, 3, 8, 0], getpos("'>"))
" Test for <S-C-Home> and <S-C-End>
call cursor(2, 12)
@@ -915,12 +915,10 @@ func Test_normal14_page()
set scrolloff=0
100
exe "norm! $\<c-b>"
- call assert_equal('92', getline('.'))
call assert_equal([0, 92, 1, 0, 1], getcurpos())
100
set nostartofline
exe "norm! $\<c-b>"
- call assert_equal('92', getline('.'))
call assert_equal([0, 92, 2, 0, v:maxcol], getcurpos())
" cleanup
set startofline
@@ -1287,7 +1285,7 @@ func Test_vert_scroll_cmds()
exe "normal \<C-U>"
call assert_equal(36, line('.'))
exe "normal \<C-U>"
- call assert_equal(10, line('.'))
+ call assert_equal(1, line('.'))
exe "normal \<C-U>"
call assert_equal(1, line('.'))
set scroll&
@@ -2370,6 +2368,14 @@ func Test_normal30_changecase()
%d
call assert_beeps('norm! ~')
+ " Test with multiple lines
+ call setline(1, ['AA', 'BBBB', 'CCCCCC', 'DDDDDDDD'])
+ norm! ggguG
+ call assert_equal(['aa', 'bbbb', 'cccccc', 'dddddddd'], getline(1, '$'))
+ norm! GgUgg
+ call assert_equal(['AA', 'BBBB', 'CCCCCC', 'DDDDDDDD'], getline(1, '$'))
+ %d
+
" Test for changing case across lines using 'whichwrap'
call setline(1, ['aaaaaa', 'aaaaaa'])
normal! gg10~
@@ -3817,8 +3823,8 @@ func Test_normal_vert_scroll_longline()
call assert_equal(11, line('.'))
call assert_equal(1, winline())
exe "normal \<C-B>"
- call assert_equal(10, line('.'))
- call assert_equal(3, winline())
+ call assert_equal(11, line('.'))
+ call assert_equal(5, winline())
exe "normal \<C-B>\<C-B>"
call assert_equal(5, line('.'))
call assert_equal(5, winline())
@@ -4176,12 +4182,8 @@ endfunc
" Test for { and } paragraph movements in a single line
func Test_brace_single_line()
- let text =<< trim [DATA]
- foobar one two three
- [DATA]
-
new
- call setline(1, text)
+ call setline(1, ['foobar one two three'])
1
norm! 0}
@@ -4191,4 +4193,99 @@ func Test_brace_single_line()
bw!
endfunc
+" Test for Ctrl-B/Ctrl-U in buffer with a single line
+func Test_single_line_scroll()
+ CheckFeature textprop
+
+ new
+ call setline(1, ['foobar one two three'])
+ let vt = 'virt_above'
+ call prop_type_add(vt, {'highlight': 'IncSearch'})
+ call prop_add(1, 0, {'type': vt, 'text': '---', 'text_align': 'above'})
+ call cursor(1, 1)
+
+ " Ctrl-B/Ctrl-U scroll up with hidden "above" virtual text.
+ set smoothscroll
+ exe "normal \<C-E>"
+ call assert_notequal(0, winsaveview().skipcol)
+ exe "normal \<C-B>"
+ call assert_equal(0, winsaveview().skipcol)
+ exe "normal \<C-E>"
+ call assert_notequal(0, winsaveview().skipcol)
+ exe "normal \<C-U>"
+ call assert_equal(0, winsaveview().skipcol)
+
+ set smoothscroll&
+ bw!
+ call prop_type_delete(vt)
+endfunc
+
+" Test for zb in buffer with a single line and filler lines
+func Test_single_line_filler_zb()
+ call setline(1, ['', 'foobar one two three'])
+ diffthis
+ new
+ call setline(1, ['foobar one two three'])
+ diffthis
+
+ " zb scrolls to reveal filler lines at the start of the buffer.
+ exe "normal \<C-E>zb"
+ call assert_equal(1, winsaveview().topfill)
+
+ bw!
+endfunc
+
+" Test for Ctrl-U not getting stuck at end of buffer with 'scrolloff'.
+func Test_halfpage_scrolloff_eob()
+ set scrolloff=5
+
+ call setline(1, range(1, 100))
+ exe "norm! Gzz\<C-U>zz"
+ call assert_notequal(100, line('.'))
+
+ set scrolloff&
+ bwipe!
+endfunc
+
+" Test for Ctrl-U/D moving the cursor at the buffer boundaries.
+func Test_halfpage_cursor_startend()
+ call setline(1, range(1, 100))
+ exe "norm! jztj\<C-U>"
+ call assert_equal(1, line('.'))
+ exe "norm! G\<C-Y>k\<C-D>"
+ call assert_equal(100, line('.'))
+ bwipe!
+endfunc
+
+" Test for Ctrl-F/B moving the cursor to the window boundaries.
+func Test_page_cursor_topbot()
+ 10new
+ call setline(1, range(1, 100))
+ exe "norm! gg2\<C-F>"
+ call assert_equal(17, line('.'))
+ exe "norm! \<C-B>"
+ call assert_equal(18, line('.'))
+ exe "norm! \<C-B>\<C-F>"
+ call assert_equal(9, line('.'))
+ bwipe!
+endfunc
+
+" Test for Ctrl-D with long line
+func Test_halfpage_longline()
+ 10new
+ call setline(1, ['long'->repeat(1000), 'short'])
+ exe "norm! \<C-D>"
+ call assert_equal(2, line('.'))
+ bwipe!
+endfunc
+
+" Test for Ctrl-E with long line and very narrow window,
+" used to cause an inifite loop
+func Test_scroll_longline_no_loop()
+ 4vnew
+ setl smoothscroll number showbreak=> scrolloff=2
+ call setline(1, repeat(['Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'], 3))
+ exe "normal! \<C-E>"
+ bwipe!
+endfunc
" vim: shiftwidth=2 sts=2 expandtab nofoldenable
diff --git a/test/old/testdir/test_perl.vim b/test/old/testdir/test_perl.vim
index ce2a566f62..c08a042dae 100644
--- a/test/old/testdir/test_perl.vim
+++ b/test/old/testdir/test_perl.vim
@@ -94,6 +94,7 @@ func Test_buffer_Number()
endfunc
func Test_window_Cursor()
+ throw 'skipped: flaky '
new
call setline(1, ['line1', 'line2'])
perl $curwin->Cursor(2, 3)
@@ -104,6 +105,7 @@ func Test_window_Cursor()
endfunc
func Test_window_SetHeight()
+ throw 'skipped: flaky '
new
perl $curwin->SetHeight(2)
call assert_equal(2, winheight(0))
diff --git a/test/old/testdir/test_put.vim b/test/old/testdir/test_put.vim
index b1cf268a58..73b58dbe33 100644
--- a/test/old/testdir/test_put.vim
+++ b/test/old/testdir/test_put.vim
@@ -323,4 +323,21 @@ func Test_put_visual_replace_fold_marker()
bwipe!
endfunc
+func Test_put_dict()
+ new
+ let d = #{a: #{b: 'abc'}, c: [1, 2], d: 0z10}
+ put! =d
+ call assert_equal(["{'a': {'b': 'abc'}, 'c': [1, 2], 'd': 0z10}", ''],
+ \ getline(1, '$'))
+ bw!
+endfunc
+
+func Test_put_list()
+ new
+ let l = ['a', 'b', 'c']
+ put! =l
+ call assert_equal(['a', 'b', 'c', ''], getline(1, '$'))
+ bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_quickfix.vim b/test/old/testdir/test_quickfix.vim
index b5abb08ed8..a708cabc26 100644
--- a/test/old/testdir/test_quickfix.vim
+++ b/test/old/testdir/test_quickfix.vim
@@ -6369,4 +6369,74 @@ func Test_efm_format_b()
call setqflist([], 'f')
endfunc
+func XbufferTests_range(cchar)
+ call s:setup_commands(a:cchar)
+
+ enew!
+ let lines =<< trim END
+ Xtestfile7:700:10:Line 700
+ Xtestfile8:800:15:Line 800
+ END
+ silent! call setline(1, lines)
+ norm! Vy
+ " Note: We cannot use :Xbuffer here,
+ " it doesn't properly fail, so we need to
+ " test using the raw c/l commands.
+ " (also further down)
+ if (a:cchar == 'c')
+ exe "'<,'>cbuffer!"
+ else
+ exe "'<,'>lbuffer!"
+ endif
+ let l = g:Xgetlist()
+ call assert_true(len(l) == 1 &&
+ \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700')
+
+ enew!
+ let lines =<< trim END
+ Xtestfile9:900:55:Line 900
+ Xtestfile10:950:66:Line 950
+ END
+ silent! call setline(1, lines)
+ if (a:cchar == 'c')
+ 1cgetbuffer
+ else
+ 1lgetbuffer
+ endif
+ let l = g:Xgetlist()
+ call assert_true(len(l) == 1 &&
+ \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900')
+
+ enew!
+ let lines =<< trim END
+ Xtestfile11:700:20:Line 700
+ Xtestfile12:750:25:Line 750
+ END
+ silent! call setline(1, lines)
+ if (a:cchar == 'c')
+ 1,1caddbuffer
+ else
+ 1,1laddbuffer
+ endif
+ let l = g:Xgetlist()
+ call assert_true(len(l) == 2 &&
+ \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
+ \ l[1].lnum == 700 && l[1].col == 20 && l[1].text ==# 'Line 700')
+ enew!
+
+ " Check for invalid range
+ " Using Xbuffer will not run the range check in the cbuffer/lbuffer
+ " commands. So directly call the commands.
+ if (a:cchar == 'c')
+ call assert_fails('900,999caddbuffer', 'E16:')
+ else
+ call assert_fails('900,999laddbuffer', 'E16:')
+ endif
+endfunc
+
+func Test_cbuffer_range()
+ call XbufferTests_range('c')
+ call XbufferTests_range('l')
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_recover.vim b/test/old/testdir/test_recover.vim
index fa8cc1abaf..ca1ee11b44 100644
--- a/test/old/testdir/test_recover.vim
+++ b/test/old/testdir/test_recover.vim
@@ -385,7 +385,7 @@ func Test_recover_encrypted_swap_file()
call delete('Xfile1')
endfunc
-" Test for :recover using a unreadable swap file
+" Test for :recover using an unreadable swap file
func Test_recover_unreadable_swap_file()
CheckUnix
CheckNotRoot
diff --git a/test/old/testdir/test_regexp_latin.vim b/test/old/testdir/test_regexp_latin.vim
index ece6ae518e..2cfa81e078 100644
--- a/test/old/testdir/test_regexp_latin.vim
+++ b/test/old/testdir/test_regexp_latin.vim
@@ -842,12 +842,26 @@ func Regex_Mark()
%d
endfunc
+" Same test as above, but use verymagic
+func Regex_Mark_Verymagic()
+ call append(0, ['', '', '', 'Marks:', 'asdfSasdfsadfEasdf', 'asdfSas',
+ \ 'dfsadfEasdf', '', '', '', '', ''])
+ call cursor(4, 1)
+ exe "normal jfSmsfEme:.-4,.+6s/\\v.%>'s.*%<'e../here/\<CR>"
+ exe "normal jfSmsj0fEme:.-4,.+6s/\\v.%>'s\\_.*%<'e../again/\<CR>"
+ call assert_equal(['', '', '', 'Marks:', 'asdfhereasdf', 'asdfagainasdf',
+ \ '', '', '', '', '', ''], getline(1, '$'))
+ %d
+endfunc
+
func Test_matching_marks()
new
set regexpengine=1
call Regex_Mark()
+ call Regex_Mark_Verymagic()
set regexpengine=2
call Regex_Mark()
+ call Regex_Mark_Verymagic()
bwipe!
endfunc
diff --git a/test/old/testdir/test_regexp_utf8.vim b/test/old/testdir/test_regexp_utf8.vim
index 97f48a0c09..728a88fa0f 100644
--- a/test/old/testdir/test_regexp_utf8.vim
+++ b/test/old/testdir/test_regexp_utf8.vim
@@ -372,7 +372,7 @@ func Test_multibyte_chars()
endfunc
" check that 'ambiwidth' does not change the meaning of \p
-func Test_ambiwidth()
+func Test_regexp_ambiwidth()
set regexpengine=1 ambiwidth=single
call assert_equal(0, match("\u00EC", '\p'))
set regexpengine=1 ambiwidth=double
diff --git a/test/old/testdir/test_registers.vim b/test/old/testdir/test_registers.vim
index e113bd9e75..e5add9414f 100644
--- a/test/old/testdir/test_registers.vim
+++ b/test/old/testdir/test_registers.vim
@@ -214,6 +214,71 @@ func Test_recording_with_select_mode()
bwipe!
endfunc
+func Run_test_recording_with_select_mode_utf8()
+ new
+
+ " Test with different text lengths: 5, 7, 9, 11, 13, 15, to check that
+ " a character isn't split between two buffer blocks.
+ for s in ['12345', '口=口', '口口口', '口=口=口', '口口=口口', '口口口口口']
+ " 0x80 is K_SPECIAL
+ " 0x9B is CSI
+ " 哦: 0xE5 0x93 0xA6
+ " 洛: 0xE6 0xB4 0x9B
+ " 固: 0xE5 0x9B 0xBA
+ " 四: 0xE5 0x9B 0x9B
+ " 最: 0xE6 0x9C 0x80
+ " 倒: 0xE5 0x80 0x92
+ " 倀: 0xE5 0x80 0x80
+ for c in ['哦', '洛', '固', '四', '最', '倒', '倀']
+ call setline(1, 'asdf')
+ call feedkeys($"qacc{s}\<Esc>gH{c}\<Esc>q", "tx")
+ call assert_equal(c, getline(1))
+ call assert_equal($"cc{s}\<Esc>gH{c}\<Esc>", @a)
+ call setline(1, 'asdf')
+ normal! @a
+ call assert_equal(c, getline(1))
+
+ " Test with Shift modifier.
+ let shift_c = eval($'"\<S-{c}>"')
+ call setline(1, 'asdf')
+ call feedkeys($"qacc{s}\<Esc>gH{shift_c}\<Esc>q", "tx")
+ call assert_equal(c, getline(1))
+ call assert_equal($"cc{s}\<Esc>gH{shift_c}\<Esc>", @a)
+ call setline(1, 'asdf')
+ normal! @a
+ call assert_equal(c, getline(1))
+ endfor
+ endfor
+
+ bwipe!
+endfunc
+
+func Test_recording_with_select_mode_utf8()
+ call Run_test_recording_with_select_mode_utf8()
+endfunc
+
+" This must be done as one of the last tests, because it starts the GUI, which
+" cannot be undone.
+func Test_zz_recording_with_select_mode_utf8_gui()
+ CheckCanRunGui
+
+ gui -f
+ call Run_test_recording_with_select_mode_utf8()
+endfunc
+
+func Test_recording_with_super_mod()
+ if "\<D-j>"[-1:] == '>'
+ throw 'Skipped: <D- modifier not supported'
+ endif
+
+ nnoremap <D-j> <Ignore>
+ let s = repeat("\<D-j>", 1000)
+ " This used to crash Vim
+ call feedkeys($'qr{s}q', 'tx')
+ call assert_equal(s, @r)
+ nunmap <D-j>
+endfunc
+
" Test for executing the last used register (@)
func Test_last_used_exec_reg()
" Test for the @: command
@@ -706,13 +771,13 @@ func Test_ve_blockpaste()
call cursor(1,1)
exe ":norm! \<C-V>3ljdP"
call assert_equal(1, col('.'))
- call assert_equal(getline(1, 2), ['QWERTZ', 'ASDFGH'])
+ call assert_equal(['QWERTZ', 'ASDFGH'], getline(1, 2))
call cursor(1,1)
exe ":norm! \<C-V>3ljd"
call cursor(1,1)
norm! $3lP
call assert_equal(5, col('.'))
- call assert_equal(getline(1, 2), ['TZ QWER', 'GH ASDF'])
+ call assert_equal(['TZ QWER', 'GH ASDF'], getline(1, 2))
set ve&vim
bwipe!
endfunc
diff --git a/test/old/testdir/test_scroll_opt.vim b/test/old/testdir/test_scroll_opt.vim
index a1987ed3c9..76b4089bd1 100644
--- a/test/old/testdir/test_scroll_opt.vim
+++ b/test/old/testdir/test_scroll_opt.vim
@@ -552,14 +552,14 @@ func Test_smoothscroll_cursor_position()
exe "normal \<C-Y>"
call s:check_col_calc(1, 3, 41)
- " Test "g0/g<Home>"
+ " Test "g0/g<Home>"
exe "normal gg\<C-E>"
norm $gkg0
- call s:check_col_calc(1, 2, 21)
+ call s:check_col_calc(4, 1, 24)
" Test moving the cursor behind the <<< display with 'virtualedit'
set virtualedit=all
- exe "normal \<C-E>3lgkh"
+ exe "normal \<C-E>gkh"
call s:check_col_calc(3, 2, 23)
set virtualedit&
@@ -741,6 +741,7 @@ func Test_smoothscroll_mouse_pos()
let &mouse = save_mouse
"let &term = save_term
"let &ttymouse = save_ttymouse
+ bwipe!
endfunc
" this was dividing by zero
@@ -832,7 +833,7 @@ func Test_smoothscroll_eob()
call VerifyScreenDump(buf, 'Test_smooth_eob_1', {})
" cursor is not placed below window
- call term_sendkeys(buf, ":call setline(92, 'a'->repeat(100))\<CR>\<C-B>G")
+ call term_sendkeys(buf, ":call setline(92, 'a'->repeat(100))\<CR>\<C-L>\<C-B>G")
call VerifyScreenDump(buf, 'Test_smooth_eob_2', {})
call StopVimInTerminal(buf)
@@ -963,4 +964,231 @@ func Test_smoothscroll_insert_bottom()
call StopVimInTerminal(buf)
endfunc
+func Test_smoothscroll_in_qf_window()
+ CheckFeature quickfix
+ CheckScreendump
+
+ let lines =<< trim END
+ set nocompatible display=lastline
+ copen 5
+ setlocal number smoothscroll
+ let g:l = [{'text': 'foo'}] + repeat([{'text': join(range(30))}], 10)
+ call setqflist(g:l, 'r')
+ normal! G
+ wincmd t
+ let g:l1 = [{'text': join(range(1000))}]
+ END
+ call writefile(lines, 'XSmoothScrollInQfWindow', 'D')
+ let buf = RunVimInTerminal('-u NONE -S XSmoothScrollInQfWindow', #{rows: 20, cols: 60})
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_1', {})
+
+ call term_sendkeys(buf, ":call setqflist([], 'r')\<CR>")
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_2', {})
+
+ call term_sendkeys(buf, ":call setqflist(g:l, 'r')\<CR>")
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_3', {})
+
+ call term_sendkeys(buf, ":call setqflist(g:l1, 'r')\<CR>")
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_4', {})
+
+ call term_sendkeys(buf, "\<C-W>b$\<C-W>t")
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_5', {})
+
+ call term_sendkeys(buf, ":call setqflist([], 'r')\<CR>")
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_2', {})
+
+ call term_sendkeys(buf, ":call setqflist(g:l1, 'r')\<CR>")
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_4', {})
+
+ call term_sendkeys(buf, "\<C-W>b$\<C-W>t")
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_5', {})
+
+ call term_sendkeys(buf, ":call setqflist(g:l, 'r')\<CR>")
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_3', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
+func Test_smoothscroll_in_zero_width_window()
+ set cpo+=n number smoothscroll
+ set winwidth=99999 winminwidth=0
+
+ vsplit
+ call assert_equal(0, winwidth(winnr('#')))
+ call win_execute(win_getid(winnr('#')), "norm! \<C-Y>")
+
+ only!
+ set winwidth& winminwidth&
+ set cpo-=n nonumber nosmoothscroll
+endfunc
+
+func Test_smoothscroll_textoff_small_winwidth()
+ set smoothscroll number
+ call setline(1, 'llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch')
+ vsplit
+
+ let textoff = getwininfo(win_getid())[0].textoff
+ execute 'vertical resize' textoff + 1
+ redraw
+ call assert_equal(0, winsaveview().skipcol)
+ execute "normal! 0\<C-E>"
+ redraw
+ call assert_equal(1, winsaveview().skipcol)
+ execute 'vertical resize' textoff - 1
+ " This caused a signed integer overflow.
+ redraw
+ call assert_equal(1, winsaveview().skipcol)
+ execute 'vertical resize' textoff
+ " This caused an infinite loop.
+ redraw
+ call assert_equal(1, winsaveview().skipcol)
+
+ %bw!
+ set smoothscroll& number&
+endfunc
+
+func Test_smoothscroll_page()
+ call NewWindow(10, 40)
+ setlocal smoothscroll
+ call setline(1, 'abcde '->repeat(150))
+
+ exe "norm! \<C-F>"
+ call assert_equal(400, winsaveview().skipcol)
+ exe "norm! \<C-F>"
+ call assert_equal(800, winsaveview().skipcol)
+ exe "norm! \<C-F>"
+ call assert_equal(880, winsaveview().skipcol)
+ exe "norm! \<C-B>"
+ call assert_equal(480, winsaveview().skipcol)
+ exe "norm! \<C-B>"
+ call assert_equal(80, winsaveview().skipcol)
+ exe "norm! \<C-B>"
+ call assert_equal(0, winsaveview().skipcol)
+
+ " Half-page scrolling does not go beyond end of buffer and moves the cursor.
+ " Even with 'nostartofline', the correct amount of lines is scrolled.
+ setl nostartofline
+ exe "norm! 15|\<C-D>"
+ call assert_equal(200, winsaveview().skipcol)
+ call assert_equal(215, col('.'))
+ exe "norm! \<C-D>"
+ call assert_equal(400, winsaveview().skipcol)
+ call assert_equal(415, col('.'))
+ exe "norm! \<C-D>"
+ call assert_equal(520, winsaveview().skipcol)
+ call assert_equal(615, col('.'))
+ exe "norm! \<C-D>"
+ call assert_equal(520, winsaveview().skipcol)
+ call assert_equal(815, col('.'))
+ exe "norm! \<C-D>"
+ call assert_equal(520, winsaveview().skipcol)
+ call assert_equal(895, col('.'))
+ exe "norm! \<C-U>"
+ call assert_equal(320, winsaveview().skipcol)
+ call assert_equal(695, col('.'))
+ exe "norm! \<C-U>"
+ call assert_equal(120, winsaveview().skipcol)
+ call assert_equal(495, col('.'))
+ exe "norm! \<C-U>"
+ call assert_equal(0, winsaveview().skipcol)
+ call assert_equal(295, col('.'))
+ exe "norm! \<C-U>"
+ call assert_equal(0, winsaveview().skipcol)
+ call assert_equal(95, col('.'))
+ exe "norm! \<C-U>"
+ call assert_equal(0, winsaveview().skipcol)
+ call assert_equal(15, col('.'))
+
+ bwipe!
+endfunc
+
+func Test_smoothscroll_next_topline()
+ call NewWindow(10, 40)
+ setlocal smoothscroll
+ call setline(1, ['abcde '->repeat(150)]->repeat(2))
+
+ " Scrolling a screenline that causes the cursor to move to the next buffer
+ " line should not skip part of that line to bring the cursor into view.
+ exe "norm! 22\<C-E>"
+ call assert_equal(880, winsaveview().skipcol)
+ exe "norm! \<C-E>"
+ redraw
+ call assert_equal(0, winsaveview().skipcol)
+
+ " Also when scrolling back.
+ exe "norm! G\<C-Y>"
+ redraw
+ call assert_equal(880, winsaveview().skipcol)
+
+ " Cursor in correct place when not in the first screenline of a buffer line.
+ exe "norm! gg4gj20\<C-D>\<C-D>"
+ redraw
+ call assert_equal(2, line('w0'))
+
+ " Cursor does not end up above topline, adjusting topline later.
+ setlocal nu cpo+=n
+ exe "norm! G$g013\<C-Y>"
+ redraw
+ call assert_equal(2, line('.'))
+ call assert_equal(0, winsaveview().skipcol)
+
+ set cpo-=n
+ bwipe!
+endfunc
+
+func Test_smoothscroll_long_line_zb()
+ call NewWindow(10, 40)
+ call setline(1, 'abcde '->repeat(150))
+
+ " Also works without 'smoothscroll' when last line of buffer doesn't fit.
+ " Used to set topline to buffer line count plus one, causing an empty screen.
+ norm zb
+ redraw
+ call assert_equal(1, winsaveview().topline)
+
+ " Moving cursor to bottom works on line that doesn't fit with 'smoothscroll'.
+ " Skipcol was adjusted later for cursor being on not visible part of line.
+ setlocal smoothscroll
+ norm zb
+ redraw
+ call assert_equal(520, winsaveview().skipcol)
+
+ bwipe!
+endfunc
+
+func Test_smooth_long_scrolloff()
+ CheckScreendump
+
+ let lines =<< trim END
+ set smoothscroll scrolloff=3
+ call setline(1, ['one', 'two long '->repeat(100), 'three', 'four', 'five', 'six'])
+ END
+ call writefile(lines, 'XSmoothLongScrolloff', 'D')
+ let buf = RunVimInTerminal('-u NONE -S XSmoothLongScrolloff', #{rows: 8, cols: 40})
+ "FIXME: empty screen due to reset_skipcol()/curs_columns() shenanigans
+ call term_sendkeys(buf, ":norm j721|\<CR>")
+ call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_1', {})
+
+ call term_sendkeys(buf, "gj")
+ call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_2', {})
+
+ call term_sendkeys(buf, "gj")
+ call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_3', {})
+
+ call term_sendkeys(buf, "gj")
+ call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_4', {})
+
+ call term_sendkeys(buf, "gj")
+ call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_5', {})
+
+ call term_sendkeys(buf, "gj")
+ call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_6', {})
+
+ call term_sendkeys(buf, "gk")
+ "FIXME: empty screen due to reset_skipcol()/curs_columns() shenanigans
+ call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_7', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_spellrare.vim b/test/old/testdir/test_spellrare.vim
new file mode 100644
index 0000000000..bbb13c27c2
--- /dev/null
+++ b/test/old/testdir/test_spellrare.vim
@@ -0,0 +1,61 @@
+" Test spell checking
+
+source check.vim
+CheckFeature spell
+
+" Test spellbadword() with argument, specifically to move to "rare" words
+" in normal mode.
+func Test_spellrareword()
+ set spell
+
+ " Create a small word list to test that spellbadword('...')
+ " can return ['...', 'rare'].
+ let lines =<< trim END
+ foo
+ foobar/?
+ foobara/?
+END
+ call writefile(lines, 'Xwords', 'D')
+
+ mkspell! Xwords.spl Xwords
+ set spelllang=Xwords.spl
+ call assert_equal(['foobar', 'rare'], spellbadword('foo foobar'))
+
+ new
+ call setline(1, ['foo', '', 'foo bar foo bar foobara foo foo foo foobar', '', 'End'])
+ set spell wrapscan
+ normal ]s
+ call assert_equal('foo', expand('<cword>'))
+ normal ]s
+ call assert_equal('bar', expand('<cword>'))
+
+ normal ]r
+ call assert_equal('foobara', expand('<cword>'))
+ normal ]r
+ call assert_equal('foobar', expand('<cword>'))
+ normal ]r
+ call assert_equal('foobara', expand('<cword>'))
+ normal 2]r
+ call assert_equal('foobara', expand('<cword>'))
+
+ normal [r
+ call assert_equal('foobar', expand('<cword>'))
+ normal [r
+ call assert_equal('foobara', expand('<cword>'))
+ normal [r
+ call assert_equal('foobar', expand('<cword>'))
+ normal 2[r
+ call assert_equal('foobar', expand('<cword>'))
+
+ bwipe!
+ set nospell
+
+ call delete('Xwords.spl')
+ set spelllang&
+ set spell&
+
+ " set 'encoding' to clear the word list
+ set encoding=utf-8
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_stat.vim b/test/old/testdir/test_stat.vim
index d3059664e9..13ade5bee1 100644
--- a/test/old/testdir/test_stat.vim
+++ b/test/old/testdir/test_stat.vim
@@ -55,7 +55,7 @@ func SleepForTimestamp()
if has('win32')
sleep 2
else
- sleep 2
+ sleep 1
endif
endfunc
diff --git a/test/old/testdir/test_substitute.vim b/test/old/testdir/test_substitute.vim
index a9e317da02..fdb0f6fc37 100644
--- a/test/old/testdir/test_substitute.vim
+++ b/test/old/testdir/test_substitute.vim
@@ -173,6 +173,16 @@ func Test_substitute_repeat()
call feedkeys("Qsc\<CR>y", 'tx')
bwipe!
endfunc
+
+" Test :s with ? as delimiter.
+func Test_substitute_question_delimiter()
+ new
+ call setline(1, '??:??')
+ %s?\?\??!!?g
+ call assert_equal('!!:!!', getline(1))
+ bwipe!
+endfunc
+
" Test %s/\n// which is implemented as a special case to use a
" more efficient join rather than doing a regular substitution.
func Test_substitute_join()
diff --git a/test/old/testdir/test_syntax.vim b/test/old/testdir/test_syntax.vim
index 711b2adf7c..35523df17d 100644
--- a/test/old/testdir/test_syntax.vim
+++ b/test/old/testdir/test_syntax.vim
@@ -197,14 +197,14 @@ func Test_syntax_completion()
" Check that clearing "Aap" avoids it showing up before Boolean.
hi @Aap ctermfg=blue
call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_match('^"syn list @Aap @attribute @boolean @character ', @:)
+ call assert_match('^"syn list @Aap @attribute @attribute.builtin @boolean @character ', @:)
hi clear @Aap
call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_match('^"syn list @attribute @boolean @character ', @:)
+ call assert_match('^"syn list @attribute @attribute.builtin @boolean @character ', @:)
call feedkeys(":syn match \<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_match('^"syn match @attribute @boolean @character ', @:)
+ call assert_match('^"syn match @attribute @attribute.builtin @boolean @character ', @:)
syn cluster Aax contains=Aap
call feedkeys(":syn list @A\<C-A>\<C-B>\"\<CR>", 'tx')
diff --git a/test/old/testdir/test_tabpage.vim b/test/old/testdir/test_tabpage.vim
index 0f038c8bee..2bd2907a55 100644
--- a/test/old/testdir/test_tabpage.vim
+++ b/test/old/testdir/test_tabpage.vim
@@ -117,10 +117,16 @@ function Test_tabpage()
call assert_equal(3, tabpagenr())
+3tabmove
call assert_equal(6, tabpagenr())
+ silent -tabmove
+ call assert_equal(5, tabpagenr())
+ silent -2 tabmove
+ call assert_equal(3, tabpagenr())
+ silent -2 tabmove
+ call assert_equal(1, tabpagenr())
- " The following are a no-op
norm! 2gt
call assert_equal(2, tabpagenr())
+ " The following are a no-op
tabmove 2
call assert_equal(2, tabpagenr())
2tabmove
diff --git a/test/old/testdir/test_tagjump.vim b/test/old/testdir/test_tagjump.vim
index ff1110e070..a614c19ce2 100644
--- a/test/old/testdir/test_tagjump.vim
+++ b/test/old/testdir/test_tagjump.vim
@@ -1551,14 +1551,14 @@ func Test_tagbsearch()
\ "third\tXfoo\t3",
\ "second\tXfoo\t2",
\ "first\tXfoo\t1"],
- \ 'Xtags')
+ \ 'Xtags', 'D')
set tags=Xtags
let code =<< trim [CODE]
int first() {}
int second() {}
int third() {}
[CODE]
- call writefile(code, 'Xfoo')
+ call writefile(code, 'Xfoo', 'D')
enew
set tagbsearch
@@ -1618,9 +1618,25 @@ func Test_tagbsearch()
\ 'Xtags')
call assert_fails('tag bbb', 'E426:')
- call delete('Xtags')
- call delete('Xfoo')
set tags& tagbsearch&
endfunc
+" Test tag guessing with very short names
+func Test_tag_guess_short()
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "y\tXf\t/^y()/"],
+ \ 'Xt', 'D')
+ set tags=Xt cpoptions+=t
+ call writefile(['', 'int * y () {}', ''], 'Xf', 'D')
+
+ let v:statusmsg = ''
+ let @/ = ''
+ ta y
+ call assert_match('E435:', v:statusmsg)
+ call assert_equal(2, line('.'))
+ call assert_match('<y', @/)
+
+ set tags& cpoptions-=t
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_termdebug.vim b/test/old/testdir/test_termdebug.vim
index 33cdaf1611..fd0c850577 100644
--- a/test/old/testdir/test_termdebug.vim
+++ b/test/old/testdir/test_termdebug.vim
@@ -232,26 +232,26 @@ endfunc
func Test_termdebug_mapping()
%bw!
- call assert_equal(maparg('K', 'n', 0, 1)->empty(), 1)
- call assert_equal(maparg('-', 'n', 0, 1)->empty(), 1)
- call assert_equal(maparg('+', 'n', 0, 1)->empty(), 1)
+ call assert_true(maparg('K', 'n', 0, 1)->empty())
+ call assert_true(maparg('-', 'n', 0, 1)->empty())
+ call assert_true(maparg('+', 'n', 0, 1)->empty())
Termdebug
call WaitForAssert({-> assert_equal(3, winnr('$'))})
wincmd b
- call assert_equal(maparg('K', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('-', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('+', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('K', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('-', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('+', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('K', 'n', 0, 1).rhs, ':Evaluate<CR>')
+ call assert_false(maparg('K', 'n', 0, 1)->empty())
+ call assert_false(maparg('-', 'n', 0, 1)->empty())
+ call assert_false(maparg('+', 'n', 0, 1)->empty())
+ call assert_false(maparg('K', 'n', 0, 1).buffer)
+ call assert_false(maparg('-', 'n', 0, 1).buffer)
+ call assert_false(maparg('+', 'n', 0, 1).buffer)
+ call assert_equal(':Evaluate<CR>', maparg('K', 'n', 0, 1).rhs)
wincmd t
quit!
redraw!
call WaitForAssert({-> assert_equal(1, winnr('$'))})
- call assert_equal(maparg('K', 'n', 0, 1)->empty(), 1)
- call assert_equal(maparg('-', 'n', 0, 1)->empty(), 1)
- call assert_equal(maparg('+', 'n', 0, 1)->empty(), 1)
+ call assert_true(maparg('K', 'n', 0, 1)->empty())
+ call assert_true(maparg('-', 'n', 0, 1)->empty())
+ call assert_true(maparg('+', 'n', 0, 1)->empty())
%bw!
nnoremap K :echom "K"<cr>
@@ -260,24 +260,24 @@ func Test_termdebug_mapping()
Termdebug
call WaitForAssert({-> assert_equal(3, winnr('$'))})
wincmd b
- call assert_equal(maparg('K', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('-', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('+', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('K', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('-', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('+', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('K', 'n', 0, 1).rhs, ':Evaluate<CR>')
+ call assert_false(maparg('K', 'n', 0, 1)->empty())
+ call assert_false(maparg('-', 'n', 0, 1)->empty())
+ call assert_false(maparg('+', 'n', 0, 1)->empty())
+ call assert_false(maparg('K', 'n', 0, 1).buffer)
+ call assert_false(maparg('-', 'n', 0, 1).buffer)
+ call assert_false(maparg('+', 'n', 0, 1).buffer)
+ call assert_equal(':Evaluate<CR>', maparg('K', 'n', 0, 1).rhs)
wincmd t
quit!
redraw!
call WaitForAssert({-> assert_equal(1, winnr('$'))})
- call assert_equal(maparg('K', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('-', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('+', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('K', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('-', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('+', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('K', 'n', 0, 1).rhs, ':echom "K"<cr>')
+ call assert_false(maparg('K', 'n', 0, 1)->empty())
+ call assert_false(maparg('-', 'n', 0, 1)->empty())
+ call assert_false(maparg('+', 'n', 0, 1)->empty())
+ call assert_false(maparg('K', 'n', 0, 1).buffer)
+ call assert_false(maparg('-', 'n', 0, 1).buffer)
+ call assert_false(maparg('+', 'n', 0, 1).buffer)
+ call assert_equal(':echom "K"<cr>', maparg('K', 'n', 0, 1).rhs)
%bw!
nnoremap <buffer> K :echom "bK"<cr>
@@ -286,20 +286,59 @@ func Test_termdebug_mapping()
Termdebug
call WaitForAssert({-> assert_equal(3, winnr('$'))})
wincmd b
- call assert_equal(maparg('K', 'n', 0, 1).buffer, 1)
- call assert_equal(maparg('-', 'n', 0, 1).buffer, 1)
- call assert_equal(maparg('+', 'n', 0, 1).buffer, 1)
+ call assert_true(maparg('K', 'n', 0, 1).buffer)
+ call assert_true(maparg('-', 'n', 0, 1).buffer)
+ call assert_true(maparg('+', 'n', 0, 1).buffer)
call assert_equal(maparg('K', 'n', 0, 1).rhs, ':echom "bK"<cr>')
wincmd t
quit!
redraw!
call WaitForAssert({-> assert_equal(1, winnr('$'))})
- call assert_equal(maparg('K', 'n', 0, 1).buffer, 1)
- call assert_equal(maparg('-', 'n', 0, 1).buffer, 1)
- call assert_equal(maparg('+', 'n', 0, 1).buffer, 1)
- call assert_equal(maparg('K', 'n', 0, 1).rhs, ':echom "bK"<cr>')
+ call assert_true(maparg('K', 'n', 0, 1).buffer)
+ call assert_true(maparg('-', 'n', 0, 1).buffer)
+ call assert_true(maparg('+', 'n', 0, 1).buffer)
+ call assert_equal(':echom "bK"<cr>', maparg('K', 'n', 0, 1).rhs)
%bw!
endfunc
+func Test_termdebug_bufnames()
+ " Test if user has filename/folders named gdb, Termdebug-gdb-console,
+ " etc. in the current directory
+ let g:termdebug_config = {}
+ let g:termdebug_config['use_prompt'] = 1
+ let filename = 'gdb'
+ let replacement_filename = 'Termdebug-gdb-console'
+
+ call writefile(['This', 'is', 'a', 'test'], filename, 'D')
+ " Throw away the file once the test has done.
+ Termdebug
+ " Once termdebug has completed the startup you should have 3 windows on screen
+ call WaitForAssert({-> assert_equal(3, winnr('$'))})
+ " A file named filename already exists in the working directory,
+ " hence you must call the newly created buffer differently
+ call WaitForAssert({-> assert_false(bufexists(filename))})
+ call WaitForAssert({-> assert_true(bufexists(replacement_filename))})
+ quit!
+ call WaitForAssert({-> assert_equal(1, winnr('$'))})
+
+ " Check if error message is in :message
+ let g:termdebug_config['disasm_window'] = 1
+ let filename = 'Termdebug-asm-listing'
+ call writefile(['This', 'is', 'a', 'test'], filename, 'D')
+ " Check only the head of the error message
+ let error_message = "You have a file/folder named '" .. filename .. "'"
+ Termdebug
+ " Once termdebug has completed the startup you should have 4 windows on screen
+ call WaitForAssert({-> assert_equal(4, winnr('$'))})
+ call WaitForAssert({-> assert_notequal(-1, stridx(execute('messages'), error_message))})
+ quit!
+ wincmd b
+ wincmd q
+ call WaitForAssert({-> assert_equal(1, winnr('$'))})
+
+ unlet g:termdebug_config
+endfunc
+
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_user_func.vim b/test/old/testdir/test_user_func.vim
index fc7dcd62b8..3c24412eb7 100644
--- a/test/old/testdir/test_user_func.vim
+++ b/test/old/testdir/test_user_func.vim
@@ -891,4 +891,23 @@ func Test_multidefer_with_exception()
delfunc Foo
endfunc
+func Test_func_curly_brace_invalid_name()
+ func Fail()
+ func Foo{'()'}bar()
+ endfunc
+ endfunc
+
+ call assert_fails('call Fail()', 'E475: Invalid argument: Foo()bar')
+
+ silent! call Fail()
+ call assert_equal([], getcompletion('Foo', 'function'))
+
+ set formatexpr=Fail()
+ normal! gqq
+ call assert_equal([], getcompletion('Foo', 'function'))
+
+ set formatexpr&
+ delfunc Fail
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_utf8.vim b/test/old/testdir/test_utf8.vim
index a5a9624ec3..51ac47f082 100644
--- a/test/old/testdir/test_utf8.vim
+++ b/test/old/testdir/test_utf8.vim
@@ -62,6 +62,9 @@ func Test_customlist_completion()
call assert_equal('"Test3 N', getreg(':'))
call garbagecollect(1)
+ delcommand Test1
+ delcommand Test2
+ delcommand Test3
endfunc
" Yank one 3 byte character and check the mark columns.
@@ -75,53 +78,6 @@ func Test_getvcol()
call assert_equal(2, virtcol("']"))
endfunc
-func Test_screenchar_utf8()
- new
-
- " 1-cell, with composing characters
- call setline(1, ["ABC\u0308"])
- redraw
- call assert_equal([0x0041], screenchars(1, 1))
- call assert_equal([0x0042], 1->screenchars(2))
- call assert_equal([0x0043, 0x0308], screenchars(1, 3))
- call assert_equal("A", screenstring(1, 1))
- call assert_equal("B", screenstring(1, 2))
- call assert_equal("C\u0308", screenstring(1, 3))
-
- " 1-cell, with 6 composing characters
- set maxcombine=6
- call setline(1, ["ABC" .. repeat("\u0308", 6)])
- redraw
- call assert_equal([0x0041], screenchars(1, 1))
- call assert_equal([0x0042], 1->screenchars(2))
- " This should not use uninitialized memory
- call assert_equal([0x0043] + repeat([0x0308], 6), screenchars(1, 3))
- call assert_equal("A", screenstring(1, 1))
- call assert_equal("B", screenstring(1, 2))
- call assert_equal("C" .. repeat("\u0308", 6), screenstring(1, 3))
- set maxcombine&
-
- " 2-cells, with composing characters
- let text = "\u3042\u3044\u3046\u3099"
- call setline(1, text)
- redraw
- call assert_equal([0x3042], screenchars(1, 1))
- call assert_equal([0], screenchars(1, 2))
- call assert_equal([0x3044], screenchars(1, 3))
- call assert_equal([0], screenchars(1, 4))
- call assert_equal([0x3046, 0x3099], screenchars(1, 5))
-
- call assert_equal("\u3042", screenstring(1, 1))
- call assert_equal("", screenstring(1, 2))
- call assert_equal("\u3044", screenstring(1, 3))
- call assert_equal("", screenstring(1, 4))
- call assert_equal("\u3046\u3099", screenstring(1, 5))
-
- call assert_equal([text . ' '], ScreenLines(1, 8))
-
- bwipe!
-endfunc
-
func Test_list2str_str2list_utf8()
" One Unicode codepoint
let s = "\u3042\u3044"
@@ -169,7 +125,55 @@ func Test_list2str_str2list_latin1()
call assert_equal(s, sres)
endfunc
+func Test_screenchar_utf8()
+ new
+
+ " 1-cell, with composing characters
+ call setline(1, ["ABC\u0308"])
+ redraw
+ call assert_equal([0x0041], screenchars(1, 1))
+ call assert_equal([0x0042], 1->screenchars(2))
+ call assert_equal([0x0043, 0x0308], screenchars(1, 3))
+ call assert_equal("A", screenstring(1, 1))
+ call assert_equal("B", screenstring(1, 2))
+ call assert_equal("C\u0308", screenstring(1, 3))
+
+ " 1-cell, with 6 composing characters
+ set maxcombine=6
+ call setline(1, ["ABC" .. repeat("\u0308", 6)])
+ redraw
+ call assert_equal([0x0041], screenchars(1, 1))
+ call assert_equal([0x0042], 1->screenchars(2))
+ " This should not use uninitialized memory
+ call assert_equal([0x0043] + repeat([0x0308], 6), screenchars(1, 3))
+ call assert_equal("A", screenstring(1, 1))
+ call assert_equal("B", screenstring(1, 2))
+ call assert_equal("C" .. repeat("\u0308", 6), screenstring(1, 3))
+ set maxcombine&
+
+ " 2-cells, with composing characters
+ let text = "\u3042\u3044\u3046\u3099"
+ call setline(1, text)
+ redraw
+ call assert_equal([0x3042], screenchars(1, 1))
+ call assert_equal([0], screenchars(1, 2))
+ call assert_equal([0x3044], screenchars(1, 3))
+ call assert_equal([0], screenchars(1, 4))
+ call assert_equal([0x3046, 0x3099], screenchars(1, 5))
+
+ call assert_equal("\u3042", screenstring(1, 1))
+ call assert_equal("", screenstring(1, 2))
+ call assert_equal("\u3044", screenstring(1, 3))
+ call assert_equal("", screenstring(1, 4))
+ call assert_equal("\u3046\u3099", screenstring(1, 5))
+
+ call assert_equal([text . ' '], ScreenLines(1, 8))
+
+ bwipe!
+endfunc
+
func Test_setcellwidths()
+ new
call setcellwidths([
\ [0x1330, 0x1330, 2],
\ [9999, 10000, 1],
@@ -212,6 +216,18 @@ func Test_setcellwidths()
" Ambiguous width chars
call assert_equal(2, strwidth("\u00A1"))
call assert_equal(2, strwidth("\u2010"))
+
+ call setcellwidths([])
+ call setline(1, repeat("\u2103", 10))
+ normal! $
+ redraw
+ call assert_equal((aw == 'single') ? 10 : 19, wincol())
+ call setcellwidths([[0x2103, 0x2103, 1]])
+ redraw
+ call assert_equal(10, wincol())
+ call setcellwidths([[0x2103, 0x2103, 2]])
+ redraw
+ call assert_equal(19, wincol())
endfor
set ambiwidth& isprint&
@@ -245,6 +261,7 @@ func Test_setcellwidths()
set listchars&
set fillchars&
call setcellwidths([])
+ bwipe!
endfunc
func Test_getcellwidths()
@@ -283,64 +300,66 @@ func Test_setcellwidths_dump()
call StopVimInTerminal(buf)
endfunc
-func Test_print_overlong()
- " Text with more composing characters than MB_MAXBYTES.
- new
- call setline(1, 'axxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
- s/x/\=nr2char(1629)/g
- print
- bwipe!
-endfunc
+" Test setcellwidths() on characters that are not targets of 'ambiwidth'.
+func Test_setcellwidths_with_non_ambiwidth_character_dump()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ call setline(1, [repeat("\u279c", 60), repeat("\u279c", 60)])
+ set ambiwidth=single
+ END
+ call writefile(lines, 'XCellwidthsWithNonAmbiwidthCharacter', 'D')
+ let buf = RunVimInTerminal('-S XCellwidthsWithNonAmbiwidthCharacter', {'rows': 6, 'cols': 50})
+ call term_sendkeys(buf, ":call setcellwidths([[0x279c, 0x279c, 1]])\<CR>")
+ call term_sendkeys(buf, ":echo\<CR>")
+ call VerifyScreenDump(buf, 'Test_setcellwidths_with_non_ambiwidth_character_dump_1', {})
-func Test_recording_with_select_mode_utf8()
- call Run_test_recording_with_select_mode_utf8()
+ call term_sendkeys(buf, ":call setcellwidths([[0x279c, 0x279c, 2]])\<CR>")
+ call term_sendkeys(buf, ":echo\<CR>")
+ call VerifyScreenDump(buf, 'Test_setcellwidths_with_non_ambiwidth_character_dump_2', {})
+
+ call StopVimInTerminal(buf)
endfunc
-func Run_test_recording_with_select_mode_utf8()
- new
+" For some reason this test causes Test_customlist_completion() to fail on CI,
+" so run it as the last test.
+func Test_zz_ambiwidth_hl_dump()
+ CheckRunVimInTerminal
- " No escaping
- call feedkeys("qacc12345\<Esc>gH哦\<Esc>q", "tx")
- call assert_equal("哦", getline(1))
- call assert_equal("cc12345\<Esc>gH哦\<Esc>", @a)
- call setline(1, 'asdf')
- normal! @a
- call assert_equal("哦", getline(1))
-
- " 固 is 0xE5 0x9B 0xBA where 0x9B is CSI
- call feedkeys("qacc12345\<Esc>gH固\<Esc>q", "tx")
- call assert_equal("固", getline(1))
- call assert_equal("cc12345\<Esc>gH固\<Esc>", @a)
- call setline(1, 'asdf')
- normal! @a
- call assert_equal("固", getline(1))
-
- " 四 is 0xE5 0x9B 0x9B where 0x9B is CSI
- call feedkeys("qacc12345\<Esc>gH四\<Esc>q", "tx")
- call assert_equal("四", getline(1))
- call assert_equal("cc12345\<Esc>gH四\<Esc>", @a)
- call setline(1, 'asdf')
- normal! @a
- call assert_equal("四", getline(1))
-
- " 倒 is 0xE5 0x80 0x92 where 0x80 is K_SPECIAL
- call feedkeys("qacc12345\<Esc>gH倒\<Esc>q", "tx")
- call assert_equal("倒", getline(1))
- call assert_equal("cc12345\<Esc>gH倒\<Esc>", @a)
- call setline(1, 'asdf')
- normal! @a
- call assert_equal("倒", getline(1))
+ let lines =<< trim END
+ call setline(1, [repeat("\u2103", 60), repeat("\u2103", 60)])
+ set ambiwidth=single cursorline list display=lastline
+ END
+ call writefile(lines, 'XAmbiwidthHl', 'D')
+ let buf = RunVimInTerminal('-S XAmbiwidthHl', {'rows': 6, 'cols': 50})
+ call VerifyScreenDump(buf, 'Test_ambiwidth_hl_dump_1', {})
- bwipe!
-endfunc
+ call term_sendkeys(buf, ":set ambiwidth=double\<CR>")
+ call term_sendkeys(buf, ":echo\<CR>")
+ call VerifyScreenDump(buf, 'Test_ambiwidth_hl_dump_2', {})
-" This must be done as one of the last tests, because it starts the GUI, which
-" cannot be undone.
-func Test_zz_recording_with_select_mode_utf8_gui()
- CheckCanRunGui
+ call term_sendkeys(buf, ":set ambiwidth=single\<CR>")
+ call term_sendkeys(buf, ":echo\<CR>")
+ call VerifyScreenDump(buf, 'Test_ambiwidth_hl_dump_1', {})
+
+ call term_sendkeys(buf, ":call setcellwidths([[0x2103, 0x2103, 2]])\<CR>")
+ call term_sendkeys(buf, ":echo\<CR>")
+ call VerifyScreenDump(buf, 'Test_ambiwidth_hl_dump_2', {})
+
+ call term_sendkeys(buf, ":call setcellwidths([[0x2103, 0x2103, 1]])\<CR>")
+ call term_sendkeys(buf, ":echo\<CR>")
+ call VerifyScreenDump(buf, 'Test_ambiwidth_hl_dump_1', {})
+
+ call StopVimInTerminal(buf)
+endfunc
- gui -f
- call Run_test_recording_with_select_mode_utf8()
+func Test_print_overlong()
+ " Text with more composing characters than MB_MAXBYTES.
+ new
+ call setline(1, 'axxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
+ s/x/\=nr2char(1629)/g
+ print
+ bwipe!
endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_virtualedit.vim b/test/old/testdir/test_virtualedit.vim
index 6448c7a3e3..8d9656e058 100644
--- a/test/old/testdir/test_virtualedit.vim
+++ b/test/old/testdir/test_virtualedit.vim
@@ -709,5 +709,27 @@ func Test_virtualedit_replace_after_tab()
bwipe!
endfunc
+" Test that setpos('.') and cursor() behave the same for v:maxcol
+func Test_virtualedit_set_cursor_pos_maxcol()
+ new
+ set virtualedit=all
+
+ call setline(1, 'foobar')
+ exe "normal! V\<Esc>"
+ call assert_equal([0, 1, 1, 0], getpos("'<"))
+ call assert_equal([0, 1, v:maxcol, 0], getpos("'>"))
+ let pos = getpos("'>")
+
+ call cursor(1, 1)
+ call setpos('.', pos)
+ call assert_equal([0, 1, 7, 0], getpos('.'))
+
+ call cursor(1, 1)
+ call cursor(pos[1:])
+ call assert_equal([0, 1, 7, 0], getpos('.'))
+
+ set virtualedit&
+ bwipe!
+endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_visual.vim b/test/old/testdir/test_visual.vim
index 4c5ab9f61f..b7b5f611c4 100644
--- a/test/old/testdir/test_visual.vim
+++ b/test/old/testdir/test_visual.vim
@@ -1151,7 +1151,7 @@ func Test_visual_inner_block()
" try to select non-existing inner block
call cursor(5, 1)
call assert_beeps('normal ViBiBiB')
- " try to select a unclosed inner block
+ " try to select an unclosed inner block
8,9d
call cursor(5, 1)
call assert_beeps('normal ViBiB')
@@ -1635,6 +1635,22 @@ func Test_visual_substitute_visual()
bwipe!
endfunc
+func Test_virtualedit_exclusive_selection()
+ new
+ set virtualedit=all selection=exclusive
+
+ call setline(1, "a\tb")
+ normal! 0v8ly
+ call assert_equal("a\t", getreg('"'))
+ normal! 0v6ly
+ call assert_equal('a ', getreg('"'))
+ normal! 06lv2ly
+ call assert_equal(' ', getreg('"'))
+
+ set virtualedit& selection&
+ bwipe!
+endfunc
+
func Test_visual_getregion()
let lines =<< trim END
new
@@ -1644,18 +1660,52 @@ func Test_visual_getregion()
#" Visual mode
call cursor(1, 1)
call feedkeys("\<ESC>vjl", 'tx')
+
call assert_equal(['one', 'tw'],
\ 'v'->getpos()->getregion(getpos('.')))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]]
+ \ ],
+ \ 'v'->getpos()->getregionpos(getpos('.')))
+
call assert_equal(['one', 'tw'],
\ '.'->getpos()->getregion(getpos('v')))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]]
+ \ ],
+ \ '.'->getpos()->getregionpos(getpos('v')))
+
call assert_equal(['o'],
\ 'v'->getpos()->getregion(getpos('v')))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
+ \ ],
+ \ 'v'->getpos()->getregionpos(getpos('v')))
+
call assert_equal(['w'],
\ '.'->getpos()->getregion(getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 0]],
+ \ ],
+ \ '.'->getpos()->getregionpos(getpos('.'), {'type': 'v' }))
+
call assert_equal(['one', 'two'],
\ getpos('.')->getregion(getpos('v'), {'type': 'V' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ ],
+ \ getpos('.')->getregionpos(getpos('v'), {'type': 'V' }))
+
call assert_equal(['on', 'tw'],
\ getpos('.')->getregion(getpos('v'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]],
+ \ ],
+ \ getpos('.')->getregionpos(getpos('v'), {'type': "\<C-v>" }))
#" Line visual mode
call cursor(1, 1)
@@ -1702,6 +1752,9 @@ func Test_visual_getregion()
\ "'a"->getpos()->getregion(getpos("'a"), {'type': 'V' }))
call assert_equal(['one', 'two'],
\ "."->getpos()->getregion(getpos("'a"), {'type': "\<c-v>" }))
+ call feedkeys("\<ESC>jVj\<ESC>", 'tx')
+ call assert_equal(['two', 'three'], getregion(getpos("'<"), getpos("'>")))
+ call assert_equal(['two', 'three'], getregion(getpos("'>"), getpos("'<")))
#" Using List
call cursor(1, 1)
@@ -1721,65 +1774,264 @@ func Test_visual_getregion()
call feedkeys("\<ESC>Vjj", 'tx')
call assert_equal(['one', 'two', 'three'],
\ getregion(getpos('v'), getpos('.'), {'type': 'V' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'V' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': 'V', 'eol': v:true }))
#" Multiline with block visual mode
call cursor(1, 1)
call feedkeys("\<ESC>\<C-v>jj", 'tx')
call assert_equal(['o', 't', 't'],
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 1, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
call cursor(1, 1)
call feedkeys("\<ESC>\<C-v>jj$", 'tx')
call assert_equal(['one', 'two', 'three'],
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", 'eol': v:true }))
#" 'virtualedit'
set virtualedit=all
+
call cursor(1, 1)
call feedkeys("\<ESC>\<C-v>10ljj$", 'tx')
call assert_equal(['one ', 'two ', 'three '],
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 3]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 3]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 1]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", 'eol': v:true }))
+
+ call cursor(3, 5)
+ call feedkeys("\<ESC>\<C-v>hkk", 'tx')
+ call assert_equal([' ', ' ', 'ee'],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
+ \ [[bufnr('%'), 2, 0, 0], [bufnr('%'), 2, 0, 0]],
+ \ [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 4, 2]],
+ \ [[bufnr('%'), 2, 4, 0], [bufnr('%'), 2, 4, 2]],
+ \ [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", 'eol': v:true }))
+
+ call cursor(3, 5)
+ call feedkeys("\<ESC>\<C-v>kk", 'tx')
+ call assert_equal([' ', ' ', 'e'],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
+ \ [[bufnr('%'), 2, 0, 0], [bufnr('%'), 2, 0, 0]],
+ \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 4, 1], [bufnr('%'), 1, 4, 2]],
+ \ [[bufnr('%'), 2, 4, 1], [bufnr('%'), 2, 4, 2]],
+ \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", 'eol': v:true }))
+
+ call cursor(1, 3)
+ call feedkeys("\<ESC>vjj4l", 'tx')
+ call assert_equal(['e', 'two', 'three '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 2]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': 'v', 'eol': v:true }))
+
+ call cursor(1, 3)
+ call feedkeys("\<ESC>lvjj3l", 'tx')
+ call assert_equal(['', 'two', 'three '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 4, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 2]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': 'v', 'eol': v:true }))
+
+ call cursor(3, 5)
+ call feedkeys("\<ESC>v3l", 'tx')
+ call assert_equal(['e '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 6, 3]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': 'v', 'eol': v:true }))
+
+ call cursor(3, 5)
+ call feedkeys("\<ESC>lv3l", 'tx')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 3, 6, 0], [bufnr('%'), 3, 6, 4]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': 'v', 'eol': v:true }))
+
+ call cursor(3, 5)
+ call feedkeys("\<ESC>3lv3l", 'tx')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 3, 6, 2], [bufnr('%'), 3, 6, 6]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': 'v', 'eol': v:true }))
+
set virtualedit&
- #" Invalid position
+ #" using wrong types for positions
call cursor(1, 1)
call feedkeys("\<ESC>vjj$", 'tx')
call assert_fails("call getregion(1, 2)", 'E1211:')
call assert_fails("call getregion(getpos('.'), {})", 'E1211:')
- call assert_equal([], getregion(getpos('.'), getpos('.'), {'type': '' }))
-
- #" using the wrong type
call assert_fails(':echo "."->getpos()->getregion("$", [])', 'E1211:')
+ call assert_fails("call getregionpos(1, 2)", 'E1211:')
+ call assert_fails("call getregionpos(getpos('.'), {})", 'E1211:')
+ call assert_fails(':echo "."->getpos()->getregionpos("$", [])', 'E1211:')
+
+ #" using invalid value for "type"
+ call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
+ call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
#" using a mark from another buffer to current buffer
new
- VAR newbuf = bufnr()
+ LET g:buf = bufnr()
call setline(1, range(10))
normal! GmA
wincmd p
- call assert_equal([newbuf, 10, 1, 0], getpos("'A"))
+ call assert_equal([g:buf, 10, 1, 0], getpos("'A"))
call assert_equal([], getregion(getpos('.'), getpos("'A"), {'type': 'v' }))
call assert_equal([], getregion(getpos("'A"), getpos('.'), {'type': 'v' }))
- exe $':{newbuf}bwipe!'
+ call assert_equal([], getregionpos(getpos('.'), getpos("'A"), {'type': 'v' }))
+ call assert_equal([], getregionpos(getpos("'A"), getpos('.'), {'type': 'v' }))
- #" using a mark from another buffer to another buffer
- new
- VAR anotherbuf = bufnr()
- call setline(1, range(10))
- normal! GmA
+ #" using two marks from another buffer
+ wincmd p
normal! GmB
wincmd p
- call assert_equal([anotherbuf, 10, 1, 0], getpos("'A"))
- call assert_equal(['9'], getregion(getpos("'B"), getpos("'A"), {'type': 'v' }))
- exe $':{anotherbuf}bwipe!'
+ call assert_equal([g:buf, 10, 1, 0], getpos("'B"))
+ call assert_equal(['9'],
+ \ getregion(getpos("'B"), getpos("'A"), {'type': 'v' }))
+ call assert_equal([
+ \ [[g:buf, 10, 1, 0], [g:buf, 10, 1, 0]],
+ \ ],
+ \ getregionpos(getpos("'B"), getpos("'A"), {'type': 'v' }))
+
+ #" using two positions from another buffer
+ for type in ['v', 'V', "\<C-V>"]
+ for exclusive in [v:false, v:true]
+ call assert_equal(range(10)->mapnew('string(v:val)'),
+ \ getregion([g:buf, 1, 1, 0], [g:buf, 10, 2, 0],
+ \ {'type': type, 'exclusive': exclusive }))
+ call assert_equal(range(10)->mapnew('string(v:val)'),
+ \ getregion([g:buf, 10, 2, 0], [g:buf, 1, 1, 0],
+ \ {'type': type, 'exclusive': exclusive }))
+ call assert_equal(range(1, 10)->mapnew('repeat([[g:buf, v:val, 1, 0]], 2)'),
+ \ getregionpos([g:buf, 1, 1, 0], [g:buf, 10, 2, 0],
+ \ {'type': type, 'exclusive': exclusive }))
+ call assert_equal(range(1, 10)->mapnew('repeat([[g:buf, v:val, 1, 0]], 2)'),
+ \ getregionpos([g:buf, 10, 2, 0], [g:buf, 1, 1, 0],
+ \ {'type': type, 'exclusive': exclusive }))
+ endfor
+ endfor
+
+ #" using invalid positions in buffer
+ call assert_fails('call getregion([g:buf, 0, 1, 0], [g:buf, 10, 2, 0])', 'E966:')
+ call assert_fails('call getregion([g:buf, 10, 2, 0], [g:buf, 0, 1, 0])', 'E966:')
+ call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 11, 2, 0])', 'E966:')
+ call assert_fails('call getregion([g:buf, 11, 2, 0], [g:buf, 1, 1, 0])', 'E966:')
+ call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 10, 0, 0])', 'E964:')
+ call assert_fails('call getregion([g:buf, 10, 0, 0], [g:buf, 1, 1, 0])', 'E964:')
+ call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 10, 3, 0])', 'E964:')
+ call assert_fails('call getregion([g:buf, 10, 3, 0], [g:buf, 1, 1, 0])', 'E964:')
+ call assert_fails('call getregion([g:buf, 1, 0, 0], [g:buf, 1, 1, 0])', 'E964:')
+ call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 1, 0, 0])', 'E964:')
#" using invalid buffer
- call assert_equal([], getregion([10000, 10, 1, 0], [10000, 10, 1, 0]))
+ call assert_fails('call getregion([10000, 10, 1, 0], [10000, 10, 1, 0])', 'E681:')
+
+ exe $':{g:buf}bwipe!'
+ unlet g:buf
+ bwipe!
END
call CheckLegacyAndVim9Success(lines)
- bwipe!
-
let lines =<< trim END
#" Selection in starts or ends in the middle of a multibyte character
new
@@ -1788,35 +2040,95 @@ func Test_visual_getregion()
\ "\U0001f1e6\u00ab\U0001f1e7\u00ab\U0001f1e8\u00ab\U0001f1e9",
\ "1234567890"
\ ])
+
call cursor(1, 3)
call feedkeys("\<Esc>\<C-v>ljj", 'xt')
call assert_equal(['cd', "\u00ab ", '34'],
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
+ \ [[bufnr('%'), 2, 5, 0], [bufnr('%'), 2, 7, 1]],
+ \ [[bufnr('%'), 3, 3, 0], [bufnr('%'), 3, 4, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+
call cursor(1, 4)
call feedkeys("\<Esc>\<C-v>ljj", 'xt')
call assert_equal(['de', "\U0001f1e7", '45'],
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 5, 0]],
+ \ [[bufnr('%'), 2, 7, 0], [bufnr('%'), 2, 10, 0]],
+ \ [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+
call cursor(1, 5)
call feedkeys("\<Esc>\<C-v>jj", 'xt')
call assert_equal(['e', ' ', '5'],
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 5, 0]],
+ \ [[bufnr('%'), 2, 10, 1], [bufnr('%'), 2, 10, 2]],
+ \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 13, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 22, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ #" characterwise selection with multibyte chars
call cursor(1, 1)
call feedkeys("\<Esc>vj", 'xt')
call assert_equal(['abcdefghijk«', "\U0001f1e6"],
\ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 13, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ set selection=exclusive
+ call feedkeys('l', 'xt')
+ call assert_equal(['abcdefghijk«', "\U0001f1e6"],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 13, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
#" marks on multibyte chars
- :set selection=exclusive
call setpos("'a", [0, 1, 11, 0])
call setpos("'b", [0, 2, 16, 0])
call setpos("'c", [0, 2, 0, 0])
call cursor(1, 1)
+
call assert_equal(['ghijk', '🇨«🇩'],
- \ getregion(getpos("'a"), getpos("'b"), {'type': "\<c-v>" }))
+ \ getregion(getpos("'a"), getpos("'b"), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 7, 0], [bufnr('%'), 1, 11, 0]],
+ \ [[bufnr('%'), 2, 13, 0], [bufnr('%'), 2, 22, 0]],
+ \ ],
+ \ getregionpos(getpos("'a"), getpos("'b"), {'type': "\<C-v>" }))
+
call assert_equal(['k«', '🇦«🇧«🇨'],
\ getregion(getpos("'a"), getpos("'b"), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 11, 0], [bufnr('%'), 1, 13, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 16, 0]],
+ \ ],
+ \ getregionpos(getpos("'a"), getpos("'b"), {'type': 'v' }))
+
call assert_equal(['k«'],
\ getregion(getpos("'a"), getpos("'c"), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 11, 0], [bufnr('%'), 1, 13, 0]],
+ \ ],
+ \ getregionpos(getpos("'a"), getpos("'c"), {'type': 'v' }))
#" use inclusive selection, although 'selection' is exclusive
call setpos("'a", [0, 1, 11, 0])
@@ -1839,12 +2151,12 @@ func Test_visual_getregion()
call assert_equal(['abcdefghijk«'],
\ getregion(getpos("'a"), getpos("'b"),
\ {'type': 'V', 'exclusive': 1 }))
- :set selection&
+
+ set selection&
+ bwipe!
END
call CheckLegacyAndVim9Success(lines)
- bwipe!
-
let lines =<< trim END
#" Exclusive selection
new
@@ -1875,51 +2187,346 @@ func Test_visual_getregion()
call assert_equal(["c", "x\tz"],
\ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
set selection&
+ bwipe!
#" Exclusive selection 2
new
call setline(1, ["a\tc", "x\tz", '', ''])
+
call cursor(1, 1)
call feedkeys("\<Esc>v2l", 'xt')
call assert_equal(["a\t"],
\ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
+
call cursor(1, 1)
call feedkeys("\<Esc>v$G", 'xt')
call assert_equal(["a\tc", "x\tz", ''],
\ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
+
call cursor(1, 1)
call feedkeys("\<Esc>v$j", 'xt')
call assert_equal(["a\tc", "x\tz"],
\ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
+
call cursor(1, 1)
call feedkeys("\<Esc>\<C-v>$j", 'xt')
call assert_equal(["a\tc", "x\tz"],
\ getregion(getpos('v'), getpos('.'),
\ {'exclusive': v:true, 'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'exclusive': v:true, 'type': "\<C-v>" }))
+
call cursor(1, 1)
call feedkeys("\<Esc>\<C-v>$G", 'xt')
call assert_equal(["a", "x", '', ''],
\ getregion(getpos('v'), getpos('.'),
\ {'exclusive': v:true, 'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ [[bufnr('%'), 4, 0, 0], [bufnr('%'), 4, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'exclusive': v:true, 'type': "\<C-v>" }))
+
call cursor(1, 1)
call feedkeys("\<Esc>wv2j", 'xt')
call assert_equal(["c", "x\tz"],
\ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
- #" virtualedit
+ #" 'virtualedit' with exclusive selection
set selection=exclusive
set virtualedit=all
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>vj", 'xt')
+ call assert_equal(["a\tc"],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>v8l", 'xt')
+ call assert_equal(["a\t"],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>v6l", 'xt')
+ call assert_equal(['a '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 5]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
call cursor(1, 1)
- call feedkeys("\<Esc>2lv2lj", 'xt')
+ call feedkeys("\<Esc>6lv2l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 2, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>lv2l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>2lv2l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call feedkeys('j', 'xt')
call assert_equal([' c', 'x '],
\ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 3]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>6l\<C-v>2lj", 'xt')
+ call assert_equal([' ', ' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 2, 7]],
+ \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 2, 7]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>l\<C-v>2l2j", 'xt')
+ call assert_equal([' ', ' ', ' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
+ \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 2]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
+ \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 2]],
+ \ [[bufnr('%'), 3, 1, 1], [bufnr('%'), 3, 1, 3]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", "eol": v:true }))
+
call cursor(1, 1)
call feedkeys("\<Esc>2l\<C-v>2l2j", 'xt')
call assert_equal([' ', ' ', ' '],
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
- set virtualedit&
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
+ \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 3]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
+ \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 3]],
+ \ [[bufnr('%'), 3, 1, 2], [bufnr('%'), 3, 1, 4]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", "eol": v:true }))
+
+ #" 'virtualedit' with inclusive selection
set selection&
+ call cursor(1, 1)
+ call feedkeys("\<Esc>vj", 'xt')
+ call assert_equal(["a\tc", 'x'],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>v8l", 'xt')
+ call assert_equal(["a\tc"],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>v6l", 'xt')
+ call assert_equal(['a '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 6]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>6lv2l", 'xt')
+ call assert_equal([' c'],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>lv2l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>2lv2l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call feedkeys('j', 'xt')
+ call assert_equal([' c', 'x '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 4]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>6l\<C-v>2lj", 'xt')
+ call assert_equal([' c', ' z'],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>l\<C-v>2l2j", 'xt')
+ call assert_equal([' ', ' ', ' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
+ \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 3]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
+ \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 3]],
+ \ [[bufnr('%'), 3, 1, 1], [bufnr('%'), 3, 1, 4]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", "eol": v:true }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>2l\<C-v>2l2j", 'xt')
+ call assert_equal([' ', ' ', ' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
+ \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 4]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
+ \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 4]],
+ \ [[bufnr('%'), 3, 1, 2], [bufnr('%'), 3, 1, 5]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", "eol": v:true }))
+
+ set virtualedit&
+ bwipe!
+ END
+ call CheckLegacyAndVim9Success(lines)
+
+ let lines =<< trim END
+ #" 'virtualedit' with TABs at end of line
+ new
+ set virtualedit=all
+ call setline(1, ["\t", "a\t", "aa\t"])
+
+ call feedkeys("gg06l\<C-v>3l2j", 'xt')
+ call assert_equal([' ', ' ', ' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 1, 0]],
+ \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 2, 0]],
+ \ [[bufnr('%'), 3, 3, 4], [bufnr('%'), 3, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 2, 2]],
+ \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 3, 2]],
+ \ [[bufnr('%'), 3, 3, 4], [bufnr('%'), 3, 4, 2]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", "eol": v:true }))
+
+ call feedkeys("gg06lv3l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 1, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 2, 2]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': 'v', "eol": v:true }))
+
+ set virtualedit&
bwipe!
END
call CheckLegacyAndVim9Success(lines)
@@ -1935,7 +2542,41 @@ func Test_getregion_invalid_buf()
call assert_equal(['Move around:'], getregion(getpos("'A"), getpos("'B")))
" close the help window
q
- call assert_equal([], getregion(getpos("'A"), getpos("'B")))
+ call assert_fails("call getregion(getpos(\"'A\"), getpos(\"'B\"))", 'E681:')
+ bwipe!
+endfunc
+
+func Test_getregion_maxcol()
+ new
+ autocmd TextYankPost *
+ \ : if v:event.operator ==? 'y'
+ \ | call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
+ \ ],
+ \ getregionpos(getpos("'["), getpos("']"),
+ \ #{ mode: visualmode() }))
+ \ | call assert_equal(['abcd'],
+ \ getregion(getpos("'["), getpos("']"),
+ \ #{ mode: visualmode() }))
+ \ | call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
+ \ ],
+ \ getregionpos(getpos("']"), getpos("'["),
+ \ #{ mode: visualmode() }))
+ \ | call assert_equal(['abcd'],
+ \ getregion(getpos("']"), getpos("'["),
+ \ #{ mode: visualmode() }))
+ \ | endif
+ call setline(1, ['abcd', 'efghij'])
+ normal yy
+ bwipe!
+endfunc
+
+func Test_visual_block_cursor_delete()
+ new
+ call setline(1, 'ab')
+ exe ":norm! $\<c-v>hI\<Del>\<ESC>"
+ call assert_equal(['b'], getline(1, 1))
bwipe!
endfunc
diff --git a/test/old/testdir/test_window_cmd.vim b/test/old/testdir/test_window_cmd.vim
index da1711a0a1..50da2beb40 100644
--- a/test/old/testdir/test_window_cmd.vim
+++ b/test/old/testdir/test_window_cmd.vim
@@ -113,64 +113,6 @@ func Test_window_quit()
bw Xa Xb
endfunc
-func Test_window_curwin_not_prevwin()
- botright split
- call assert_equal(2, winnr())
- call assert_equal(1, winnr('#'))
- quit
- call assert_equal(1, winnr())
- call assert_equal(0, winnr('#'))
-
- botright split
- botright split
- call assert_equal(3, winnr())
- call assert_equal(2, winnr('#'))
- 1quit
- call assert_equal(2, winnr())
- call assert_equal(1, winnr('#'))
-
- botright split
- call assert_equal(1, tabpagenr())
- call assert_equal(3, winnr())
- call assert_equal(2, winnr('#'))
- wincmd T
- call assert_equal(2, tabpagenr())
- call assert_equal(1, winnr())
- call assert_equal(0, winnr('#'))
- tabfirst
- call assert_equal(1, tabpagenr())
- call assert_equal(2, winnr())
- call assert_equal(0, winnr('#'))
-
- tabonly
- botright split
- wincmd t
- wincmd p
- call assert_equal(3, winnr())
- call assert_equal(1, winnr('#'))
- quit
- call assert_equal(2, winnr())
- call assert_equal(1, winnr('#'))
-
- botright split
- wincmd t
- wincmd p
- call assert_equal(1, tabpagenr())
- call assert_equal(3, winnr())
- call assert_equal(1, winnr('#'))
- wincmd T
- call assert_equal(2, tabpagenr())
- call assert_equal(1, winnr())
- call assert_equal(0, winnr('#'))
- tabfirst
- call assert_equal(1, tabpagenr())
- call assert_equal(2, winnr())
- call assert_equal(1, winnr('#'))
-
- tabonly
- only
-endfunc
-
func Test_window_horizontal_split()
call assert_equal(1, winnr('$'))
3wincmd s
@@ -258,6 +200,20 @@ func Test_window_split_edit_bufnr()
%bw!
endfunc
+func s:win_layout_info(tp = tabpagenr()) abort
+ return #{
+ \ layout: winlayout(a:tp),
+ \ pos_sizes: range(1, tabpagewinnr(a:tp, '$'))
+ \ ->map({_, nr -> win_getid(nr, a:tp)->getwininfo()[0]})
+ \ ->map({_, wininfo -> #{id: wininfo.winid,
+ \ row: wininfo.winrow,
+ \ col: wininfo.wincol,
+ \ width: wininfo.width,
+ \ height: wininfo.height}})
+ \ ->sort({a, b -> a.id - b.id})
+ \ }
+endfunc
+
func Test_window_split_no_room()
" N horizontal windows need >= 2*N + 1 lines:
" - 1 line + 1 status line in each window
@@ -272,6 +228,14 @@ func Test_window_split_no_room()
for s in range(1, hor_split_count) | split | endfor
call assert_fails('split', 'E36:')
+ botright vsplit
+ wincmd |
+ let info = s:win_layout_info()
+ call assert_fails('wincmd J', 'E36:')
+ call assert_fails('wincmd K', 'E36:')
+ call assert_equal(info, s:win_layout_info())
+ only
+
" N vertical windows need >= 2*(N - 1) + 1 columns:
" - 1 column + 1 separator for each window (except last window)
" - 1 column for the last window which does not have separator
@@ -284,7 +248,37 @@ func Test_window_split_no_room()
for s in range(1, ver_split_count) | vsplit | endfor
call assert_fails('vsplit', 'E36:')
+ split
+ wincmd |
+ let info = s:win_layout_info()
+ call assert_fails('wincmd H', 'E36:')
+ call assert_fails('wincmd L', 'E36:')
+ call assert_equal(info, s:win_layout_info())
+
+ " Check that the last statusline isn't lost.
+ " Set its window's width to 2 for the test.
+ wincmd j
+ set laststatus=0 winminwidth=0
+ vertical resize 2
+ " Update expected positions/sizes after the resize. Layout is unchanged.
+ let info.pos_sizes = s:win_layout_info().pos_sizes
+ set winminwidth&
+ call setwinvar(winnr('k'), '&statusline', '@#')
+ let last_stl_row = win_screenpos(0)[0] - 1
+ redraw
+ call assert_equal('@#|', GetScreenStr(last_stl_row))
+ call assert_equal('~ |', GetScreenStr(&lines - &cmdheight))
+
+ call assert_fails('wincmd H', 'E36:')
+ call assert_fails('wincmd L', 'E36:')
+ call assert_equal(info, s:win_layout_info())
+ call setwinvar(winnr('k'), '&statusline', '=-')
+ redraw
+ call assert_equal('=-|', GetScreenStr(last_stl_row))
+ call assert_equal('~ |', GetScreenStr(&lines - &cmdheight))
+
%bw!
+ set laststatus&
endfunc
func Test_window_exchange()
@@ -1024,6 +1018,19 @@ func Test_win_splitmove()
leftabove split b
leftabove vsplit c
leftabove split d
+
+ " win_splitmove doesn't actually create or close any windows, so expect an
+ " unchanged winid and no WinNew/WinClosed events, like :wincmd H/J/K/L.
+ let s:triggered = []
+ augroup WinSplitMove
+ au!
+ " Nvim: WinNewPre not ported yet. Also needs full port of v9.1.0117 to pass.
+ " au WinNewPre * let s:triggered += ['WinNewPre']
+ au WinNew * let s:triggered += ['WinNew', win_getid()]
+ au WinClosed * let s:triggered += ['WinClosed', str2nr(expand('<afile>'))]
+ augroup END
+ let winid = win_getid()
+
call assert_equal(0, win_splitmove(winnr(), winnr('l')))
call assert_equal(bufname(winbufnr(1)), 'c')
call assert_equal(bufname(winbufnr(2)), 'd')
@@ -1046,6 +1053,11 @@ func Test_win_splitmove()
call assert_equal(bufname(winbufnr(3)), 'a')
call assert_equal(bufname(winbufnr(4)), 'd')
call assert_fails('call win_splitmove(winnr(), winnr("k"), v:_null_dict)', 'E1297:')
+ call assert_equal([], s:triggered)
+ call assert_equal(winid, win_getid())
+
+ unlet! s:triggered
+ au! WinSplitMove
only | bd
call assert_fails('call win_splitmove(winnr(), 123)', 'E957:')
@@ -1055,18 +1067,54 @@ func Test_win_splitmove()
tabnew
call assert_fails('call win_splitmove(1, win_getid(1, 1))', 'E957:')
tabclose
-endfunc
-func Test_floatwin_splitmove()
- vsplit
- let win2 = win_getid()
- let popup_winid = nvim_open_win(0, 0, {'relative': 'win',
- \ 'row': 3, 'col': 3, 'width': 12, 'height': 3})
- call assert_fails('call win_splitmove(popup_winid, win2)', 'E957:')
- call assert_fails('call win_splitmove(win2, popup_winid)', 'E957:')
+ split
+ augroup WinSplitMove
+ au!
+ au WinEnter * ++once call win_gotoid(win_getid(winnr('#')))
+ augroup END
+ call assert_fails('call win_splitmove(winnr(), winnr("#"))', 'E855:')
+
+ augroup WinSplitMove
+ au!
+ au WinLeave * ++once quit
+ augroup END
+ call assert_fails('call win_splitmove(winnr(), winnr("#"))', 'E855:')
+
+ split
+ split
+ augroup WinSplitMove
+ au!
+ au WinEnter * ++once let s:triggered = v:true
+ \| call assert_fails('call win_splitmove(winnr(), winnr("$"))', 'E242:')
+ \| call assert_fails('call win_splitmove(winnr("$"), winnr())', 'E242:')
+ augroup END
+ quit
+ call assert_equal(v:true, s:triggered)
+ unlet! s:triggered
+
+ new
+ augroup WinSplitMove
+ au!
+ au BufHidden * ++once let s:triggered = v:true
+ \| call assert_fails('call win_splitmove(winnr(), winnr("#"))', 'E1159:')
+ augroup END
+ hide
+ call assert_equal(v:true, s:triggered)
+ unlet! s:triggered
- call nvim_win_close(popup_winid, 1)
- bwipe
+ split
+ let close_win = winnr('#')
+ augroup WinSplitMove
+ au!
+ au WinEnter * ++once quit!
+ augroup END
+ call win_splitmove(close_win, winnr())
+ call assert_equal(0, win_id2win(close_win))
+
+ au! WinSplitMove
+ augroup! WinSplitMove
+ %bw!
endfunc
" Test for the :only command
@@ -2006,24 +2054,160 @@ func Test_new_help_window_on_error()
call assert_equal(expand("<cword>"), "'mod'")
endfunc
-func Test_smoothscroll_in_zero_width_window()
- let save_lines = &lines
- let save_columns = &columns
+func Test_splitmove_flatten_frame()
+ split
+ vsplit
- winsize 0 24
- set cpo+=n
- exe "noremap 0 \<C-W>n\<C-W>L"
- norm 000000
- set number smoothscroll
- exe "norm \<C-Y>"
+ wincmd L
+ let layout = winlayout()
+ wincmd K
+ wincmd L
+ call assert_equal(winlayout(), layout)
only!
- let &lines = save_lines
- let &columns = save_columns
- set cpo-=n
- unmap 0
- set nonumber nosmoothscroll
endfunc
+func Test_autocmd_window_force_room()
+ " Open as many windows as possible
+ while v:true
+ try
+ split
+ catch /E36:/
+ break
+ endtry
+ endwhile
+ while v:true
+ try
+ vsplit
+ catch /E36:/
+ break
+ endtry
+ endwhile
+
+ wincmd j
+ vsplit
+ call assert_fails('wincmd H', 'E36:')
+ call assert_fails('wincmd J', 'E36:')
+ call assert_fails('wincmd K', 'E36:')
+ call assert_fails('wincmd L', 'E36:')
+
+ edit unload me
+ enew
+ bunload! unload\ me
+ augroup AucmdWinForceRoom
+ au!
+ au BufEnter * ++once let s:triggered = v:true
+ \| call assert_equal('autocmd', win_gettype())
+ augroup END
+ let info = s:win_layout_info()
+ " bufload opening the autocommand window shouldn't give E36.
+ call bufload('unload me')
+ call assert_equal(v:true, s:triggered)
+ call assert_equal(info, s:win_layout_info())
+
+ unlet! s:triggered
+ au! AucmdWinForceRoom
+ augroup! AucmdWinForceRoom
+ %bw!
+endfunc
+
+func Test_win_gotoid_splitmove_textlock_cmdwin()
+ call setline(1, 'foo')
+ new
+ let curwin = win_getid()
+ call setline(1, 'bar')
+
+ set debug+=throw indentexpr=win_gotoid(win_getid(winnr('#')))
+ call assert_fails('normal! ==', 'E565:')
+ call assert_equal(curwin, win_getid())
+ " No error if attempting to switch to curwin; nothing happens.
+ set indentexpr=assert_equal(1,win_gotoid(win_getid()))
+ normal! ==
+ call assert_equal(curwin, win_getid())
+
+ set indentexpr=win_splitmove(winnr('#'),winnr())
+ call assert_fails('normal! ==', 'E565:')
+ call assert_equal(curwin, win_getid())
+
+ %bw!
+ set debug-=throw indentexpr&
+
+ call feedkeys('q:'
+ \ .. ":call assert_fails('call win_splitmove(winnr(''#''), winnr())', 'E11:')\<CR>"
+ \ .. ":call assert_equal('command', win_gettype())\<CR>"
+ \ .. ":call assert_equal('', win_gettype(winnr('#')))\<CR>", 'ntx')
+
+ call feedkeys('q:'
+ \ .. ":call assert_fails('call win_gotoid(win_getid(winnr(''#'')))', 'E11:')\<CR>"
+ "\ No error if attempting to switch to curwin; nothing happens.
+ \ .. ":call assert_equal(1, win_gotoid(win_getid()))\<CR>"
+ \ .. ":call assert_equal('command', win_gettype())\<CR>"
+ \ .. ":call assert_equal('', win_gettype(winnr('#')))\<CR>", 'ntx')
+endfunc
+
+func Test_winfixsize_positions()
+ " Check positions are correct when closing a window in a non-current tabpage
+ " causes non-adjacent window to fill the space due to 'winfix{width,height}'.
+ tabnew
+ vsplit
+ wincmd |
+ split
+ set winfixheight
+ split foo
+ tabfirst
+
+ bwipe! foo
+ " Save actual values before entering the tabpage.
+ let info = s:win_layout_info(2)
+ tabnext
+ " Compare it with the expected value (after win_comp_pos) from entering.
+ call assert_equal(s:win_layout_info(), info)
+
+ $tabnew
+ split
+ split
+ wincmd k
+ belowright vsplit
+ set winfixwidth
+ belowright vsplit foo
+ tabprevious
+
+ bwipe! foo
+ " Save actual values before entering the tabpage.
+ let info = s:win_layout_info(3)
+ tabnext
+ " Compare it with the expected value (after win_comp_pos) from entering.
+ call assert_equal(s:win_layout_info(), info)
+
+ " Check positions unchanged when failing to move a window, if 'winfix{width,
+ " height}' would otherwise cause a non-adjacent window to fill the space.
+ %bwipe
+ call assert_fails('execute "split|"->repeat(&lines)', 'E36:')
+ wincmd p
+ vsplit
+ set winfixwidth
+ vsplit
+ set winfixwidth
+ vsplit
+ vsplit
+ set winfixwidth
+ wincmd p
+
+ let info = s:win_layout_info()
+ call assert_fails('wincmd J', 'E36:')
+ call assert_equal(info, s:win_layout_info())
+
+ only
+ call assert_fails('execute "vsplit|"->repeat(&columns)', 'E36:')
+ belowright split
+ set winfixheight
+ belowright split
+
+ let info = s:win_layout_info()
+ call assert_fails('wincmd H', 'E36:')
+ call assert_equal(info, s:win_layout_info())
+
+ %bwipe
+endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_winfixbuf.vim b/test/old/testdir/test_winfixbuf.vim
new file mode 100644
index 0000000000..b41eaf3c9b
--- /dev/null
+++ b/test/old/testdir/test_winfixbuf.vim
@@ -0,0 +1,3358 @@
+" Test 'winfixbuf'
+
+source check.vim
+source shared.vim
+
+" Find the number of open windows in the current tab
+func s:get_windows_count()
+ return tabpagewinnr(tabpagenr(), '$')
+endfunc
+
+" Create some unnamed buffers.
+func s:make_buffers_list()
+ enew
+ file first
+ let l:first = bufnr()
+
+ enew
+ file middle
+ let l:middle = bufnr()
+
+ enew
+ file last
+ let l:last = bufnr()
+
+ set winfixbuf
+
+ return [l:first, l:last]
+endfunc
+
+" Create some unnamed buffers and add them to an args list
+func s:make_args_list()
+ let [l:first, l:last] = s:make_buffers_list()
+
+ args! first middle last
+
+ return [l:first, l:last]
+endfunc
+
+" Create two buffers and then set the window to 'winfixbuf'
+func s:make_buffer_pairs(...)
+ let l:reversed = get(a:, 1, 0)
+
+ if l:reversed == 1
+ enew
+ file original
+
+ set winfixbuf
+
+ enew!
+ file other
+ let l:other = bufnr()
+
+ return l:other
+ endif
+
+ enew
+ file other
+ let l:other = bufnr()
+
+ enew
+ file current
+
+ set winfixbuf
+
+ return l:other
+endfunc
+
+" Create 3 quick buffers and set the window to 'winfixbuf'
+func s:make_buffer_trio()
+ edit first
+ let l:first = bufnr()
+ edit second
+ let l:second = bufnr()
+
+ set winfixbuf
+
+ edit! third
+ let l:third = bufnr()
+
+ execute ":buffer! " . l:second
+
+ return [l:first, l:second, l:third]
+endfunc
+
+" Create a location list with at least 2 entries + a 'winfixbuf' window.
+func s:make_simple_location_list()
+ enew
+ file middle
+ let l:middle = bufnr()
+ call append(0, ["winfix search-term", "another line"])
+
+ enew!
+ file first
+ let l:first = bufnr()
+ call append(0, "first search-term")
+
+ enew!
+ file last
+ let l:last = bufnr()
+ call append(0, "last search-term")
+
+ call setloclist(
+ \ 0,
+ \ [
+ \ {
+ \ "filename": "first",
+ \ "bufnr": l:first,
+ \ "lnum": 1,
+ \ },
+ \ {
+ \ "filename": "middle",
+ \ "bufnr": l:middle,
+ \ "lnum": 1,
+ \ },
+ \ {
+ \ "filename": "middle",
+ \ "bufnr": l:middle,
+ \ "lnum": 2,
+ \ },
+ \ {
+ \ "filename": "last",
+ \ "bufnr": l:last,
+ \ "lnum": 1,
+ \ },
+ \ ]
+ \)
+
+ set winfixbuf
+
+ return [l:first, l:middle, l:last]
+endfunc
+
+" Create a quickfix with at least 2 entries that are in the current 'winfixbuf' window.
+func s:make_simple_quickfix()
+ enew
+ file current
+ let l:current = bufnr()
+ call append(0, ["winfix search-term", "another line"])
+
+ enew!
+ file first
+ let l:first = bufnr()
+ call append(0, "first search-term")
+
+ enew!
+ file last
+ let l:last = bufnr()
+ call append(0, "last search-term")
+
+ call setqflist(
+ \ [
+ \ {
+ \ "filename": "first",
+ \ "bufnr": l:first,
+ \ "lnum": 1,
+ \ },
+ \ {
+ \ "filename": "current",
+ \ "bufnr": l:current,
+ \ "lnum": 1,
+ \ },
+ \ {
+ \ "filename": "current",
+ \ "bufnr": l:current,
+ \ "lnum": 2,
+ \ },
+ \ {
+ \ "filename": "last",
+ \ "bufnr": l:last,
+ \ "lnum": 1,
+ \ },
+ \ ]
+ \)
+
+ set winfixbuf
+
+ return [l:current, l:last]
+endfunc
+
+" Create a quickfix with at least 2 entries that are in the current 'winfixbuf' window.
+func s:make_quickfix_windows()
+ let [l:current, _] = s:make_simple_quickfix()
+ execute "buffer! " . l:current
+
+ split
+ let l:first_window = win_getid()
+ execute "normal \<C-w>j"
+ let l:winfix_window = win_getid()
+
+ " Open the quickfix in a separate split and go to it
+ copen
+ let l:quickfix_window = win_getid()
+
+ return [l:first_window, l:winfix_window, l:quickfix_window]
+endfunc
+
+" Revert all changes that occurred in any past test
+func s:reset_all_buffers()
+ %bwipeout!
+ set nowinfixbuf
+
+ call setqflist([])
+ call setloclist(0, [], 'f')
+
+ delmarks A-Z0-9
+endfunc
+
+" Find and set the first quickfix entry that points to `buffer`
+func s:set_quickfix_by_buffer(buffer)
+ let l:index = 1 " quickfix indices start at 1
+ for l:entry in getqflist()
+ if l:entry["bufnr"] == a:buffer
+ execute l:index . "cc"
+
+ return
+ endif
+
+ let l:index += 1
+ endfor
+
+ echoerr 'No quickfix entry matching "' . a:buffer . '" could be found.'
+endfunc
+
+" Fail to call :Next on a 'winfixbuf' window unless :Next! is used.
+func Test_Next()
+ call s:reset_all_buffers()
+
+ let [l:first, _] = s:make_args_list()
+ next!
+
+ call assert_fails("Next", "E1513:")
+ call assert_notequal(l:first, bufnr())
+
+ Next!
+ call assert_equal(l:first, bufnr())
+endfunc
+
+" Call :argdo and choose the next available 'nowinfixbuf' window.
+func Test_argdo_choose_available_window()
+ call s:reset_all_buffers()
+
+ let [_, l:last] = s:make_args_list()
+
+ " Make a split window that is 'nowinfixbuf' but make it the second-to-last
+ " window so that :argdo will first try the 'winfixbuf' window, pass over it,
+ " and prefer the other 'nowinfixbuf' window, instead.
+ "
+ " +-------------------+
+ " | 'nowinfixbuf' |
+ " +-------------------+
+ " | 'winfixbuf' | <-- Cursor is here
+ " +-------------------+
+ split
+ let l:nowinfixbuf_window = win_getid()
+ " Move to the 'winfixbuf' window now
+ execute "normal \<C-w>j"
+ let l:winfixbuf_window = win_getid()
+ let l:expected_windows = s:get_windows_count()
+
+ argdo echo ''
+ call assert_equal(l:nowinfixbuf_window, win_getid())
+ call assert_equal(l:last, bufnr())
+ call assert_equal(l:expected_windows, s:get_windows_count())
+endfunc
+
+" Call :argdo and create a new split window if all available windows are 'winfixbuf'.
+func Test_argdo_make_new_window()
+ call s:reset_all_buffers()
+
+ let [l:first, l:last] = s:make_args_list()
+ let l:current = win_getid()
+ let l:current_windows = s:get_windows_count()
+
+ argdo echo ''
+ call assert_notequal(l:current, win_getid())
+ call assert_equal(l:last, bufnr())
+ execute "normal \<C-w>j"
+ call assert_equal(l:first, bufnr())
+ call assert_equal(l:current_windows + 1, s:get_windows_count())
+endfunc
+
+" Fail :argedit but :argedit! is allowed
+func Test_argedit()
+ call s:reset_all_buffers()
+
+ args! first middle last
+ enew
+ file first
+ let l:first = bufnr()
+
+ enew
+ file middle
+ let l:middle = bufnr()
+
+ enew
+ file last
+ let l:last = bufnr()
+
+ set winfixbuf
+
+ let l:current = bufnr()
+ call assert_fails("argedit first middle last", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ argedit! first middle last
+ call assert_equal(l:first, bufnr())
+endfunc
+
+" Fail :arglocal but :arglocal! is allowed
+func Test_arglocal()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+ argglobal! other
+ execute "buffer! " . l:current
+
+ call assert_fails("arglocal other", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ arglocal! other
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Fail :argglobal but :argglobal! is allowed
+func Test_argglobal()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ call assert_fails("argglobal other", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ argglobal! other
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Fail :args but :args! is allowed
+func Test_args()
+ call s:reset_all_buffers()
+
+ let [l:first, _] = s:make_buffers_list()
+ let l:current = bufnr()
+
+ call assert_fails("args first middle last", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ args! first middle last
+ call assert_equal(l:first, bufnr())
+endfunc
+
+" Fail :bNext but :bNext! is allowed
+func Test_bNext()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ call assert_fails("bNext", "E1513:")
+ let l:current = bufnr()
+
+ call assert_equal(l:current, bufnr())
+
+ bNext!
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Allow :badd because it doesn't actually change the current window's buffer
+func Test_badd()
+ call s:reset_all_buffers()
+
+ call s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ badd other
+ call assert_equal(l:current, bufnr())
+endfunc
+
+" Allow :balt because it doesn't actually change the current window's buffer
+func Test_balt()
+ call s:reset_all_buffers()
+
+ call s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ balt other
+ call assert_equal(l:current, bufnr())
+endfunc
+
+" Fail :bfirst but :bfirst! is allowed
+func Test_bfirst()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ call assert_fails("bfirst", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ bfirst!
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Fail :blast but :blast! is allowed
+func Test_blast()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs(1)
+ bfirst!
+ let l:current = bufnr()
+
+ call assert_fails("blast", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ blast!
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Fail :bmodified but :bmodified! is allowed
+func Test_bmodified()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ execute "buffer! " . l:other
+ set modified
+ execute "buffer! " . l:current
+
+ call assert_fails("bmodified", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ bmodified!
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Fail :bnext but :bnext! is allowed
+func Test_bnext()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ call assert_fails("bnext", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ bnext!
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Fail :bprevious but :bprevious! is allowed
+func Test_bprevious()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ call assert_fails("bprevious", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ bprevious!
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Fail :brewind but :brewind! is allowed
+func Test_brewind()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ call assert_fails("brewind", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ brewind!
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Fail :browse edit but :browse edit! is allowed
+func Test_browse_edit_fail()
+ " A GUI dialog may stall the test.
+ CheckNotGui
+
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ call assert_fails("browse edit other", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ try
+ browse edit! other
+ call assert_equal(l:other, bufnr())
+ catch /^Vim\%((\a\+)\)\=:E338:/
+ " Ignore E338, which occurs if console Vim is built with +browse.
+ " Console Vim without +browse will treat this as a regular :edit.
+ endtry
+endfunc
+
+" Allow :browse w because it doesn't change the buffer in the current file
+func Test_browse_edit_pass()
+ " A GUI dialog may stall the test.
+ CheckNotGui
+
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ try
+ browse write other
+ catch /^Vim\%((\a\+)\)\=:E338:/
+ " Ignore E338, which occurs if console Vim is built with +browse.
+ " Console Vim without +browse will treat this as a regular :write.
+ endtry
+
+ call delete("other")
+endfunc
+
+" Call :bufdo and choose the next available 'nowinfixbuf' window.
+func Test_bufdo_choose_available_window()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+
+ " Make a split window that is 'nowinfixbuf' but make it the second-to-last
+ " window so that :bufdo will first try the 'winfixbuf' window, pass over it,
+ " and prefer the other 'nowinfixbuf' window, instead.
+ "
+ " +-------------------+
+ " | 'nowinfixbuf' |
+ " +-------------------+
+ " | 'winfixbuf' | <-- Cursor is here
+ " +-------------------+
+ split
+ let l:nowinfixbuf_window = win_getid()
+ " Move to the 'winfixbuf' window now
+ execute "normal \<C-w>j"
+ let l:winfixbuf_window = win_getid()
+
+ let l:current = bufnr()
+ let l:expected_windows = s:get_windows_count()
+
+ call assert_notequal(l:current, l:other)
+
+ bufdo echo ''
+ call assert_equal(l:nowinfixbuf_window, win_getid())
+ call assert_notequal(l:other, bufnr())
+ call assert_equal(l:expected_windows, s:get_windows_count())
+endfunc
+
+" Call :bufdo and create a new split window if all available windows are 'winfixbuf'.
+func Test_bufdo_make_new_window()
+ call s:reset_all_buffers()
+
+ let [l:first, l:last] = s:make_buffers_list()
+ execute "buffer! " . l:first
+ let l:current = win_getid()
+ let l:current_windows = s:get_windows_count()
+
+ bufdo echo ''
+ call assert_notequal(l:current, win_getid())
+ call assert_equal(l:last, bufnr())
+ execute "normal \<C-w>j"
+ call assert_equal(l:first, bufnr())
+ call assert_equal(l:current_windows + 1, s:get_windows_count())
+endfunc
+
+" Fail :buffer but :buffer! is allowed
+func Test_buffer()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ call assert_fails("buffer " . l:other, "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ execute "buffer! " . l:other
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Allow :buffer on a 'winfixbuf' window if there is no change in buffer
+func Test_buffer_same_buffer()
+ call s:reset_all_buffers()
+
+ call s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ execute "buffer " . l:current
+ call assert_equal(l:current, bufnr())
+
+ execute "buffer! " . l:current
+ call assert_equal(l:current, bufnr())
+endfunc
+
+" Allow :cNext but the 'nowinfixbuf' window is selected, instead
+func Test_cNext()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first_window, l:winfix_window, l:quickfix_window] = s:make_quickfix_windows()
+
+ " The call to `:cNext` succeeds but it selects the window with 'nowinfixbuf' instead
+ call s:set_quickfix_by_buffer(winbufnr(l:winfix_window))
+
+ " Make sure the previous window has 'winfixbuf' so we can test that our
+ " "skip 'winfixbuf' window" logic works.
+ call win_gotoid(l:winfix_window)
+ call win_gotoid(l:quickfix_window)
+
+ cNext
+ call assert_equal(l:first_window, win_getid())
+endfunc
+
+" Allow :cNfile but the 'nowinfixbuf' window is selected, instead
+func Test_cNfile()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first_window, l:winfix_window, l:quickfix_window] = s:make_quickfix_windows()
+
+ " The call to `:cNfile` succeeds but it selects the window with 'nowinfixbuf' instead
+ call s:set_quickfix_by_buffer(winbufnr(l:winfix_window))
+ cnext!
+
+ " Make sure the previous window has 'winfixbuf' so we can test that our
+ " "skip 'winfixbuf' window" logic works.
+ call win_gotoid(l:winfix_window)
+ call win_gotoid(l:quickfix_window)
+
+ cNfile
+ call assert_equal(l:first_window, win_getid())
+endfunc
+
+" Allow :caddexpr because it doesn't change the current buffer
+func Test_caddexpr()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let l:file_path = tempname()
+ call writefile(["Error - bad-thing-found"], l:file_path, 'D')
+ execute "edit " . l:file_path
+ let l:file_buffer = bufnr()
+ let l:current = bufnr()
+
+ edit first.unittest
+ call append(0, ["some-search-term bad-thing-found"])
+
+ edit! other.unittest
+
+ set winfixbuf
+
+ execute "buffer! " . l:file_buffer
+
+ execute 'caddexpr expand("%") .. ":" .. line(".") .. ":" .. getline(".")'
+ call assert_equal(l:current, bufnr())
+endfunc
+
+" Fail :cbuffer but :cbuffer! is allowed
+func Test_cbuffer()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let l:file_path = tempname()
+ call writefile(["first.unittest:1:Error - bad-thing-found"], l:file_path, 'D')
+ execute "edit " . l:file_path
+ let l:file_buffer = bufnr()
+ let l:current = bufnr()
+
+ edit first.unittest
+ call append(0, ["some-search-term bad-thing-found"])
+
+ edit! other.unittest
+
+ set winfixbuf
+
+ execute "buffer! " . l:file_buffer
+
+ call assert_fails("cbuffer " . l:file_buffer)
+ call assert_equal(l:current, bufnr())
+
+ execute "cbuffer! " . l:file_buffer
+ call assert_equal("first.unittest", expand("%:t"))
+endfunc
+
+" Allow :cc but the 'nowinfixbuf' window is selected, instead
+func Test_cc()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first_window, l:winfix_window, l:quickfix_window] = s:make_quickfix_windows()
+
+ " The call to `:cnext` succeeds but it selects the window with 'nowinfixbuf' instead
+ call s:set_quickfix_by_buffer(winbufnr(l:winfix_window))
+
+ " Make sure the previous window has 'winfixbuf' so we can test that our
+ " "skip 'winfixbuf' window" logic works.
+ call win_gotoid(l:winfix_window)
+ call win_gotoid(l:quickfix_window)
+ " Go up one line in the quickfix window to an quickfix entry that doesn't
+ " point to a winfixbuf buffer
+ normal k
+ " Attempt to make the previous window, winfixbuf buffer, to go to the
+ " non-winfixbuf quickfix entry
+ .cc
+
+ " Confirm that :.cc did not change the winfixbuf-enabled window
+ call assert_equal(l:first_window, win_getid())
+endfunc
+
+" Call :cdo and choose the next available 'nowinfixbuf' window.
+func Test_cdo_choose_available_window()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:current, l:last] = s:make_simple_quickfix()
+ execute "buffer! " . l:current
+
+ " Make a split window that is 'nowinfixbuf' but make it the second-to-last
+ " window so that :cdo will first try the 'winfixbuf' window, pass over it,
+ " and prefer the other 'nowinfixbuf' window, instead.
+ "
+ " +-------------------+
+ " | 'nowinfixbuf' |
+ " +-------------------+
+ " | 'winfixbuf' | <-- Cursor is here
+ " +-------------------+
+ split
+ let l:nowinfixbuf_window = win_getid()
+ " Move to the 'winfixbuf' window now
+ execute "normal \<C-w>j"
+ let l:winfixbuf_window = win_getid()
+ let l:expected_windows = s:get_windows_count()
+
+ cdo echo ''
+
+ call assert_equal(l:nowinfixbuf_window, win_getid())
+ call assert_equal(l:last, bufnr())
+ execute "normal \<C-w>j"
+ call assert_equal(l:current, bufnr())
+ call assert_equal(l:expected_windows, s:get_windows_count())
+endfunc
+
+" Call :cdo and create a new split window if all available windows are 'winfixbuf'.
+func Test_cdo_make_new_window()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:current_buffer, l:last] = s:make_simple_quickfix()
+ execute "buffer! " . l:current_buffer
+
+ let l:current_window = win_getid()
+ let l:current_windows = s:get_windows_count()
+
+ cdo echo ''
+ call assert_notequal(l:current_window, win_getid())
+ call assert_equal(l:last, bufnr())
+ execute "normal \<C-w>j"
+ call assert_equal(l:current_buffer, bufnr())
+ call assert_equal(l:current_windows + 1, s:get_windows_count())
+endfunc
+
+" Fail :cexpr but :cexpr! is allowed
+func Test_cexpr()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let l:file = tempname()
+ let l:entry = '["' . l:file . ':1:bar"]'
+ let l:current = bufnr()
+
+ set winfixbuf
+
+ call assert_fails("cexpr " . l:entry)
+ call assert_equal(l:current, bufnr())
+
+ execute "cexpr! " . l:entry
+ call assert_equal(fnamemodify(l:file, ":t"), expand("%:t"))
+endfunc
+
+" Call :cfdo and choose the next available 'nowinfixbuf' window.
+func Test_cfdo_choose_available_window()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:current, l:last] = s:make_simple_quickfix()
+ execute "buffer! " . l:current
+
+ " Make a split window that is 'nowinfixbuf' but make it the second-to-last
+ " window so that :cfdo will first try the 'winfixbuf' window, pass over it,
+ " and prefer the other 'nowinfixbuf' window, instead.
+ "
+ " +-------------------+
+ " | 'nowinfixbuf' |
+ " +-------------------+
+ " | 'winfixbuf' | <-- Cursor is here
+ " +-------------------+
+ split
+ let l:nowinfixbuf_window = win_getid()
+ " Move to the 'winfixbuf' window now
+ execute "normal \<C-w>j"
+ let l:winfixbuf_window = win_getid()
+ let l:expected_windows = s:get_windows_count()
+
+ cfdo echo ''
+
+ call assert_equal(l:nowinfixbuf_window, win_getid())
+ call assert_equal(l:last, bufnr())
+ execute "normal \<C-w>j"
+ call assert_equal(l:current, bufnr())
+ call assert_equal(l:expected_windows, s:get_windows_count())
+endfunc
+
+" Call :cfdo and create a new split window if all available windows are 'winfixbuf'.
+func Test_cfdo_make_new_window()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:current_buffer, l:last] = s:make_simple_quickfix()
+ execute "buffer! " . l:current_buffer
+
+ let l:current_window = win_getid()
+ let l:current_windows = s:get_windows_count()
+
+ cfdo echo ''
+ call assert_notequal(l:current_window, win_getid())
+ call assert_equal(l:last, bufnr())
+ execute "normal \<C-w>j"
+ call assert_equal(l:current_buffer, bufnr())
+ call assert_equal(l:current_windows + 1, s:get_windows_count())
+endfunc
+
+" Fail :cfile but :cfile! is allowed
+func Test_cfile()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ edit first.unittest
+ call append(0, ["some-search-term bad-thing-found"])
+ write
+ let l:first = bufnr()
+
+ edit! second.unittest
+ call append(0, ["some-search-term"])
+ write
+
+ let l:file = tempname()
+ call writefile(["first.unittest:1:Error - bad-thing-found was detected"], l:file)
+
+ let l:current = bufnr()
+
+ set winfixbuf
+
+ call assert_fails(":cfile " . l:file)
+ call assert_equal(l:current, bufnr())
+
+ execute ":cfile! " . l:file
+ call assert_equal(l:first, bufnr())
+
+ call delete(l:file)
+ call delete("first.unittest")
+ call delete("second.unittest")
+endfunc
+
+" Allow :cfirst but the 'nowinfixbuf' window is selected, instead
+func Test_cfirst()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first_window, l:winfix_window, l:quickfix_window] = s:make_quickfix_windows()
+
+ " The call to `:cfirst` succeeds but it selects the window with 'nowinfixbuf' instead
+ call s:set_quickfix_by_buffer(winbufnr(l:winfix_window))
+
+ " Make sure the previous window has 'winfixbuf' so we can test that our
+ " "skip 'winfixbuf' window" logic works.
+ call win_gotoid(l:winfix_window)
+ call win_gotoid(l:quickfix_window)
+
+ cfirst
+ call assert_equal(l:first_window, win_getid())
+endfunc
+
+" Allow :clast but the 'nowinfixbuf' window is selected, instead
+func Test_clast()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first_window, l:winfix_window, l:quickfix_window] = s:make_quickfix_windows()
+
+ " The call to `:clast` succeeds but it selects the window with 'nowinfixbuf' instead
+ call s:set_quickfix_by_buffer(winbufnr(l:winfix_window))
+
+ " Make sure the previous window has 'winfixbuf' so we can test that our
+ " "skip 'winfixbuf' window" logic works.
+ call win_gotoid(l:winfix_window)
+ call win_gotoid(l:quickfix_window)
+
+ clast
+ call assert_equal(l:first_window, win_getid())
+endfunc
+
+" Allow :cnext but the 'nowinfixbuf' window is selected, instead
+" Make sure no new windows are created and previous windows are reused
+func Test_cnext()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first_window, l:winfix_window, l:quickfix_window] = s:make_quickfix_windows()
+ let l:expected = s:get_windows_count()
+
+ " The call to `:cnext` succeeds but it selects the window with 'nowinfixbuf' instead
+ call s:set_quickfix_by_buffer(winbufnr(l:winfix_window))
+
+ cnext!
+ call assert_equal(l:expected, s:get_windows_count())
+
+ " Make sure the previous window has 'winfixbuf' so we can test that our
+ " "skip 'winfixbuf' window" logic works.
+ call win_gotoid(l:winfix_window)
+ call win_gotoid(l:quickfix_window)
+
+ cnext
+ call assert_equal(l:first_window, win_getid())
+ call assert_equal(l:expected, s:get_windows_count())
+endfunc
+
+" Make sure :cnext creates a split window if no previous window exists
+func Test_cnext_no_previous_window()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:current, _] = s:make_simple_quickfix()
+ execute "buffer! " . l:current
+
+ let l:expected = s:get_windows_count()
+
+ " Open the quickfix in a separate split and go to it
+ copen
+
+ call assert_equal(l:expected + 1, s:get_windows_count())
+endfunc
+
+" Allow :cnext and create a 'nowinfixbuf' window if none exists
+func Test_cnext_make_new_window()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:current, _] = s:make_simple_quickfix()
+ let l:current = win_getid()
+
+ cfirst!
+
+ let l:windows = s:get_windows_count()
+ let l:expected = l:windows + 1 " We're about to create a new split window
+
+ cnext
+ call assert_equal(l:expected, s:get_windows_count())
+
+ cnext!
+ call assert_equal(l:expected, s:get_windows_count())
+endfunc
+
+" Allow :cprevious but the 'nowinfixbuf' window is selected, instead
+func Test_cprevious()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first_window, l:winfix_window, l:quickfix_window] = s:make_quickfix_windows()
+
+ " The call to `:cprevious` succeeds but it selects the window with 'nowinfixbuf' instead
+ call s:set_quickfix_by_buffer(winbufnr(l:winfix_window))
+
+ " Make sure the previous window has 'winfixbuf' so we can test that our
+ " "skip 'winfixbuf' window" logic works.
+ call win_gotoid(l:winfix_window)
+ call win_gotoid(l:quickfix_window)
+
+ cprevious
+ call assert_equal(l:first_window, win_getid())
+endfunc
+
+" Allow :cnfile but the 'nowinfixbuf' window is selected, instead
+func Test_cnfile()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first_window, l:winfix_window, l:quickfix_window] = s:make_quickfix_windows()
+
+ " The call to `:cnfile` succeeds but it selects the window with 'nowinfixbuf' instead
+ call s:set_quickfix_by_buffer(winbufnr(l:winfix_window))
+ cnext!
+
+ " Make sure the previous window has 'winfixbuf' so we can test that our
+ " "skip 'winfixbuf' window" logic works.
+ call win_gotoid(l:winfix_window)
+ call win_gotoid(l:quickfix_window)
+
+ cnfile
+ call assert_equal(l:first_window, win_getid())
+endfunc
+
+" Allow :cpfile but the 'nowinfixbuf' window is selected, instead
+func Test_cpfile()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first_window, l:winfix_window, l:quickfix_window] = s:make_quickfix_windows()
+
+ " The call to `:cpfile` succeeds but it selects the window with 'nowinfixbuf' instead
+ call s:set_quickfix_by_buffer(winbufnr(l:winfix_window))
+ cnext!
+
+ " Make sure the previous window has 'winfixbuf' so we can test that our
+ " "skip 'winfixbuf' window" logic works.
+ call win_gotoid(l:winfix_window)
+ call win_gotoid(l:quickfix_window)
+
+ cpfile
+ call assert_equal(l:first_window, win_getid())
+endfunc
+
+" Allow :crewind but the 'nowinfixbuf' window is selected, instead
+func Test_crewind()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first_window, l:winfix_window, l:quickfix_window] = s:make_quickfix_windows()
+
+ " The call to `:crewind` succeeds but it selects the window with 'nowinfixbuf' instead
+ call s:set_quickfix_by_buffer(winbufnr(l:winfix_window))
+ cnext!
+
+ " Make sure the previous window has 'winfixbuf' so we can test that our
+ " "skip 'winfixbuf' window" logic works.
+ call win_gotoid(l:winfix_window)
+ call win_gotoid(l:quickfix_window)
+
+ crewind
+ call assert_equal(l:first_window, win_getid())
+endfunc
+
+" Allow <C-w>f because it opens in a new split
+func Test_ctrl_w_f()
+ call s:reset_all_buffers()
+
+ enew
+ let l:file_name = tempname()
+ call writefile([], l:file_name)
+ let l:file_buffer = bufnr()
+
+ enew
+ file other
+ let l:other_buffer = bufnr()
+
+ set winfixbuf
+
+ call setline(1, l:file_name)
+ let l:current_windows = s:get_windows_count()
+ execute "normal \<C-w>f"
+
+ call assert_equal(l:current_windows + 1, s:get_windows_count())
+
+ call delete(l:file_name)
+endfunc
+
+" Fail :djump but :djump! is allowed
+func Test_djump()
+ call s:reset_all_buffers()
+
+ let l:include_file = tempname() . ".h"
+ call writefile(["min(1, 12);",
+ \ '#include "' . l:include_file . '"'
+ \ ],
+ \ "main.c")
+ call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file)
+ edit main.c
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("djump 1 /min/", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ djump! 1 /min/
+ call assert_notequal(l:current, bufnr())
+
+ call delete("main.c")
+ call delete(l:include_file)
+endfunc
+
+" Fail :drop but :drop! is allowed
+func Test_drop()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ call assert_fails("drop other", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ drop! other
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Fail :edit but :edit! is allowed
+func Test_edit()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ call assert_fails("edit other", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ edit! other
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Fail :e when selecting a buffer from a relative path if in a different folder
+"
+" In this tests there's 2 buffers
+"
+" foo - lives on disk, in some folder. e.g. /tmp/foo
+" foo - an in-memory buffer that has not been saved to disk. If saved, it
+" would live in a different folder, /other/foo.
+"
+" The 'winfixbuf' is looking at the in-memory buffer and trying to switch to
+" the buffer on-disk (and fails, because it's a different buffer)
+func Test_edit_different_buffer_on_disk_and_relative_path_to_disk()
+ call s:reset_all_buffers()
+
+ let l:file_on_disk = tempname()
+ let l:directory_on_disk1 = fnamemodify(l:file_on_disk, ":p:h")
+ let l:name = fnamemodify(l:file_on_disk, ":t")
+ execute "edit " . l:file_on_disk
+ write!
+
+ let l:directory_on_disk2 = l:directory_on_disk1 . "_something_else"
+
+ if !isdirectory(l:directory_on_disk2)
+ call mkdir(l:directory_on_disk2)
+ endif
+
+ execute "cd " . l:directory_on_disk2
+ execute "edit " l:name
+
+ let l:current = bufnr()
+
+ call assert_equal(l:current, bufnr())
+ set winfixbuf
+ call assert_fails("edit " . l:file_on_disk, "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ call delete(l:directory_on_disk1)
+ call delete(l:directory_on_disk2)
+endfunc
+
+" Fail :e when selecting a buffer from a relative path if in a different folder
+"
+" In this tests there's 2 buffers
+"
+" foo - lives on disk, in some folder. e.g. /tmp/foo
+" foo - an in-memory buffer that has not been saved to disk. If saved, it
+" would live in a different folder, /other/foo.
+"
+" The 'winfixbuf' is looking at the on-disk buffer and trying to switch to
+" the in-memory buffer (and fails, because it's a different buffer)
+func Test_edit_different_buffer_on_disk_and_relative_path_to_memory()
+ call s:reset_all_buffers()
+
+ let l:file_on_disk = tempname()
+ let l:directory_on_disk1 = fnamemodify(l:file_on_disk, ":p:h")
+ let l:name = fnamemodify(l:file_on_disk, ":t")
+ execute "edit " . l:file_on_disk
+ write!
+
+ let l:directory_on_disk2 = l:directory_on_disk1 . "_something_else"
+
+ if !isdirectory(l:directory_on_disk2)
+ call mkdir(l:directory_on_disk2)
+ endif
+
+ execute "cd " . l:directory_on_disk2
+ execute "edit " l:name
+ execute "cd " . l:directory_on_disk1
+ execute "edit " l:file_on_disk
+ execute "cd " . l:directory_on_disk2
+
+ let l:current = bufnr()
+
+ call assert_equal(l:current, bufnr())
+ set winfixbuf
+ call assert_fails("edit " . l:name, "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ call delete(l:directory_on_disk1)
+ call delete(l:directory_on_disk2)
+endfunc
+
+" Fail to call `:e first` if called from a starting, in-memory buffer
+func Test_edit_first_buffer()
+ call s:reset_all_buffers()
+
+ set winfixbuf
+ let l:current = bufnr()
+
+ call assert_fails("edit first", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ edit! first
+ call assert_equal(l:current, bufnr())
+ edit! somewhere_else
+ call assert_notequal(l:current, bufnr())
+endfunc
+
+" Allow reloading a buffer using :e
+func Test_edit_no_arguments()
+ call s:reset_all_buffers()
+
+ let l:current = bufnr()
+ file some_buffer
+
+ call assert_equal(l:current, bufnr())
+ set winfixbuf
+ edit
+ call assert_equal(l:current, bufnr())
+endfunc
+
+" Allow :e selecting the current buffer
+func Test_edit_same_buffer_in_memory()
+ call s:reset_all_buffers()
+
+ let current = bufnr()
+ file same_buffer
+
+ call assert_equal(current, bufnr())
+ set winfixbuf
+ edit same_buffer
+ call assert_equal(current, bufnr())
+ set nowinfixbuf
+endfunc
+
+" Allow :e selecting the current buffer as a full path
+func Test_edit_same_buffer_on_disk_absolute_path()
+ call s:reset_all_buffers()
+
+ let file = tempname()
+ " file must exist for expansion of 8.3 paths to succeed
+ call writefile([], file, 'D')
+ let file = fnamemodify(file, ':p')
+ let current = bufnr()
+ execute "edit " . file
+ write!
+
+ call assert_equal(current, bufnr())
+ set winfixbuf
+ execute "edit " file
+ call assert_equal(current, bufnr())
+
+ set nowinfixbuf
+endfunc
+
+" Fail :enew but :enew! is allowed
+func Test_enew()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ call assert_fails("enew", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ enew!
+ call assert_notequal(l:other, bufnr())
+ call assert_notequal(3, bufnr())
+endfunc
+
+" Fail :ex but :ex! is allowed
+func Test_ex()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ call assert_fails("ex other", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ ex! other
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Fail :find but :find! is allowed
+func Test_find()
+ call s:reset_all_buffers()
+
+ let l:current = bufnr()
+ let l:file = tempname()
+ call writefile([], l:file, 'D')
+ let l:file = fnamemodify(l:file, ':p') " In case it's Windows 8.3-style.
+ let l:directory = fnamemodify(l:file, ":p:h")
+ let l:name = fnamemodify(l:file, ":p:t")
+
+ let l:original_path = &path
+ execute "set path=" . l:directory
+
+ set winfixbuf
+
+ call assert_fails("execute 'find " . l:name . "'", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ execute "find! " . l:name
+ call assert_equal(l:file, expand("%:p"))
+
+ execute "set path=" . l:original_path
+endfunc
+
+" Fail :first but :first! is allowed
+func Test_first()
+ call s:reset_all_buffers()
+
+ let [l:first, _] = s:make_args_list()
+ next!
+
+ call assert_fails("first", "E1513:")
+ call assert_notequal(l:first, bufnr())
+
+ first!
+ call assert_equal(l:first, bufnr())
+endfunc
+
+" Fail :grep but :grep! is allowed
+func Test_grep()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ edit first.unittest
+ call append(0, ["some-search-term"])
+ write
+ let l:first = bufnr()
+
+ edit current.unittest
+ call append(0, ["some-search-term"])
+ write
+ let l:current = bufnr()
+
+ edit! last.unittest
+ call append(0, ["some-search-term"])
+ write
+ let l:last = bufnr()
+
+ set winfixbuf
+
+ buffer! current.unittest
+
+ call assert_fails("silent! grep some-search-term *.unittest", "E1513:")
+ call assert_equal(l:current, bufnr())
+ execute "edit! " . l:first
+
+ silent! grep! some-search-term *.unittest
+ call assert_notequal(l:first, bufnr())
+
+ call delete("first.unittest")
+ call delete("current.unittest")
+ call delete("last.unittest")
+endfunc
+
+" Fail :ijump but :ijump! is allowed
+func Test_ijump()
+ call s:reset_all_buffers()
+
+ let l:include_file = tempname() . ".h"
+ call writefile([
+ \ '#include "' . l:include_file . '"'
+ \ ],
+ \ "main.c", 'D')
+ call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file, 'D')
+ edit main.c
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ set define=^\\s*#\\s*define
+ set include=^\\s*#\\s*include
+ set path=.,/usr/include,,
+
+ call assert_fails("ijump /min/", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ set nowinfixbuf
+
+ ijump! /min/
+ call assert_notequal(l:current, bufnr())
+
+ set define&
+ set include&
+ set path&
+endfunc
+
+" Fail :lNext but :lNext! is allowed
+func Test_lNext()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first, l:middle, _] = s:make_simple_location_list()
+ call assert_equal(1, getloclist(0, #{idx: 0}).idx)
+
+ lnext!
+ call assert_equal(2, getloclist(0, #{idx: 0}).idx)
+ call assert_equal(l:middle, bufnr())
+
+ call assert_fails("lNext", "E1513:")
+ " Ensure the entry didn't change.
+ call assert_equal(2, getloclist(0, #{idx: 0}).idx)
+ call assert_equal(l:middle, bufnr())
+
+ lnext!
+ call assert_equal(3, getloclist(0, #{idx: 0}).idx)
+ call assert_equal(l:middle, bufnr())
+
+ lNext!
+ call assert_equal(2, getloclist(0, #{idx: 0}).idx)
+ call assert_equal(l:middle, bufnr())
+
+ lNext!
+ call assert_equal(1, getloclist(0, #{idx: 0}).idx)
+ call assert_equal(l:first, bufnr())
+endfunc
+
+" Fail :lNfile but :lNfile! is allowed
+func Test_lNfile()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first, l:current, _] = s:make_simple_location_list()
+ call assert_equal(1, getloclist(0, #{idx: 0}).idx)
+
+ lnext!
+ call assert_equal(2, getloclist(0, #{idx: 0}).idx)
+ call assert_equal(l:current, bufnr())
+
+ call assert_fails("lNfile", "E1513:")
+ " Ensure the entry didn't change.
+ call assert_equal(2, getloclist(0, #{idx: 0}).idx)
+ call assert_equal(l:current, bufnr())
+
+ lnext!
+ call assert_equal(3, getloclist(0, #{idx: 0}).idx)
+ call assert_equal(l:current, bufnr())
+
+ lNfile!
+ call assert_equal(1, getloclist(0, #{idx: 0}).idx)
+ call assert_equal(l:first, bufnr())
+endfunc
+
+" Allow :laddexpr because it doesn't change the current buffer
+func Test_laddexpr()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let l:file_path = tempname()
+ call writefile(["Error - bad-thing-found"], l:file_path, 'D')
+ execute "edit " . l:file_path
+ let l:file_buffer = bufnr()
+ let l:current = bufnr()
+
+ edit first.unittest
+ call append(0, ["some-search-term bad-thing-found"])
+
+ edit! other.unittest
+
+ set winfixbuf
+
+ execute "buffer! " . l:file_buffer
+
+ execute 'laddexpr expand("%") .. ":" .. line(".") .. ":" .. getline(".")'
+ call assert_equal(l:current, bufnr())
+endfunc
+
+" Fail :last but :last! is allowed
+func Test_last()
+ call s:reset_all_buffers()
+
+ let [_, l:last] = s:make_args_list()
+ next!
+
+ call assert_fails("last", "E1513:")
+ call assert_notequal(l:last, bufnr())
+
+ last!
+ call assert_equal(l:last, bufnr())
+endfunc
+
+" Fail :lbuffer but :lbuffer! is allowed
+func Test_lbuffer()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let l:file_path = tempname()
+ call writefile(["first.unittest:1:Error - bad-thing-found"], l:file_path, 'D')
+ execute "edit " . l:file_path
+ let l:file_buffer = bufnr()
+ let l:current = bufnr()
+
+ edit first.unittest
+ call append(0, ["some-search-term bad-thing-found"])
+
+ edit! other.unittest
+
+ set winfixbuf
+
+ execute "buffer! " . l:file_buffer
+
+ call assert_fails("lbuffer " . l:file_buffer)
+ call assert_equal(l:current, bufnr())
+
+ execute "lbuffer! " . l:file_buffer
+ call assert_equal("first.unittest", expand("%:t"))
+endfunc
+
+" Fail :ldo but :ldo! is allowed
+func Test_ldo()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first, l:middle, l:last] = s:make_simple_location_list()
+ lnext!
+
+ call assert_fails('execute "ldo buffer ' . l:first . '"', "E1513:")
+ call assert_equal(l:middle, bufnr())
+ execute "ldo! buffer " . l:first
+ call assert_notequal(l:last, bufnr())
+endfunc
+
+" Fail :lfdo but :lfdo! is allowed
+func Test_lexpr()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let l:file = tempname()
+ let l:entry = '["' . l:file . ':1:bar"]'
+ let l:current = bufnr()
+
+ set winfixbuf
+
+ call assert_fails("lexpr " . l:entry)
+ call assert_equal(l:current, bufnr())
+
+ execute "lexpr! " . l:entry
+ call assert_equal(fnamemodify(l:file, ":t"), expand("%:t"))
+endfunc
+
+" Fail :lfdo but :lfdo! is allowed
+func Test_lfdo()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first, l:middle, l:last] = s:make_simple_location_list()
+ lnext!
+
+ call assert_fails('execute "lfdo buffer ' . l:first . '"', "E1513:")
+ call assert_equal(l:middle, bufnr())
+ execute "lfdo! buffer " . l:first
+ call assert_notequal(l:last, bufnr())
+endfunc
+
+" Fail :lfile but :lfile! is allowed
+func Test_lfile()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ edit first.unittest
+ call append(0, ["some-search-term bad-thing-found"])
+ write
+ let l:first = bufnr()
+
+ edit! second.unittest
+ call append(0, ["some-search-term"])
+ write
+
+ let l:file = tempname()
+ call writefile(["first.unittest:1:Error - bad-thing-found was detected"], l:file, 'D')
+
+ let l:current = bufnr()
+
+ set winfixbuf
+
+ call assert_fails(":lfile " . l:file)
+ call assert_equal(l:current, bufnr())
+
+ execute ":lfile! " . l:file
+ call assert_equal(l:first, bufnr())
+
+ call delete("first.unittest")
+ call delete("second.unittest")
+endfunc
+
+" Fail :ll but :ll! is allowed
+func Test_ll()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first, l:middle, l:last] = s:make_simple_location_list()
+ lopen
+ lfirst!
+ execute "normal \<C-w>j"
+ normal j
+
+ call assert_fails(".ll", "E1513:")
+ execute "normal \<C-w>k"
+ call assert_equal(l:first, bufnr())
+ execute "normal \<C-w>j"
+ .ll!
+ execute "normal \<C-w>k"
+ call assert_equal(l:middle, bufnr())
+endfunc
+
+" Fail :llast but :llast! is allowed
+func Test_llast()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first, _, l:last] = s:make_simple_location_list()
+ lfirst!
+
+ call assert_fails("llast", "E1513:")
+ call assert_equal(l:first, bufnr())
+
+ llast!
+ call assert_equal(l:last, bufnr())
+endfunc
+
+" Fail :lnext but :lnext! is allowed
+func Test_lnext()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first, l:middle, l:last] = s:make_simple_location_list()
+ ll!
+
+ call assert_fails("lnext", "E1513:")
+ call assert_equal(l:first, bufnr())
+
+ lnext!
+ call assert_equal(l:middle, bufnr())
+endfunc
+
+" Fail :lnfile but :lnfile! is allowed
+func Test_lnfile()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [_, l:current, l:last] = s:make_simple_location_list()
+ call assert_equal(1, getloclist(0, #{idx: 0}).idx)
+
+ lnext!
+ call assert_equal(2, getloclist(0, #{idx: 0}).idx)
+ call assert_equal(l:current, bufnr())
+
+ call assert_fails("lnfile", "E1513:")
+ " Ensure the entry didn't change.
+ call assert_equal(2, getloclist(0, #{idx: 0}).idx)
+ call assert_equal(l:current, bufnr())
+
+ lnfile!
+ call assert_equal(4, getloclist(0, #{idx: 0}).idx)
+ call assert_equal(l:last, bufnr())
+endfunc
+
+" Fail :lpfile but :lpfile! is allowed
+func Test_lpfile()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first, l:current, _] = s:make_simple_location_list()
+ lnext!
+
+ call assert_fails("lpfile", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ lnext! " Reset for the next test call
+
+ lpfile!
+ call assert_equal(l:first, bufnr())
+endfunc
+
+" Fail :lprevious but :lprevious! is allowed
+func Test_lprevious()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first, l:middle, _] = s:make_simple_location_list()
+ call assert_equal(1, getloclist(0, #{idx: 0}).idx)
+
+ lnext!
+ call assert_equal(2, getloclist(0, #{idx: 0}).idx)
+ call assert_equal(l:middle, bufnr())
+
+ call assert_fails("lprevious", "E1513:")
+ " Ensure the entry didn't change.
+ call assert_equal(2, getloclist(0, #{idx: 0}).idx)
+ call assert_equal(l:middle, bufnr())
+
+ lprevious!
+ call assert_equal(1, getloclist(0, #{idx: 0}).idx)
+ call assert_equal(l:first, bufnr())
+endfunc
+
+" Fail :lrewind but :lrewind! is allowed
+func Test_lrewind()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ let [l:first, l:middle, _] = s:make_simple_location_list()
+ lnext!
+
+ call assert_fails("lrewind", "E1513:")
+ call assert_equal(l:middle, bufnr())
+
+ lrewind!
+ call assert_equal(l:first, bufnr())
+endfunc
+
+" Fail :ltag but :ltag! is allowed
+func Test_ltag()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile\t1",
+ \ "three\tXfile\t3",
+ \ "two\tXfile\t2"],
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
+ edit Xother
+ execute "normal \<C-]>"
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("ltag one", "E1513:")
+
+ ltag! one
+
+ set tags&
+endfunc
+
+" Fail vim.cmd if we try to change buffers while 'winfixbuf' is set
+func Test_lua_command()
+ " CheckFeature lua
+ call s:reset_all_buffers()
+
+ enew
+ file first
+ let l:previous = bufnr()
+
+ enew
+ file second
+ let l:current = bufnr()
+
+ set winfixbuf
+
+ call assert_fails('lua vim.cmd("buffer " .. ' . l:previous . ')')
+ call assert_equal(l:current, bufnr())
+
+ execute 'lua vim.cmd("buffer! " .. ' . l:previous . ')'
+ call assert_equal(l:previous, bufnr())
+endfunc
+
+" Fail :lvimgrep but :lvimgrep! is allowed
+func Test_lvimgrep()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ edit first.unittest
+ call append(0, ["some-search-term"])
+ write
+
+ edit winfix.unittest
+ call append(0, ["some-search-term"])
+ write
+ let l:current = bufnr()
+
+ set winfixbuf
+
+ edit! last.unittest
+ call append(0, ["some-search-term"])
+ write
+ let l:last = bufnr()
+
+ buffer! winfix.unittest
+
+ call assert_fails("lvimgrep /some-search-term/ *.unittest", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ lvimgrep! /some-search-term/ *.unittest
+ call assert_notequal(l:current, bufnr())
+
+ call delete("first.unittest")
+ call delete("winfix.unittest")
+ call delete("last.unittest")
+endfunc
+
+" Fail :lvimgrepadd but :lvimgrepadd! is allowed
+func Test_lvimgrepadd()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ edit first.unittest
+ call append(0, ["some-search-term"])
+ write
+
+ edit winfix.unittest
+ call append(0, ["some-search-term"])
+ write
+ let l:current = bufnr()
+
+ set winfixbuf
+
+ edit! last.unittest
+ call append(0, ["some-search-term"])
+ write
+ let l:last = bufnr()
+
+ buffer! winfix.unittest
+
+ call assert_fails("lvimgrepadd /some-search-term/ *.unittest")
+ call assert_equal(l:current, bufnr())
+
+ lvimgrepadd! /some-search-term/ *.unittest
+ call assert_notequal(l:current, bufnr())
+
+ call delete("first.unittest")
+ call delete("winfix.unittest")
+ call delete("last.unittest")
+endfunc
+
+" Don't allow global marks to change the current 'winfixbuf' window
+func Test_marks_mappings_fail()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+ execute "buffer! " . l:other
+ normal mA
+ execute "buffer! " . l:current
+ normal mB
+
+ call assert_fails("normal `A", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ call assert_fails("normal 'A", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ set nowinfixbuf
+
+ normal `A
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Allow global marks in a 'winfixbuf' window if the jump is the same buffer
+func Test_marks_mappings_pass_intra_move()
+ call s:reset_all_buffers()
+
+ let l:current = bufnr()
+ call append(0, ["some line", "another line"])
+ normal mA
+ normal j
+ normal mB
+
+ set winfixbuf
+
+ normal `A
+ call assert_equal(l:current, bufnr())
+endfunc
+
+" Fail :next but :next! is allowed
+func Test_next()
+ call s:reset_all_buffers()
+
+ let [l:first, _] = s:make_args_list()
+ first!
+
+ call assert_fails("next", "E1513:")
+ call assert_equal(l:first, bufnr())
+
+ next!
+ call assert_notequal(l:first, bufnr())
+endfunc
+
+" Ensure :mksession saves 'winfixbuf' details
+func Test_mksession()
+ CheckFeature mksession
+ call s:reset_all_buffers()
+
+ set sessionoptions+=options
+ set winfixbuf
+
+ mksession test_winfixbuf_Test_mksession.vim
+
+ call s:reset_all_buffers()
+ let l:winfixbuf = &winfixbuf
+ call assert_equal(0, l:winfixbuf)
+
+ source test_winfixbuf_Test_mksession.vim
+
+ let l:winfixbuf = &winfixbuf
+ call assert_equal(1, l:winfixbuf)
+
+ set sessionoptions&
+ call delete("test_winfixbuf_Test_mksession.vim")
+endfunc
+
+" Allow :next if the next index is the same as the current buffer
+func Test_next_same_buffer()
+ call s:reset_all_buffers()
+
+ enew
+ file foo
+ enew
+ file bar
+ enew
+ file fizz
+ enew
+ file buzz
+ args foo foo bar fizz buzz
+
+ edit foo
+ set winfixbuf
+ let l:current = bufnr()
+
+ " Allow :next because the args list is `[foo] foo bar fizz buzz
+ next
+ call assert_equal(l:current, bufnr())
+
+ " Fail :next because the args list is `foo [foo] bar fizz buzz
+ " and the next buffer would be bar, which is a different buffer
+ call assert_fails("next", "E1513:")
+ call assert_equal(l:current, bufnr())
+endfunc
+
+" Fail to jump to a tag with g<C-]> if 'winfixbuf' is enabled
+func Test_normal_g_ctrl_square_bracket_right()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile\t1",
+ \ "three\tXfile\t3",
+ \ "two\tXfile\t2"],
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
+ edit Xother
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("normal g\<C-]>", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ set tags&
+endfunc
+
+" Fail to jump to a tag with g<RightMouse> if 'winfixbuf' is enabled
+func Test_normal_g_rightmouse()
+ call s:reset_all_buffers()
+ set mouse=n
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile\t1",
+ \ "three\tXfile\t3",
+ \ "two\tXfile\t2"],
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
+ edit Xother
+ execute "normal \<C-]>"
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("normal g\<RightMouse>", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ set tags&
+ set mouse&
+endfunc
+
+" Fail to jump to a tag with g] if 'winfixbuf' is enabled
+func Test_normal_g_square_bracket_right()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile\t1",
+ \ "three\tXfile\t3",
+ \ "two\tXfile\t2"],
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
+ edit Xother
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("normal g]", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ set tags&
+endfunc
+
+" Fail to jump to a tag with <C-RightMouse> if 'winfixbuf' is enabled
+func Test_normal_ctrl_rightmouse()
+ call s:reset_all_buffers()
+ set mouse=n
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile\t1",
+ \ "three\tXfile\t3",
+ \ "two\tXfile\t2"],
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
+ edit Xother
+ execute "normal \<C-]>"
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("normal \<C-RightMouse>", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ set tags&
+ set mouse&
+endfunc
+
+" Fail to jump to a tag with <C-t> if 'winfixbuf' is enabled
+func Test_normal_ctrl_t()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile\t1",
+ \ "three\tXfile\t3",
+ \ "two\tXfile\t2"],
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
+ edit Xother
+ execute "normal \<C-]>"
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("normal \<C-t>", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ set tags&
+endfunc
+
+" Disallow <C-^> in 'winfixbuf' windows
+func Test_normal_ctrl_hat()
+ call s:reset_all_buffers()
+ clearjumps
+
+ enew
+ file first
+ let l:first = bufnr()
+
+ enew
+ file current
+ let l:current = bufnr()
+
+ set winfixbuf
+
+ call assert_fails("normal \<C-^>", "E1513:")
+ call assert_equal(l:current, bufnr())
+endfunc
+
+" Allow <C-i> in 'winfixbuf' windows if the movement stays within the buffer
+func Test_normal_ctrl_i_pass()
+ call s:reset_all_buffers()
+ clearjumps
+
+ enew
+ file first
+ let l:first = bufnr()
+
+ enew!
+ file current
+ let l:current = bufnr()
+ " Add some lines so we can populate a jumplist"
+ call append(0, ["some line", "another line"])
+ " Add an entry to the jump list
+ " Go up another line
+ normal m`
+ normal k
+ execute "normal \<C-o>"
+
+ set winfixbuf
+
+ let l:line = getcurpos()[1]
+ execute "normal 1\<C-i>"
+ call assert_notequal(l:line, getcurpos()[1])
+endfunc
+
+" Disallow <C-o> in 'winfixbuf' windows if it would cause the buffer to switch
+func Test_normal_ctrl_o_fail()
+ call s:reset_all_buffers()
+ clearjumps
+
+ enew
+ file first
+ let l:first = bufnr()
+
+ enew
+ file current
+ let l:current = bufnr()
+
+ set winfixbuf
+
+ call assert_fails("normal \<C-o>", "E1513:")
+ call assert_equal(l:current, bufnr())
+endfunc
+
+" Allow <C-o> in 'winfixbuf' windows if the movement stays within the buffer
+func Test_normal_ctrl_o_pass()
+ call s:reset_all_buffers()
+ clearjumps
+
+ enew
+ file first
+ let l:first = bufnr()
+
+ enew!
+ file current
+ let l:current = bufnr()
+ " Add some lines so we can populate a jumplist
+ call append(0, ["some line", "another line"])
+ " Add an entry to the jump list
+ " Go up another line
+ normal m`
+ normal k
+
+ set winfixbuf
+
+ execute "normal \<C-o>"
+ call assert_equal(l:current, bufnr())
+endfunc
+
+" Fail to jump to a tag with <C-]> if 'winfixbuf' is enabled
+func Test_normal_ctrl_square_bracket_right()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile\t1",
+ \ "three\tXfile\t3",
+ \ "two\tXfile\t2"],
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
+ edit Xother
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("normal \<C-]>", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ set tags&
+endfunc
+
+" Allow <C-w><C-]> with 'winfixbuf' enabled because it runs in a new, split window
+func Test_normal_ctrl_w_ctrl_square_bracket_right()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile\t1",
+ \ "three\tXfile\t3",
+ \ "two\tXfile\t2"],
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
+ edit Xother
+
+ set winfixbuf
+
+ let l:current_windows = s:get_windows_count()
+ execute "normal \<C-w>\<C-]>"
+ call assert_equal(l:current_windows + 1, s:get_windows_count())
+
+ set tags&
+endfunc
+
+" Allow <C-w>g<C-]> with 'winfixbuf' enabled because it runs in a new, split window
+func Test_normal_ctrl_w_g_ctrl_square_bracket_right()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile\t1",
+ \ "three\tXfile\t3",
+ \ "two\tXfile\t2"],
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
+ edit Xother
+
+ set winfixbuf
+
+ let l:current_windows = s:get_windows_count()
+ execute "normal \<C-w>g\<C-]>"
+ call assert_equal(l:current_windows + 1, s:get_windows_count())
+
+ set tags&
+endfunc
+
+" Fail to jump to a tag with <C-]> if 'winfixbuf' is enabled
+func Test_normal_gt()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile\t1",
+ \ "three\tXfile\t3",
+ \ "two\tXfile\t2"],
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one", "two", "three"], "Xother", 'D')
+ edit Xother
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("normal \<C-]>", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ set tags&
+endfunc
+
+" Prevent gF from switching a 'winfixbuf' window's buffer
+func Test_normal_gF()
+ call s:reset_all_buffers()
+
+ let l:file = tempname()
+ call append(0, [l:file])
+ call writefile([], l:file, 'D')
+ " Place the cursor onto the line that has `l:file`
+ normal gg
+ " Prevent Vim from erroring with "No write since last change @ command
+ " line" when we try to call gF, later.
+ set hidden
+
+ set winfixbuf
+
+ let l:buffer = bufnr()
+
+ call assert_fails("normal gF", "E1513:")
+ call assert_equal(l:buffer, bufnr())
+
+ set nowinfixbuf
+
+ normal gF
+ call assert_notequal(l:buffer, bufnr())
+
+ set nohidden
+endfunc
+
+" Prevent gf from switching a 'winfixbuf' window's buffer
+func Test_normal_gf()
+ call s:reset_all_buffers()
+
+ let l:file = tempname()
+ call append(0, [l:file])
+ call writefile([], l:file, 'D')
+ " Place the cursor onto the line that has `l:file`
+ normal gg
+ " Prevent Vim from erroring with "No write since last change @ command
+ " line" when we try to call gf, later.
+ set hidden
+
+ set winfixbuf
+
+ let l:buffer = bufnr()
+
+ call assert_fails("normal gf", "E1513:")
+ call assert_equal(l:buffer, bufnr())
+
+ set nowinfixbuf
+
+ normal gf
+ call assert_notequal(l:buffer, bufnr())
+
+ set nohidden
+endfunc
+
+" Fail "goto file under the cursor" (using [f, which is the same as `:normal gf`)
+func Test_normal_square_bracket_left_f()
+ call s:reset_all_buffers()
+
+ let l:file = tempname()
+ call append(0, [l:file])
+ call writefile([], l:file, 'D')
+ " Place the cursor onto the line that has `l:file`
+ normal gg
+ " Prevent Vim from erroring with "No write since last change @ command
+ " line" when we try to call gf, later.
+ set hidden
+
+ set winfixbuf
+
+ let l:buffer = bufnr()
+
+ call assert_fails("normal [f", "E1513:")
+ call assert_equal(l:buffer, bufnr())
+
+ set nowinfixbuf
+
+ normal [f
+ call assert_notequal(l:buffer, bufnr())
+
+ set nohidden
+endfunc
+
+" Fail to go to a C macro with [<C-d> if 'winfixbuf' is enabled
+func Test_normal_square_bracket_left_ctrl_d()
+ call s:reset_all_buffers()
+
+ let l:include_file = tempname() . ".h"
+ call writefile(["min(1, 12);",
+ \ '#include "' . l:include_file . '"'
+ \ ],
+ \ "main.c", 'D')
+ call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file, 'D')
+ edit main.c
+ normal ]\<C-d>
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("normal [\<C-d>", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ set nowinfixbuf
+
+ execute "normal [\<C-d>"
+ call assert_notequal(l:current, bufnr())
+endfunc
+
+" Fail to go to a C macro with ]<C-d> if 'winfixbuf' is enabled
+func Test_normal_square_bracket_right_ctrl_d()
+ call s:reset_all_buffers()
+
+ let l:include_file = tempname() . ".h"
+ call writefile(["min(1, 12);",
+ \ '#include "' . l:include_file . '"'
+ \ ],
+ \ "main.c", 'D')
+ call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file, 'D')
+ edit main.c
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("normal ]\<C-d>", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ set nowinfixbuf
+
+ execute "normal ]\<C-d>"
+ call assert_notequal(l:current, bufnr())
+endfunc
+
+" Fail to go to a C macro with [<C-i> if 'winfixbuf' is enabled
+func Test_normal_square_bracket_left_ctrl_i()
+ call s:reset_all_buffers()
+
+ let l:include_file = tempname() . ".h"
+ call writefile(['#include "' . l:include_file . '"',
+ \ "min(1, 12);",
+ \ ],
+ \ "main.c", 'D')
+ call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file, 'D')
+ edit main.c
+ " Move to the line with `min(1, 12);` on it"
+ normal j
+
+ set define=^\\s*#\\s*define
+ set include=^\\s*#\\s*include
+ set path=.,/usr/include,,
+
+ let l:current = bufnr()
+
+ set winfixbuf
+
+ call assert_fails("normal [\<C-i>", "E1513:")
+
+ set nowinfixbuf
+
+ execute "normal [\<C-i>"
+ call assert_notequal(l:current, bufnr())
+
+ set define&
+ set include&
+ set path&
+endfunc
+
+" Fail to go to a C macro with ]<C-i> if 'winfixbuf' is enabled
+func Test_normal_square_bracket_right_ctrl_i()
+ call s:reset_all_buffers()
+
+ let l:include_file = tempname() . ".h"
+ call writefile(["min(1, 12);",
+ \ '#include "' . l:include_file . '"'
+ \ ],
+ \ "main.c", 'D')
+ call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file, 'D')
+ edit main.c
+
+ set winfixbuf
+
+ set define=^\\s*#\\s*define
+ set include=^\\s*#\\s*include
+ set path=.,/usr/include,,
+
+ let l:current = bufnr()
+
+ call assert_fails("normal ]\<C-i>", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ set nowinfixbuf
+
+ execute "normal ]\<C-i>"
+ call assert_notequal(l:current, bufnr())
+
+ set define&
+ set include&
+ set path&
+endfunc
+
+" Fail "goto file under the cursor" (using ]f, which is the same as `:normal gf`)
+func Test_normal_square_bracket_right_f()
+ call s:reset_all_buffers()
+
+ let l:file = tempname()
+ call append(0, [l:file])
+ call writefile([], l:file, 'D')
+ " Place the cursor onto the line that has `l:file`
+ normal gg
+ " Prevent Vim from erroring with "No write since last change @ command
+ " line" when we try to call gf, later.
+ set hidden
+
+ set winfixbuf
+
+ let l:buffer = bufnr()
+
+ call assert_fails("normal ]f", "E1513:")
+ call assert_equal(l:buffer, bufnr())
+
+ set nowinfixbuf
+
+ normal ]f
+ call assert_notequal(l:buffer, bufnr())
+
+ set nohidden
+endfunc
+
+" Fail to jump to a tag with v<C-]> if 'winfixbuf' is enabled
+func Test_normal_v_ctrl_square_bracket_right()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile\t1",
+ \ "three\tXfile\t3",
+ \ "two\tXfile\t2"],
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
+ edit Xother
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("normal v\<C-]>", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ set tags&
+endfunc
+
+" Fail to jump to a tag with vg<C-]> if 'winfixbuf' is enabled
+func Test_normal_v_g_ctrl_square_bracket_right()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile\t1",
+ \ "three\tXfile\t3",
+ \ "two\tXfile\t2"],
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
+ edit Xother
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("normal vg\<C-]>", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ set tags&
+endfunc
+
+" Allow :pedit because, unlike :edit, it uses a separate window
+func Test_pedit()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+
+ pedit other
+
+ execute "normal \<C-w>w"
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Fail :pop but :pop! is allowed
+func Test_pop()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "thesame\tXfile\t1;\"\td\tfile:",
+ \ "thesame\tXfile\t2;\"\td\tfile:",
+ \ "thesame\tXfile\t3;\"\td\tfile:",
+ \ ],
+ \ "Xtags", 'D')
+ call writefile(["thesame one", "thesame two", "thesame three"], "Xfile", 'D')
+ call writefile(["thesame one"], "Xother", 'D')
+ edit Xother
+
+ tag thesame
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("pop", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ pop!
+ call assert_notequal(l:current, bufnr())
+
+ set tags&
+endfunc
+
+" Fail :previous but :previous! is allowed
+func Test_previous()
+ call s:reset_all_buffers()
+
+ let [l:first, _] = s:make_args_list()
+ next!
+
+ call assert_fails("previous", "E1513:")
+ call assert_notequal(l:first, bufnr())
+
+ previous!
+ call assert_equal(l:first, bufnr())
+endfunc
+
+" Fail pyxdo if it changes a window with 'winfixbuf' is set
+func Test_pythonx_pyxdo()
+ CheckFeature pythonx
+ call s:reset_all_buffers()
+
+ enew
+ file first
+ let g:_previous_buffer = bufnr()
+
+ enew
+ file second
+
+ set winfixbuf
+
+ pythonx << EOF
+import vim
+
+def test_winfixbuf_Test_pythonx_pyxdo_set_buffer():
+ buffer = vim.vars['_previous_buffer']
+ vim.current.buffer = vim.buffers[buffer]
+EOF
+
+ try
+ pyxdo test_winfixbuf_Test_pythonx_pyxdo_set_buffer()
+ catch /pynvim\.api\.common\.NvimError: E1513:/
+ let l:caught = 1
+ endtry
+
+ call assert_equal(1, l:caught)
+
+ unlet g:_previous_buffer
+endfunc
+
+" Fail pyxfile if it changes a window with 'winfixbuf' is set
+func Test_pythonx_pyxfile()
+ CheckFeature pythonx
+ call s:reset_all_buffers()
+
+ enew
+ file first
+ let g:_previous_buffer = bufnr()
+
+ enew
+ file second
+
+ set winfixbuf
+
+ call writefile(["import vim",
+ \ "buffer = vim.vars['_previous_buffer']",
+ \ "vim.current.buffer = vim.buffers[buffer]",
+ \ ],
+ \ "file.py", 'D')
+
+ try
+ pyxfile file.py
+ catch /pynvim\.api\.common\.NvimError: E1513:/
+ let l:caught = 1
+ endtry
+
+ call assert_equal(1, l:caught)
+
+ unlet g:_previous_buffer
+endfunc
+
+" Fail vim.current.buffer if 'winfixbuf' is set
+func Test_pythonx_vim_current_buffer()
+ CheckFeature pythonx
+ call s:reset_all_buffers()
+
+ enew
+ file first
+ let g:_previous_buffer = bufnr()
+
+ enew
+ file second
+
+ let l:caught = 0
+
+ set winfixbuf
+
+ try
+ pythonx << EOF
+import vim
+
+buffer = vim.vars["_previous_buffer"]
+vim.current.buffer = vim.buffers[buffer]
+EOF
+ catch /pynvim\.api\.common\.NvimError: E1513:/
+ let l:caught = 1
+ endtry
+
+ call assert_equal(1, l:caught)
+ unlet g:_previous_buffer
+endfunc
+
+" Ensure remapping to a disabled action still triggers failures
+func Test_remap_key_fail()
+ call s:reset_all_buffers()
+
+ enew
+ file first
+ let l:first = bufnr()
+
+ enew
+ file current
+ let l:current = bufnr()
+
+ set winfixbuf
+
+ nnoremap g <C-^>
+
+ call assert_fails("normal g", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ nunmap g
+endfunc
+
+" Ensure remapping a disabled key to something valid does trigger any failures
+func Test_remap_key_pass()
+ call s:reset_all_buffers()
+
+ enew
+ file first
+ let l:first = bufnr()
+
+ enew
+ file current
+ let l:current = bufnr()
+
+ set winfixbuf
+
+ call assert_fails("normal \<C-^>", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ " Disallow <C-^> by default but allow it if the command does something else
+ nnoremap <C-^> :echo "hello!"
+
+ execute "normal \<C-^>"
+ call assert_equal(l:current, bufnr())
+
+ nunmap <C-^>
+endfunc
+
+" Fail :rewind but :rewind! is allowed
+func Test_rewind()
+ call s:reset_all_buffers()
+
+ let [l:first, _] = s:make_args_list()
+ next!
+
+ call assert_fails("rewind", "E1513:")
+ call assert_notequal(l:first, bufnr())
+
+ rewind!
+ call assert_equal(l:first, bufnr())
+endfunc
+
+" Allow :sblast because it opens the buffer in a new, split window
+func Test_sblast()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs(1)
+ bfirst!
+ let l:current = bufnr()
+
+ sblast
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Fail :sbprevious but :sbprevious! is allowed
+func Test_sbprevious()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ sbprevious
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Make sure 'winfixbuf' can be set using 'winfixbuf' or 'wfb'
+func Test_short_option()
+ call s:reset_all_buffers()
+
+ call s:make_buffer_pairs()
+
+ set winfixbuf
+ call assert_fails("edit something_else", "E1513:")
+
+ set nowinfixbuf
+ set wfb
+ call assert_fails("edit another_place", "E1513:")
+
+ set nowfb
+ edit last_place
+endfunc
+
+" Allow :snext because it makes a new window
+func Test_snext()
+ call s:reset_all_buffers()
+
+ let [l:first, _] = s:make_args_list()
+ first!
+
+ let l:current_window = win_getid()
+
+ snext
+ call assert_notequal(l:current_window, win_getid())
+ call assert_notequal(l:first, bufnr())
+endfunc
+
+" Ensure the first has 'winfixbuf' and a new split window is 'nowinfixbuf'
+func Test_split_window()
+ call s:reset_all_buffers()
+
+ split
+ execute "normal \<C-w>j"
+
+ set winfixbuf
+
+ let l:winfix_window_1 = win_getid()
+ vsplit
+ let l:winfix_window_2 = win_getid()
+
+ call assert_equal(1, getwinvar(l:winfix_window_1, "&winfixbuf"))
+ call assert_equal(0, getwinvar(l:winfix_window_2, "&winfixbuf"))
+endfunc
+
+" Fail :tNext but :tNext! is allowed
+func Test_tNext()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "thesame\tXfile\t1;\"\td\tfile:",
+ \ "thesame\tXfile\t2;\"\td\tfile:",
+ \ "thesame\tXfile\t3;\"\td\tfile:",
+ \ ],
+ \ "Xtags", 'D')
+ call writefile(["thesame one", "thesame two", "thesame three"], "Xfile", 'D')
+ call writefile(["thesame one"], "Xother", 'D')
+ edit Xother
+
+ tag thesame
+ execute "normal \<C-^>"
+ tnext!
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("tNext", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ tNext!
+
+ set tags&
+endfunc
+
+" Call :tabdo and choose the next available 'nowinfixbuf' window.
+func Test_tabdo_choose_available_window()
+ call s:reset_all_buffers()
+
+ let [l:first, _] = s:make_args_list()
+
+ " Make a split window that is 'nowinfixbuf' but make it the second-to-last
+ " window so that :tabdo will first try the 'winfixbuf' window, pass over it,
+ " and prefer the other 'nowinfixbuf' window, instead.
+ "
+ " +-------------------+
+ " | 'nowinfixbuf' |
+ " +-------------------+
+ " | 'winfixbuf' | <-- Cursor is here
+ " +-------------------+
+ split
+ let l:nowinfixbuf_window = win_getid()
+ " Move to the 'winfixbuf' window now
+ execute "normal \<C-w>j"
+ let l:winfixbuf_window = win_getid()
+
+ let l:expected_windows = s:get_windows_count()
+ tabdo echo ''
+ call assert_equal(l:nowinfixbuf_window, win_getid())
+ call assert_equal(l:first, bufnr())
+ call assert_equal(l:expected_windows, s:get_windows_count())
+endfunc
+
+" Call :tabdo and create a new split window if all available windows are 'winfixbuf'.
+func Test_tabdo_make_new_window()
+ call s:reset_all_buffers()
+
+ let [l:first, _] = s:make_buffers_list()
+ execute "buffer! " . l:first
+
+ let l:current = win_getid()
+ let l:current_windows = s:get_windows_count()
+
+ tabdo echo ''
+ call assert_notequal(l:current, win_getid())
+ call assert_equal(l:first, bufnr())
+ execute "normal \<C-w>j"
+ call assert_equal(l:first, bufnr())
+ call assert_equal(l:current_windows + 1, s:get_windows_count())
+endfunc
+
+" Fail :tag but :tag! is allowed
+func Test_tag()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile\t1",
+ \ "three\tXfile\t3",
+ \ "two\tXfile\t2"],
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
+ edit Xother
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("tag one", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ tag! one
+ call assert_notequal(l:current, bufnr())
+
+ set tags&
+endfunc
+
+
+" Fail :tfirst but :tfirst! is allowed
+func Test_tfirst()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile\t1",
+ \ "three\tXfile\t3",
+ \ "two\tXfile\t2"],
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
+ edit Xother
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("tfirst", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ tfirst!
+ call assert_notequal(l:current, bufnr())
+
+ set tags&
+endfunc
+
+" Fail :tjump but :tjump! is allowed
+func Test_tjump()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile\t1",
+ \ "three\tXfile\t3",
+ \ "two\tXfile\t2"],
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
+ edit Xother
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("tjump one", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ tjump! one
+ call assert_notequal(l:current, bufnr())
+
+ set tags&
+endfunc
+
+" Fail :tlast but :tlast! is allowed
+func Test_tlast()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile\t1",
+ \ "three\tXfile\t3",
+ \ "two\tXfile\t2"],
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ edit Xfile
+ tjump one
+ edit Xfile
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("tlast", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ tlast!
+ call assert_equal(l:current, bufnr())
+
+ set tags&
+endfunc
+
+" Fail :tnext but :tnext! is allowed
+func Test_tnext()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "thesame\tXfile\t1;\"\td\tfile:",
+ \ "thesame\tXfile\t2;\"\td\tfile:",
+ \ "thesame\tXfile\t3;\"\td\tfile:",
+ \ ],
+ \ "Xtags", 'D')
+ call writefile(["thesame one", "thesame two", "thesame three"], "Xfile", 'D')
+ call writefile(["thesame one"], "Xother", 'D')
+ edit Xother
+
+ tag thesame
+ execute "normal \<C-^>"
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("tnext", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ tnext!
+ call assert_notequal(l:current, bufnr())
+
+ set tags&
+endfunc
+
+" Fail :tprevious but :tprevious! is allowed
+func Test_tprevious()
+ call s:reset_all_buffers()
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "thesame\tXfile\t1;\"\td\tfile:",
+ \ "thesame\tXfile\t2;\"\td\tfile:",
+ \ "thesame\tXfile\t3;\"\td\tfile:",
+ \ ],
+ \ "Xtags", 'D')
+ call writefile(["thesame one", "thesame two", "thesame three"], "Xfile", 'D')
+ call writefile(["thesame one"], "Xother", 'D')
+ edit Xother
+
+ tag thesame
+ execute "normal \<C-^>"
+ tnext!
+
+ set winfixbuf
+
+ let l:current = bufnr()
+
+ call assert_fails("tprevious", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ tprevious!
+
+ set tags&
+endfunc
+
+" Fail :view but :view! is allowed
+func Test_view()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ call assert_fails("view other", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ view! other
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Fail :visual but :visual! is allowed
+func Test_visual()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+ let l:current = bufnr()
+
+ call assert_fails("visual other", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ visual! other
+ call assert_equal(l:other, bufnr())
+endfunc
+
+" Fail :vimgrep but :vimgrep! is allowed
+func Test_vimgrep()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ edit first.unittest
+ call append(0, ["some-search-term"])
+ write
+
+ edit winfix.unittest
+ call append(0, ["some-search-term"])
+ write
+ let l:current = bufnr()
+
+ set winfixbuf
+
+ edit! last.unittest
+ call append(0, ["some-search-term"])
+ write
+ let l:last = bufnr()
+
+ buffer! winfix.unittest
+
+ call assert_fails("vimgrep /some-search-term/ *.unittest")
+ call assert_equal(l:current, bufnr())
+
+ " Don't error and also do swap to the first match because ! was included
+ vimgrep! /some-search-term/ *.unittest
+ call assert_notequal(l:current, bufnr())
+
+ call delete("first.unittest")
+ call delete("winfix.unittest")
+ call delete("last.unittest")
+endfunc
+
+" Fail :vimgrepadd but ::vimgrepadd! is allowed
+func Test_vimgrepadd()
+ CheckFeature quickfix
+ call s:reset_all_buffers()
+
+ edit first.unittest
+ call append(0, ["some-search-term"])
+ write
+
+ edit winfix.unittest
+ call append(0, ["some-search-term"])
+ write
+ let l:current = bufnr()
+
+ set winfixbuf
+
+ edit! last.unittest
+ call append(0, ["some-search-term"])
+ write
+ let l:last = bufnr()
+
+ buffer! winfix.unittest
+
+ call assert_fails("vimgrepadd /some-search-term/ *.unittest")
+ call assert_equal(l:current, bufnr())
+
+ vimgrepadd! /some-search-term/ *.unittest
+ call assert_notequal(l:current, bufnr())
+ call delete("first.unittest")
+ call delete("winfix.unittest")
+ call delete("last.unittest")
+endfunc
+
+" Fail :wNext but :wNext! is allowed
+func Test_wNext()
+ call s:reset_all_buffers()
+
+ let [l:first, _] = s:make_args_list()
+ next!
+
+ call assert_fails("wNext", "E1513:")
+ call assert_notequal(l:first, bufnr())
+
+ wNext!
+ call assert_equal(l:first, bufnr())
+
+ call delete("first")
+ call delete("middle")
+ call delete("last")
+endfunc
+
+" Allow :windo unless `:windo foo` would change a 'winfixbuf' window's buffer
+func Test_windo()
+ call s:reset_all_buffers()
+
+ let l:current_window = win_getid()
+ let l:current_buffer = bufnr()
+ split
+ enew
+ file some_other_buffer
+
+ set winfixbuf
+
+ let l:current = win_getid()
+
+ windo echo ''
+ call assert_equal(l:current_window, win_getid())
+
+ call assert_fails('execute "windo buffer ' . l:current_buffer . '"', "E1513:")
+ call assert_equal(l:current_window, win_getid())
+
+ execute "windo buffer! " . l:current_buffer
+ call assert_equal(l:current_window, win_getid())
+endfunc
+
+" Fail :wnext but :wnext! is allowed
+func Test_wnext()
+ call s:reset_all_buffers()
+
+ let [_, l:last] = s:make_args_list()
+ next!
+
+ call assert_fails("wnext", "E1513:")
+ call assert_notequal(l:last, bufnr())
+
+ wnext!
+ call assert_equal(l:last, bufnr())
+
+ call delete("first")
+ call delete("middle")
+ call delete("last")
+endfunc
+
+" Fail :wprevious but :wprevious! is allowed
+func Test_wprevious()
+ call s:reset_all_buffers()
+
+ let [l:first, _] = s:make_args_list()
+ next!
+
+ call assert_fails("wprevious", "E1513:")
+ call assert_notequal(l:first, bufnr())
+
+ wprevious!
+ call assert_equal(l:first, bufnr())
+
+ call delete("first")
+ call delete("middle")
+ call delete("last")
+endfunc
+
+func Test_quickfix_switchbuf_invalid_prevwin()
+ call s:reset_all_buffers()
+
+ call s:make_simple_quickfix()
+ call assert_equal(1, getqflist(#{idx: 0}).idx)
+
+ set switchbuf=uselast
+ split
+ copen
+ execute winnr('#') 'quit'
+ call assert_equal(2, winnr('$'))
+
+ cnext " Would've triggered a null pointer member access
+ call assert_equal(2, getqflist(#{idx: 0}).idx)
+
+ set switchbuf&
+endfunc
+
+func Test_listdo_goto_prevwin()
+ call s:reset_all_buffers()
+ call s:make_buffers_list()
+
+ new
+ call assert_equal(0, &winfixbuf)
+ wincmd p
+ call assert_equal(1, &winfixbuf)
+ call assert_notequal(bufnr(), bufnr('#'))
+
+ augroup ListDoGotoPrevwin
+ au!
+ au BufLeave * let s:triggered = 1
+ \| call assert_equal(bufnr(), winbufnr(winnr()))
+ augroup END
+ " Should correctly switch to the window without 'winfixbuf', and curbuf should
+ " be consistent with curwin->w_buffer for autocommands.
+ bufdo "
+ call assert_equal(0, &winfixbuf)
+ call assert_equal(1, s:triggered)
+ unlet! s:triggered
+ au! ListDoGotoPrevwin
+
+ set winfixbuf
+ wincmd p
+ call assert_equal(2, winnr('$'))
+ " Both curwin and prevwin have 'winfixbuf' set, so should split a new window
+ " without it set.
+ bufdo "
+ call assert_equal(0, &winfixbuf)
+ call assert_equal(3, winnr('$'))
+
+ quit
+ call assert_equal(2, winnr('$'))
+ call assert_equal(1, &winfixbuf)
+ augroup ListDoGotoPrevwin
+ au!
+ au WinEnter * ++once set winfixbuf
+ augroup END
+ " Same as before, but naughty autocommands set 'winfixbuf' for the new window.
+ " :bufdo should give up in this case.
+ call assert_fails('bufdo "', 'E1513:')
+
+ au! ListDoGotoPrevwin
+ augroup! ListDoGotoPrevwin
+endfunc
+
+func Test_quickfix_changed_split_failed()
+ call s:reset_all_buffers()
+
+ call s:make_simple_quickfix()
+ call assert_equal(1, winnr('$'))
+
+ " Quickfix code will open a split in an attempt to get a 'nowinfixbuf' window
+ " to switch buffers in. Interfere with things by setting 'winfixbuf' in it.
+ augroup QfChanged
+ au!
+ au WinEnter * ++once call assert_equal(2, winnr('$'))
+ \| set winfixbuf | call setqflist([], 'f')
+ augroup END
+ call assert_fails('cnext', ['E1513:', 'E925:'])
+ " Check that the split was automatically closed.
+ call assert_equal(1, winnr('$'))
+
+ au! QfChanged
+ augroup! QfChanged
+endfunc
+
+func Test_bufdo_cnext_splitwin_fails()
+ call s:reset_all_buffers()
+ call s:make_simple_quickfix()
+ call assert_equal(1, getqflist(#{idx: 0}).idx)
+ " Make sure there is not enough room to
+ " split the winfixedbuf window
+ let &winheight=&lines
+ let &winminheight=&lines-2
+ " Still want E1513, or it may not be clear why a split was attempted and why
+ " it failing caused the commands to abort.
+ call assert_fails(':bufdo echo 1', ['E36:', 'E1513:'])
+ call assert_fails(':cnext', ['E36:', 'E1513:'])
+ " Ensure the entry didn't change.
+ call assert_equal(1, getqflist(#{idx: 0}).idx)
+ set winminheight&vim winheight&vim
+endfunc
+
+" Test that exiting with 'winfixbuf' and EXITFREE doesn't cause an error.
+func Test_exitfree_no_error()
+ let lines =<< trim END
+ set winfixbuf
+ qall!
+ END
+ call writefile(lines, 'Xwfb_exitfree', 'D')
+ call assert_notmatch('E1513:',
+ "\ system(GetVimCommandClean() .. ' --not-a-term -X -S Xwfb_exitfree'))
+ \ system(GetVimCommandClean() .. ' -X -S Xwfb_exitfree'))
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/vim9.vim b/test/old/testdir/vim9.vim
index 218fab6c5e..7d1eec7d4f 100644
--- a/test/old/testdir/vim9.vim
+++ b/test/old/testdir/vim9.vim
@@ -46,49 +46,6 @@ func CheckScriptSuccess(lines)
endtry
endfunc
-" :source a list of "lines" and check whether it fails with "error"
-func CheckSourceFailure(lines, error, lnum = -3)
- if get(a:lines, 0, '') ==# 'vim9script'
- return
- endif
- new
- call setline(1, a:lines)
- try
- call assert_fails('source', a:error, a:lines, a:lnum)
- finally
- bw!
- endtry
-endfunc
-
-" :source a list of "lines" and check whether it fails with the list of
-" "errors"
-func CheckSourceFailureList(lines, errors, lnum = -3)
- if get(a:lines, 0, '') ==# 'vim9script'
- return
- endif
- new
- call setline(1, a:lines)
- try
- call assert_fails('source', a:errors, a:lines, a:lnum)
- finally
- bw!
- endtry
-endfunc
-
-" :source a list of "lines" and check whether it succeeds
-func CheckSourceSuccess(lines)
- if get(a:lines, 0, '') ==# 'vim9script'
- return
- endif
- new
- call setline(1, a:lines)
- try
- :source
- finally
- bw!
- endtry
-endfunc
-
func CheckDefAndScriptSuccess(lines)
return
endfunc
@@ -185,3 +142,96 @@ func CheckLegacyAndVim9Failure(lines, error)
\ })
call CheckLegacyFailure(legacylines, legacyError)
endfunc
+
+" :source a list of "lines" and check whether it fails with "error"
+func CheckSourceScriptFailure(lines, error, lnum = -3)
+ if get(a:lines, 0, '') ==# 'vim9script'
+ return
+ endif
+ let cwd = getcwd()
+ new
+ call setline(1, a:lines)
+ let bnr = bufnr()
+ try
+ call assert_fails('source', a:error, a:lines, a:lnum)
+ finally
+ call chdir(cwd)
+ exe $':bw! {bnr}'
+ endtry
+endfunc
+
+" :source a list of "lines" and check whether it fails with the list of
+" "errors"
+func CheckSourceScriptFailureList(lines, errors, lnum = -3)
+ if get(a:lines, 0, '') ==# 'vim9script'
+ return
+ endif
+ let cwd = getcwd()
+ new
+ let bnr = bufnr()
+ call setline(1, a:lines)
+ try
+ call assert_fails('source', a:errors, a:lines, a:lnum)
+ finally
+ call chdir(cwd)
+ exe $':bw! {bnr}'
+ endtry
+endfunc
+
+" :source a list of "lines" and check whether it succeeds
+func CheckSourceScriptSuccess(lines)
+ if get(a:lines, 0, '') ==# 'vim9script'
+ return
+ endif
+ let cwd = getcwd()
+ new
+ let bnr = bufnr()
+ call setline(1, a:lines)
+ try
+ :source
+ finally
+ call chdir(cwd)
+ exe $':bw! {bnr}'
+ endtry
+endfunc
+
+func CheckSourceSuccess(lines)
+ call CheckSourceScriptSuccess(a:lines)
+endfunc
+
+func CheckSourceFailure(lines, error, lnum = -3)
+ call CheckSourceScriptFailure(a:lines, a:error, a:lnum)
+endfunc
+
+func CheckSourceFailureList(lines, errors, lnum = -3)
+ call CheckSourceScriptFailureList(a:lines, a:errors, a:lnum)
+endfunc
+
+func CheckSourceDefSuccess(lines)
+ return
+endfunc
+
+func CheckSourceDefAndScriptSuccess(lines)
+ return
+endfunc
+
+func CheckSourceDefCompileSuccess(lines)
+ return
+endfunc
+
+func CheckSourceDefFailure(lines, error, lnum = -3)
+ return
+endfunc
+
+func CheckSourceDefExecFailure(lines, error, lnum = -3)
+ return
+endfunc
+
+func CheckSourceDefAndScriptFailure(lines, error, lnum = -3)
+ return
+endfunc
+
+func CheckSourceDefExecAndScriptFailure(lines, error, lnum = -3)
+ return
+endfunc
+