diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/functional/api/vim_spec.lua | 12 | ||||
-rw-r--r-- | test/functional/core/fileio_spec.lua | 7 | ||||
-rw-r--r-- | test/functional/core/path_spec.lua | 34 | ||||
-rw-r--r-- | test/functional/editor/completion_spec.lua | 9 | ||||
-rw-r--r-- | test/functional/ex_cmds/swapfile_preserve_recover_spec.lua | 58 | ||||
-rw-r--r-- | test/functional/legacy/digraph_spec.lua | 6 | ||||
-rw-r--r-- | test/functional/legacy/edit_spec.lua | 2 | ||||
-rw-r--r-- | test/functional/plugin/lsp/snippet_spec.lua | 243 | ||||
-rw-r--r-- | test/functional/plugin/lsp_spec.lua | 48 | ||||
-rw-r--r-- | test/functional/terminal/window_spec.lua | 41 | ||||
-rw-r--r-- | test/functional/treesitter/fold_spec.lua | 113 | ||||
-rw-r--r-- | test/functional/ui/cmdline_highlight_spec.lua | 2 | ||||
-rw-r--r-- | test/functional/ui/popupmenu_spec.lua | 4 | ||||
-rw-r--r-- | test/functional/ui/screen_basic_spec.lua | 2 | ||||
-rw-r--r-- | test/old/testdir/test_functions.vim | 18 | ||||
-rw-r--r-- | test/old/testdir/test_history.vim | 5 | ||||
-rw-r--r-- | test/old/testdir/test_options.vim | 312 |
17 files changed, 709 insertions, 207 deletions
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 09495fbaac..f28d6ea869 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -2869,6 +2869,18 @@ describe('API', function() eq(false, eval('g:fired')) end) + it('TextChanged and TextChangedI do not trigger without changes', function() + local buf = meths.create_buf(true, false) + command([[let g:changed = '']]) + meths.create_autocmd({'TextChanged', 'TextChangedI'}, { + buffer = buf, + command = 'let g:changed ..= mode()', + }) + meths.set_current_buf(buf) + feed('i') + eq('', meths.get_var('changed')) + end) + it('scratch-buffer', function() eq({id=2}, meths.create_buf(false, true)) eq({id=3}, meths.create_buf(true, true)) diff --git a/test/functional/core/fileio_spec.lua b/test/functional/core/fileio_spec.lua index f2b360f0d8..a23dad226a 100644 --- a/test/functional/core/fileio_spec.lua +++ b/test/functional/core/fileio_spec.lua @@ -40,6 +40,7 @@ describe('fileio', function() os.remove('Xtest_startup_file1') os.remove('Xtest_startup_file1~') os.remove('Xtest_startup_file2') + os.remove('Xtest_startup_file2~') os.remove('Xtest_тест.md') os.remove('Xtest-u8-int-max') os.remove('Xtest-overwrite-forced') @@ -136,7 +137,7 @@ describe('fileio', function() it('backup with full path with spaces', function() skip(is_ci('cirrus')) clear() - mkdir('Xtest_backup with spaces') + mkdir('Xtest_backupdir with spaces') command('set backup') command('set backupdir=Xtest_backupdir\\ with\\ spaces//') command('write Xtest_startup_file1') @@ -258,8 +259,8 @@ describe('fileio', function() screen:expect([[ {2:WARNING: The file has been changed since}| {2: reading it!!!} | - {3:Do you really want to write to it (y/n)^?}| - | + {3:Do you really want to write to it (y/n)?}| + ^ | ]]) feed("n") diff --git a/test/functional/core/path_spec.lua b/test/functional/core/path_spec.lua index a786887bbd..6c677d76d1 100644 --- a/test/functional/core/path_spec.lua +++ b/test/functional/core/path_spec.lua @@ -6,16 +6,19 @@ local command = helpers.command local insert = helpers.insert local feed = helpers.feed local is_os = helpers.is_os +local mkdir = helpers.mkdir +local rmdir = helpers.rmdir +local write_file = helpers.write_file + +local function join_path(...) + local pathsep = (is_os('win') and '\\' or '/') + return table.concat({...}, pathsep) +end describe('path collapse', function() local targetdir local expected_path - local function join_path(...) - local pathsep = (is_os('win') and '\\' or '/') - return table.concat({...}, pathsep) - end - before_each(function() targetdir = join_path('test', 'functional', 'fixtures') clear() @@ -57,6 +60,27 @@ describe('path collapse', function() end) end) +describe('expand wildcard', function() + before_each(clear) + + it('with special characters #24421', function() + local folders = is_os('win') and { + '{folder}', + 'folder$name' + } or { + 'folder-name', + 'folder#name' + } + for _, folder in ipairs(folders) do + mkdir(folder) + local file = join_path(folder, 'file.txt') + write_file(file, '') + eq(file, eval('expand("'..folder..'/*")')) + rmdir(folder) + end + end) +end) + describe('file search', function() before_each(clear) diff --git a/test/functional/editor/completion_spec.lua b/test/functional/editor/completion_spec.lua index 8c299636cc..ea3397d50d 100644 --- a/test/functional/editor/completion_spec.lua +++ b/test/functional/editor/completion_spec.lua @@ -941,6 +941,15 @@ describe('completion', function() end) end) + it('cmdline completion supports various string options', function() + eq('auto', funcs.getcompletion('set foldcolumn=', 'cmdline')[2]) + eq({'nosplit', 'split'}, funcs.getcompletion('set inccommand=', 'cmdline')) + eq({'ver:3,hor:6', 'hor:', 'ver:'}, funcs.getcompletion('set mousescroll=', 'cmdline')) + eq('BS', funcs.getcompletion('set termpastefilter=', 'cmdline')[2]) + eq('SpecialKey', funcs.getcompletion('set winhighlight=', 'cmdline')[1]) + eq('SpecialKey', funcs.getcompletion('set winhighlight=NonText:', 'cmdline')[1]) + end) + describe('from the commandline window', function() it('is cleared after CTRL-C', function () feed('q:') diff --git a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua index 3e0f6d1fcc..436873b464 100644 --- a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua +++ b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua @@ -171,6 +171,7 @@ describe('swapfile detection', function() local screen2 = Screen.new(256, 40) screen2:attach() exec(init) + command('autocmd! nvim_swapfile') -- Delete the default handler (which skips the dialog). -- With shortmess+=F command('set shortmess+=F') @@ -219,11 +220,29 @@ describe('swapfile detection', function() nvim2:close() end) + it('default SwapExists handler selects "(E)dit" and skips prompt', function() + exec(init) + command('edit Xfile1') + command("put ='some text...'") + command('preserve') -- Make sure the swap file exists. + local nvimpid = funcs.getpid() + + local nvim1 = spawn(new_argv(), true, nil, true) + set_session(nvim1) + local screen = Screen.new(75, 18) + screen:attach() + exec(init) + feed(':edit Xfile1\n') + + screen:expect({ any = ('W325: Ignoring swapfile from Nvim process %d'):format(nvimpid) }) + nvim1:close() + end) + -- oldtest: Test_swap_prompt_splitwin() it('selecting "q" in the attention prompt', function() exec(init) command('edit Xfile1') - command('preserve') -- should help to make sure the swap file exists + command('preserve') -- Make sure the swap file exists. local screen = Screen.new(75, 18) screen:set_default_attr_ids({ @@ -235,7 +254,9 @@ describe('swapfile detection', function() set_session(nvim1) screen:attach() exec(init) + command('autocmd! nvim_swapfile') -- Delete the default handler (which skips the dialog). feed(':split Xfile1\n') + -- The default SwapExists handler does _not_ skip this prompt. screen:expect({ any = pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: }^') }) @@ -267,6 +288,7 @@ describe('swapfile detection', function() set_session(nvim2) screen:attach() exec(init) + command('autocmd! nvim_swapfile') -- Delete the default handler (which skips the dialog). command('set more') command('au bufadd * let foo_w = wincol()') feed(':e Xfile1<CR>') @@ -300,8 +322,9 @@ describe('swapfile detection', function() nvim2:close() end) - -- oldtest: Test_nocatch_process_still_running() - it('allows deleting swapfile created before boot vim-patch:8.2.2586', function() + --- @param swapexists boolean Enable the default SwapExists handler. + --- @param on_swapfile_running fun(screen: any) Called after swapfile ("STILL RUNNING") prompt. + local function test_swapfile_after_reboot(swapexists, on_swapfile_running) local screen = Screen.new(75, 30) screen:set_default_attr_ids({ [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText @@ -311,6 +334,9 @@ describe('swapfile detection', function() screen:attach() exec(init) + if not swapexists then + command('autocmd! nvim_swapfile') -- Delete the default handler (which skips the dialog). + end command('set nohidden') exec([=[ @@ -347,12 +373,7 @@ describe('swapfile detection', function() os.rename('Xswap', swname) feed(':edit Xswaptest<CR>') - screen:expect({any = table.concat({ - pesc('{2:E325: ATTENTION}'), - 'file name: .*Xswaptest', - 'process ID: %d* %(STILL RUNNING%)', - pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: }^'), - }, '.*')}) + on_swapfile_running(screen) feed('e') @@ -374,7 +395,26 @@ describe('swapfile detection', function() }, '.*')}) feed('e') + end + + -- oldtest: Test_nocatch_process_still_running() + it('swapfile created before boot vim-patch:8.2.2586', function() + test_swapfile_after_reboot(false, function(screen) + screen:expect({any = table.concat({ + pesc('{2:E325: ATTENTION}'), + 'file name: .*Xswaptest', + 'process ID: %d* %(STILL RUNNING%)', + pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: }^'), + }, '.*')}) + end) + end) + + it('swapfile created before boot + default SwapExists handler', function() + test_swapfile_after_reboot(true, function(screen) + screen:expect({ any = 'W325: Ignoring swapfile from Nvim process' }) + end) end) + end) describe('quitting swapfile dialog on startup stops TUI properly', function() diff --git a/test/functional/legacy/digraph_spec.lua b/test/functional/legacy/digraph_spec.lua index 0cb0bb84be..7eeb83eb5f 100644 --- a/test/functional/legacy/digraph_spec.lua +++ b/test/functional/legacy/digraph_spec.lua @@ -22,7 +22,7 @@ describe('digraph', function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT -} | + {2:-- INSERT --}| ]]) feed('1') screen:expect([[ @@ -31,7 +31,7 @@ describe('digraph', function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT -} | + {2:-- INSERT --}| ]]) feed('2') screen:expect([[ @@ -40,7 +40,7 @@ describe('digraph', function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT -} | + {2:-- INSERT --}| ]]) end) end) diff --git a/test/functional/legacy/edit_spec.lua b/test/functional/legacy/edit_spec.lua index 186bf395cc..939999e21b 100644 --- a/test/functional/legacy/edit_spec.lua +++ b/test/functional/legacy/edit_spec.lua @@ -43,7 +43,7 @@ describe('edit', function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT -} | + {2:-- INSERT --}| ]]) feed('=') screen:expect([[ diff --git a/test/functional/plugin/lsp/snippet_spec.lua b/test/functional/plugin/lsp/snippet_spec.lua index 7903885420..13df861b91 100644 --- a/test/functional/plugin/lsp/snippet_spec.lua +++ b/test/functional/plugin/lsp/snippet_spec.lua @@ -1,130 +1,70 @@ local helpers = require('test.functional.helpers')(after_each) -local snippet = require('vim.lsp._snippet') +local snippet = require('vim.lsp._snippet_grammar') local eq = helpers.eq local exec_lua = helpers.exec_lua -describe('vim.lsp._snippet', function() +describe('vim.lsp._snippet_grammar', function() before_each(helpers.clear) after_each(helpers.clear) local parse = function(...) - return exec_lua('return require("vim.lsp._snippet").parse(...)', ...) + local res = exec_lua('return require("vim.lsp._snippet_grammar").parse(...)', ...) + return res.data.children end - it('should parse only text', function() + it('parses only text', function() eq({ - type = snippet.NodeType.SNIPPET, - children = { - { - type = snippet.NodeType.TEXT, - raw = 'TE\\$\\}XT', - esc = 'TE$}XT', - }, - }, + { type = snippet.NodeType.Text, data = { text = 'TE$}XT' } }, }, parse('TE\\$\\}XT')) end) - it('should parse tabstop', function() + it('parses tabstops', function() eq({ - type = snippet.NodeType.SNIPPET, - children = { - { - type = snippet.NodeType.TABSTOP, - tabstop = 1, - }, - { - type = snippet.NodeType.TABSTOP, - tabstop = 2, - }, - }, + { type = snippet.NodeType.Tabstop, data = { tabstop = 1 } }, + { type = snippet.NodeType.Tabstop, data = { tabstop = 2 } }, }, parse('$1${2}')) end) - it('should parse placeholders', function() + it('parses nested placeholders', function() eq({ - type = snippet.NodeType.SNIPPET, - children = { - { - type = snippet.NodeType.PLACEHOLDER, + { + type = snippet.NodeType.Placeholder, + data = { tabstop = 1, - children = { - { - type = snippet.NodeType.PLACEHOLDER, + value = { + type = snippet.NodeType.Placeholder, + data = { tabstop = 2, - children = { - { - type = snippet.NodeType.TEXT, - raw = 'TE\\$\\}XT', - esc = 'TE$}XT', - }, - { - type = snippet.NodeType.TABSTOP, - tabstop = 3, - }, - { - type = snippet.NodeType.TABSTOP, - tabstop = 1, - transform = { - type = snippet.NodeType.TRANSFORM, - pattern = 'regex', - option = 'i', - format = { - { - type = snippet.NodeType.FORMAT, - capture_index = 1, - modifier = 'upcase', - }, - }, - }, - }, - { - type = snippet.NodeType.TEXT, - raw = 'TE\\$\\}XT', - esc = 'TE$}XT', - }, - }, + value = { type = snippet.NodeType.Tabstop, data = { tabstop = 3 } }, }, }, }, }, - }, parse('${1:${2:TE\\$\\}XT$3${1/regex/${1:/upcase}/i}TE\\$\\}XT}}')) + }, parse('${1:${2:${3}}}')) end) - it('should parse variables', function() + it('parses variables', function() eq({ - type = snippet.NodeType.SNIPPET, - children = { - { - type = snippet.NodeType.VARIABLE, - name = 'VAR', - }, - { - type = snippet.NodeType.VARIABLE, + { type = snippet.NodeType.Variable, data = { name = 'VAR' } }, + { type = snippet.NodeType.Variable, data = { name = 'VAR' } }, + { + type = snippet.NodeType.Variable, + data = { name = 'VAR', + default = { type = snippet.NodeType.Tabstop, data = { tabstop = 1 } }, }, - { - type = snippet.NodeType.VARIABLE, + }, + { + type = snippet.NodeType.Variable, + data = { name = 'VAR', - children = { + regex = 'regex', + options = '', + format = { { - type = snippet.NodeType.TABSTOP, - tabstop = 1, - }, - }, - }, - { - type = snippet.NodeType.VARIABLE, - name = 'VAR', - transform = { - type = snippet.NodeType.TRANSFORM, - pattern = 'regex', - format = { - { - type = snippet.NodeType.FORMAT, - capture_index = 1, - modifier = 'upcase', - }, + type = snippet.NodeType.Format, + data = { capture = 1, modifier = 'upcase' }, }, }, }, @@ -132,105 +72,82 @@ describe('vim.lsp._snippet', function() }, parse('$VAR${VAR}${VAR:$1}${VAR/regex/${1:/upcase}/}')) end) - it('should parse choice', function() + it('parses choice', function() eq({ - type = snippet.NodeType.SNIPPET, - children = { - { - type = snippet.NodeType.CHOICE, - tabstop = 1, - items = { - ',', - '|', - }, - }, + { + type = snippet.NodeType.Choice, + data = { tabstop = 1, values = { ',', '|' } }, }, }, parse('${1|\\,,\\||}')) end) - it('should parse format', function() - eq({ - type = snippet.NodeType.SNIPPET, - children = { + it('parses format', function() + eq( + { { - type = snippet.NodeType.VARIABLE, - name = 'VAR', - transform = { - type = snippet.NodeType.TRANSFORM, - pattern = 'regex', + type = snippet.NodeType.Variable, + data = { + name = 'VAR', + regex = 'regex', + options = '', format = { { - type = snippet.NodeType.FORMAT, - capture_index = 1, - modifier = 'upcase', + type = snippet.NodeType.Format, + data = { capture = 1, modifier = 'upcase' }, }, { - type = snippet.NodeType.FORMAT, - capture_index = 1, - if_text = 'if_text', - else_text = '', + type = snippet.NodeType.Format, + data = { capture = 1, if_text = 'if_text' }, }, { - type = snippet.NodeType.FORMAT, - capture_index = 1, - if_text = '', - else_text = 'else_text', + type = snippet.NodeType.Format, + data = { capture = 1, else_text = 'else_text' }, }, { - type = snippet.NodeType.FORMAT, - capture_index = 1, - else_text = 'else_text', - if_text = 'if_text', + type = snippet.NodeType.Format, + data = { capture = 1, if_text = 'if_text', else_text = 'else_text' }, }, { - type = snippet.NodeType.FORMAT, - capture_index = 1, - if_text = '', - else_text = 'else_text', + type = snippet.NodeType.Format, + data = { capture = 1, else_text = 'else_text' }, }, }, }, }, }, - }, parse('${VAR/regex/${1:/upcase}${1:+if_text}${1:-else_text}${1:?if_text:else_text}${1:else_text}/}')) + parse( + '${VAR/regex/${1:/upcase}${1:+if_text}${1:-else_text}${1:?if_text:else_text}${1:else_text}/}' + ) + ) end) - it('should parse empty strings', function() + it('parses empty strings', function() eq({ - children = { - { - children = { { - esc = '', - raw = '', - type = 7, - } }, + { + type = snippet.NodeType.Placeholder, + data = { tabstop = 1, - type = 2, - }, - { - esc = ' ', - raw = ' ', - type = 7, + value = { type = snippet.NodeType.Text, data = { text = '' } }, }, - { + }, + { + type = snippet.NodeType.Text, + data = { text = ' ' }, + }, + { + type = snippet.NodeType.Variable, + data = { name = 'VAR', - transform = { - format = { - { - capture_index = 1, - else_text = '', - if_text = '', - type = 6, - }, + regex = 'erg', + format = { + { + type = snippet.NodeType.Format, + data = { capture = 1, if_text = '' }, }, - option = 'g', - pattern = 'erg', - type = 5, }, - type = 3, + options = 'g', }, }, - type = 0, - }, parse('${1:} ${VAR/erg/${1:?:}/g}')) + }, parse('${1:} ${VAR/erg/${1:+}/g}')) end) end) diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 155c9ad96c..73e05d8d11 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -2301,7 +2301,7 @@ describe('LSP', function() { label='foocar', sortText="g", insertText='foodar', insertTextFormat=2, textEdit={newText='foobar(${1:place holder}, ${2:more ...holder{\\}})'} }, { label='foocar', sortText="h", insertText='foodar(${1:var1} typ1, ${2:var2} *typ2) {$0\\}', insertTextFormat=2, textEdit={} }, -- nested snippet tokens - { label='foocar', sortText="i", insertText='foodar(${1:var1 ${2|typ2,typ3|} ${3:tail}}) {$0\\}', insertTextFormat=2, textEdit={} }, + { label='foocar', sortText="i", insertText='foodar(${1:${2|typ1,typ2|}}) {$0\\}', insertTextFormat=2, textEdit={} }, -- braced tabstop { label='foocar', sortText="j", insertText='foodar()${0}', insertTextFormat=2, textEdit={} }, -- plain text @@ -2317,7 +2317,7 @@ describe('LSP', function() { abbr = 'foocar', dup = 1, empty = 1, icase = 1, kind = 'Unknown', menu = '', word = 'foobar', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="f", textEdit={newText='foobar'} } } } } }, { abbr = 'foocar', dup = 1, empty = 1, icase = 1, kind = 'Unknown', menu = '', word = 'foobar(place holder, more ...holder{})', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="g", insertText='foodar', insertTextFormat=2, textEdit={newText='foobar(${1:place holder}, ${2:more ...holder{\\}})'} } } } } }, { abbr = 'foocar', dup = 1, empty = 1, icase = 1, kind = 'Unknown', menu = '', word = 'foodar(var1 typ1, var2 *typ2) {}', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="h", insertText='foodar(${1:var1} typ1, ${2:var2} *typ2) {$0\\}', insertTextFormat=2, textEdit={} } } } } }, - { abbr = 'foocar', dup = 1, empty = 1, icase = 1, kind = 'Unknown', menu = '', word = 'foodar(var1 typ2 tail) {}', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="i", insertText='foodar(${1:var1 ${2|typ2,typ3|} ${3:tail}}) {$0\\}', insertTextFormat=2, textEdit={} } } } } }, + { abbr = 'foocar', dup = 1, empty = 1, icase = 1, kind = 'Unknown', menu = '', word = 'foodar(typ1) {}', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="i", insertText='foodar(${1:${2|typ1,typ2|}}) {$0\\}', insertTextFormat=2, textEdit={} } } } } }, { abbr = 'foocar', dup = 1, empty = 1, icase = 1, kind = 'Unknown', menu = '', word = 'foodar()', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="j", insertText='foodar()${0}', insertTextFormat=2, textEdit={} } } } } }, { abbr = 'foocar', dup = 1, empty = 1, icase = 1, kind = 'Unknown', menu = '', word = 'foodar(${1:var1})', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="k", insertText='foodar(${1:var1})', insertTextFormat=1, textEdit={} } } } } }, } @@ -3483,6 +3483,50 @@ describe('LSP', function() end } end) + it("Fallback to command execution on resolve error", function() + clear() + exec_lua(create_server_definition) + local result = exec_lua([[ + local server = _create_server({ + capabilities = { + executeCommandProvider = { + commands = {"command:1"}, + }, + codeActionProvider = { + resolveProvider = true + } + }, + handlers = { + ["textDocument/codeAction"] = function() + return { + { + title = "Code Action 1", + command = { + title = "Command 1", + command = "command:1", + } + } + } + end, + ["codeAction/resolve"] = function() + return nil, "resolve failed" + end, + } + }) + + local client_id = vim.lsp.start({ + name = "dummy", + cmd = server.cmd, + }) + + vim.lsp.buf.code_action({ apply = true }) + vim.lsp.stop_client(client_id) + return server.messages + ]]) + eq("codeAction/resolve", result[4].method) + eq("workspace/executeCommand", result[5].method) + eq("command:1", result[5].params.command) + end) end) describe('vim.lsp.commands', function() it('Accepts only string keys', function() diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua index f90e4f7e9d..39fc2c2562 100644 --- a/test/functional/terminal/window_spec.lua +++ b/test/functional/terminal/window_spec.lua @@ -44,7 +44,7 @@ describe(':terminal window', function() {7:6 } | {3:-- TERMINAL --} | ]]) - feed_data({'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'}) + feed_data('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') screen:expect([[ {7:1 }tty ready | {7:2 }rows: 6, cols: 48 | @@ -55,8 +55,6 @@ describe(':terminal window', function() {3:-- TERMINAL --} | ]]) - skip(is_os('win'), 'win: :terminal resize is unreliable #7007') - -- numberwidth=9 feed([[<C-\><C-N>]]) feed([[:set numberwidth=9 number<CR>i]]) @@ -69,7 +67,7 @@ describe(':terminal window', function() {7: 6 } | {3:-- TERMINAL --} | ]]) - feed_data({' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'}) + feed_data(' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') screen:expect([[ {7: 1 }tty ready | {7: 2 }rows: 6, cols: 48 | @@ -82,6 +80,41 @@ describe(':terminal window', function() end) end) + describe("with 'statuscolumn'", function() + it('wraps text', function() + command([[set number statuscolumn=++%l\ \ ]]) + screen:expect([[ + {7:++1 }tty ready | + {7:++2 }rows: 6, cols: 45 | + {7:++3 }{1: } | + {7:++4 } | + {7:++5 } | + {7:++6 } | + {3:-- TERMINAL --} | + ]]) + feed_data('\n\n\n\n\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') + screen:expect([[ + {7:++4 } | + {7:++5 } | + {7:++6 } | + {7:++7 } | + {7:++8 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS| + {7:++9 }TUVWXYZ{1: } | + {3:-- TERMINAL --} | + ]]) + feed_data('\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') + screen:expect([[ + {7:++7 } | + {7:++8 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR| + {7:++9 }STUVWXYZ | + {7:++10 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR| + {7:++11 }STUVWXYZrows: 6, cols: 44 | + {7:++12 }{1: } | + {3:-- TERMINAL --} | + ]]) + end) + end) + describe("with 'colorcolumn'", function() before_each(function() feed([[<C-\><C-N>]]) diff --git a/test/functional/treesitter/fold_spec.lua b/test/functional/treesitter/fold_spec.lua index 9ed86e87f1..a8abbc002b 100644 --- a/test/functional/treesitter/fold_spec.lua +++ b/test/functional/treesitter/fold_spec.lua @@ -359,3 +359,116 @@ void ui_refresh(void) end) end) + +describe('treesitter foldtext', function() + local test_text = [[ +void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)) +{ + int width = INT_MAX, height = INT_MAX; + bool ext_widgets[kUIExtCount]; + for (UIExtension i = 0; (int)i < kUIExtCount; i++) { + ext_widgets[i] = true; + } + + bool inclusive = ui_override(); + for (size_t i = 0; i < ui_count; i++) { + UI *ui = uis[i]; + width = MIN(ui->width, width); + height = MIN(ui->height, height); + foo = BAR(ui->bazaar, bazaar); + for (UIExtension j = 0; (int)j < kUIExtCount; j++) { + ext_widgets[j] &= (ui->ui_ext[j] || inclusive); + } + } +}]] + local screen + + before_each(function() + screen = Screen.new(60, 5) + screen:set_default_attr_ids({ + [0] = {foreground = Screen.colors.Blue, bold = true}, + [1] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGray}; + [2] = {bold = true, background = Screen.colors.LightGray, foreground = Screen.colors.SeaGreen}; + [3] = {foreground = Screen.colors.DarkCyan, background = Screen.colors.LightGray}; + [4] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.LightGray}; + [5] = {bold = true, background = Screen.colors.LightGray, foreground = Screen.colors.Brown}; + [6] = {background = Screen.colors.Red1}; + [7] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.Red}; + [8] = {foreground = Screen.colors.Brown, bold = true, background = Screen.colors.Red}; + [9] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.Red}; + [10] = {bold = true}; + }) + screen:attach() + end) + + it('displays highlighted content', function() + command([[set foldmethod=manual foldtext=v:lua.vim.treesitter.foldtext() updatetime=50]]) + insert(test_text) + exec_lua([[vim.treesitter.get_parser(0, "c")]]) + + feed('ggVGzf') + screen:expect{grid=[[ + {2:^void}{1: }{3:qsort}{4:(}{2:void}{1: }{5:*}{3:base}{4:,}{1: }{2:size_t}{1: }{3:nel}{4:,}{1: }{2:size_t}{1: }{3:width}{4:,}{1: }{2:int}{1: }{4:(}{5:*}{3:compa}| + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]} + end) + + it('handles deep nested captures', function() + command([[set foldmethod=manual foldtext=v:lua.vim.treesitter.foldtext() updatetime=50]]) + insert([[ +function FoldInfo.new() + return setmetatable({ + start_counts = {}, + stop_counts = {}, + levels0 = {}, + levels = {}, + }, FoldInfo) +end]]) + exec_lua([[vim.treesitter.get_parser(0, "lua")]]) + + feed('ggjVGkzfgg') + screen:expect{grid=[[ + ^function FoldInfo.new() | + {1: }{5:return}{1: }{4:setmetatable({}{1:·····································}| + end | + {0:~ }| + | + ]]} + + command('hi! Visual guibg=Red') + feed('GVgg') + screen:expect{grid=[[ + ^f{6:unction FoldInfo.new()} | + {7: }{8:return}{7: }{9:setmetatable({}{7:·····································}| + {6:end} | + {0:~ }| + {10:-- VISUAL LINE --} | + ]]} + + feed('10l<C-V>') + screen:expect{grid=[[ + {6:function F}^oldInfo.new() | + {7: }{8:return}{7: }{9:se}{4:tmetatable({}{1:·····································}| + {6:end} | + {0:~ }| + {10:-- VISUAL BLOCK --} | + ]]} + end) + + it('falls back to default', function() + command([[set foldmethod=manual foldtext=v:lua.vim.treesitter.foldtext()]]) + insert(test_text) + + feed('ggVGzf') + screen:expect{grid=[[ + {1:^+-- 19 lines: void qsort(void *base, size_t nel, size_t widt}| + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]} + end) +end) diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua index 17e6855ee4..e4766103c2 100644 --- a/test/functional/ui/cmdline_highlight_spec.lua +++ b/test/functional/ui/cmdline_highlight_spec.lua @@ -577,10 +577,10 @@ describe('Command-line coloring', function() | {EOB:~ }| {EOB:~ }| + {EOB:~ }| {MSEP: }| :+ | {ERR:E5404: Chunk 1 end 3 not in range (1, 2]}| - | :++^ | ]]) end) diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index ea65cf35bd..38649a2be3 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -2439,14 +2439,14 @@ describe('builtin popupmenu', function() prefix | bef{n: word } | tex{n: }^ | - {2:-- INSERT -} | + {2:-- INSERT --}| ]]) -- can't draw the pum, but check we don't crash screen:try_resize(12,2) screen:expect([[ {1:<<<}t^ | - {2:-- INSERT -} | + {2:-- INSERT --}| ]]) -- but state is preserved, pum reappears diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua index bc9517aa60..7cc1accd3f 100644 --- a/test/functional/ui/screen_basic_spec.lua +++ b/test/functional/ui/screen_basic_spec.lua @@ -795,7 +795,7 @@ local function screen_tests(linegrid) screen:try_resize(1, 1) screen:expect([[ resize^ | - {2:-- INSERT -} | + {2:-- INSERT --}| ]]) feed('<esc>:ls') diff --git a/test/old/testdir/test_functions.vim b/test/old/testdir/test_functions.vim index 7b20f47f7a..b27b0be802 100644 --- a/test/old/testdir/test_functions.vim +++ b/test/old/testdir/test_functions.vim @@ -3303,4 +3303,22 @@ func Test_glob_extended_bash() let &shell=_shell endfunc +" Test for glob() with extended patterns (MS-Windows) +" Vim doesn't use 'shell' to expand wildcards on MS-Windows. +" Unlike bash, it doesn't support {,} expansion. +func Test_glob_extended_mswin() + CheckMSWindows + + call mkdir('Xtestglob/foo/bar/src', 'p') + call writefile([], 'Xtestglob/foo/bar/src/foo.sh') + call writefile([], 'Xtestglob/foo/bar/src/foo.h') + call writefile([], 'Xtestglob/foo/bar/src/foo.cpp') + + " Sort output of glob() otherwise we end up with different + " ordering depending on whether file system is case-sensitive. + let expected = ['Xtestglob/foo/bar/src/foo.cpp', 'Xtestglob/foo/bar/src/foo.h', 'Xtestglob/foo/bar/src/foo.sh'] + call assert_equal(expected, sort(glob('Xtestglob/**/foo.*', 0, 1))) + call delete('Xtestglob', 'rf') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/test/old/testdir/test_history.vim b/test/old/testdir/test_history.vim index f1c31dee04..bb6d671725 100644 --- a/test/old/testdir/test_history.vim +++ b/test/old/testdir/test_history.vim @@ -244,8 +244,13 @@ endfunc " Test for making sure the key value is not stored in history func Test_history_crypt_key() CheckFeature cryptv + call feedkeys(":set bs=2 key=abc ts=8\<CR>", 'xt') call assert_equal('set bs=2 key= ts=8', histget(':')) + + call assert_fails("call feedkeys(':set bs=2 key-=abc ts=8\<CR>', 'xt')") + call assert_equal('set bs=2 key-= ts=8', histget(':')) + set key& bs& ts& endfunc diff --git a/test/old/testdir/test_options.vim b/test/old/testdir/test_options.vim index c56efe8786..76b7cc920b 100644 --- a/test/old/testdir/test_options.vim +++ b/test/old/testdir/test_options.vim @@ -299,11 +299,11 @@ func Test_set_completion() call assert_equal('"set tabstop thesaurus thesaurusfunc', @:) " Expand current value - call feedkeys(":set fileencodings=\<C-A>\<C-B>\"\<CR>", 'tx') - call assert_equal('"set fileencodings=ucs-bom,utf-8,default,latin1', @:) + call feedkeys(":set suffixes=\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"set suffixes=.bak,~,.o,.h,.info,.swp,.obj', @:) - call feedkeys(":set fileencodings:\<C-A>\<C-B>\"\<CR>", 'tx') - call assert_equal('"set fileencodings:ucs-bom,utf-8,default,latin1', @:) + call feedkeys(":set suffixes:\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"set suffixes:.bak,~,.o,.h,.info,.swp,.obj', @:) " Expand key codes. " call feedkeys(":set <H\<C-A>\<C-B>\"\<CR>", 'tx') @@ -364,14 +364,20 @@ func Test_set_completion() call assert_equal("\"set invtabstop=", @:) " Expand options for 'spellsuggest' - call feedkeys(":set spellsuggest=best,file:xyz\<Tab>\<C-B>\"\<CR>", 'xt') - call assert_equal("\"set spellsuggest=best,file:xyz", @:) - - " Expand value for 'key' - " set key=abcd - " call feedkeys(":set key=\<Tab>\<C-B>\"\<CR>", 'xt') - " call assert_equal('"set key=*****', @:) - " set key= + call feedkeys(":set spellsuggest=file:test_options.v\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal("\"set spellsuggest=file:test_options.vim", @:) + call feedkeys(":set spellsuggest=best,file:test_options.v\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal("\"set spellsuggest=best,file:test_options.vim", @:) + + " Expanding value for 'key' is disallowed + if exists('+key') + set key=abcd + call feedkeys(":set key=\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"set key=', @:) + call feedkeys(":set key-=\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"set key-=', @:) + set key= + endif " Expand values for 'filetype' call feedkeys(":set filetype=sshdconfi\<Tab>\<C-B>\"\<CR>", 'xt') @@ -386,6 +392,286 @@ func Test_set_completion() call assert_equal('"set syntax=' .. getcompletion('a*', 'syntax')->join(), @:) endfunc +" Test handling of expanding individual string option values +func Test_set_completion_string_values() + " + " Test basic enum string options that have well-defined enum names + " + + " call assert_equal(['lastline', 'truncate', 'uhex'], getcompletion('set display=', 'cmdline')) + call assert_equal(['lastline', 'truncate', 'uhex', 'msgsep'], getcompletion('set display=', 'cmdline')) + call assert_equal(['truncate'], getcompletion('set display=t', 'cmdline')) + call assert_equal(['uhex'], getcompletion('set display=*ex*', 'cmdline')) + + " Test that if a value is set, it will populate the results, but only if + " typed value is empty. + set display=uhex,lastline + " call assert_equal(['uhex,lastline', 'lastline', 'truncate', 'uhex'], getcompletion('set display=', 'cmdline')) + call assert_equal(['uhex,lastline', 'lastline', 'truncate', 'uhex', 'msgsep'], getcompletion('set display=', 'cmdline')) + call assert_equal(['uhex'], getcompletion('set display=u', 'cmdline')) + " If the set value is part of the enum list, it will show as the first + " result with no duplicate. + set display=uhex + " call assert_equal(['uhex', 'lastline', 'truncate'], getcompletion('set display=', 'cmdline')) + call assert_equal(['uhex', 'lastline', 'truncate', 'msgsep'], getcompletion('set display=', 'cmdline')) + " If empty value, will just show the normal list without an empty item + set display= + " call assert_equal(['lastline', 'truncate', 'uhex'], getcompletion('set display=', 'cmdline')) + call assert_equal(['lastline', 'truncate', 'uhex', 'msgsep'], getcompletion('set display=', 'cmdline')) + " Test escaping of the values + " call assert_equal('vert:\|,fold:-,eob:~,lastline:@', getcompletion('set fillchars=', 'cmdline')[0]) + call assert_equal('vert:\|,foldsep:\|,fold:-', getcompletion('set fillchars=', 'cmdline')[0]) + + " Test comma-separated lists will expand after a comma. + call assert_equal(['uhex'], getcompletion('set display=truncate,*ex*', 'cmdline')) + " Also test the positioning of the expansion is correct + call feedkeys(":set display=truncate,l\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"set display=truncate,lastline', @:) + set display& + + " Test single-value options will not expand after a comma + call assert_equal([], getcompletion('set ambw=single,', 'cmdline')) + + " Test the other simple options to make sure they have basic auto-complete, + " but don't exhaustively validate their results. + call assert_equal('single', getcompletion('set ambw=', 'cmdline')[0]) + call assert_match('light\|dark', getcompletion('set bg=', 'cmdline')[1]) + call assert_equal('indent', getcompletion('set backspace=', 'cmdline')[0]) + call assert_equal('yes', getcompletion('set backupcopy=', 'cmdline')[1]) + call assert_equal('backspace', getcompletion('set belloff=', 'cmdline')[1]) + call assert_equal('min:', getcompletion('set briopt=', 'cmdline')[1]) + if exists('+browsedir') + call assert_equal('current', getcompletion('set browsedir=', 'cmdline')[1]) + endif + call assert_equal('unload', getcompletion('set bufhidden=', 'cmdline')[1]) + call assert_equal('nowrite', getcompletion('set buftype=', 'cmdline')[1]) + call assert_equal('internal', getcompletion('set casemap=', 'cmdline')[1]) + if exists('+clipboard') + " call assert_match('unnamed', getcompletion('set clipboard=', 'cmdline')[1]) + call assert_match('unnamed', getcompletion('set clipboard=', 'cmdline')[0]) + endif + call assert_equal('.', getcompletion('set complete=', 'cmdline')[1]) + call assert_equal('menu', getcompletion('set completeopt=', 'cmdline')[1]) + if exists('+completeslash') + call assert_equal('backslash', getcompletion('set completeslash=', 'cmdline')[1]) + endif + if exists('+cryptmethod') + call assert_equal('zip', getcompletion('set cryptmethod=', 'cmdline')[1]) + endif + if exists('+cursorlineopt') + call assert_equal('line', getcompletion('set cursorlineopt=', 'cmdline')[1]) + endif + call assert_equal('throw', getcompletion('set debug=', 'cmdline')[1]) + call assert_equal('ver', getcompletion('set eadirection=', 'cmdline')[1]) + call assert_equal('mac', getcompletion('set fileformat=', 'cmdline')[2]) + if exists('+foldclose') + call assert_equal('all', getcompletion('set foldclose=', 'cmdline')[0]) + endif + if exists('+foldmethod') + call assert_equal('expr', getcompletion('set foldmethod=', 'cmdline')[1]) + endif + if exists('+foldopen') + call assert_equal('all', getcompletion('set foldopen=', 'cmdline')[1]) + endif + call assert_equal('stack', getcompletion('set jumpoptions=', 'cmdline')[0]) + call assert_equal('stopsel', getcompletion('set keymodel=', 'cmdline')[1]) + call assert_equal('expr:1', getcompletion('set lispoptions=', 'cmdline')[1]) + call assert_match('popup', getcompletion('set mousemodel=', 'cmdline')[2]) + call assert_equal('bin', getcompletion('set nrformats=', 'cmdline')[1]) + if exists('+rightleftcmd') + call assert_equal('search', getcompletion('set rightleftcmd=', 'cmdline')[0]) + endif + call assert_equal('ver', getcompletion('set scrollopt=', 'cmdline')[1]) + call assert_equal('exclusive', getcompletion('set selection=', 'cmdline')[1]) + call assert_equal('key', getcompletion('set selectmode=', 'cmdline')[1]) + if exists('+ssop') + call assert_equal('buffers', getcompletion('set ssop=', 'cmdline')[1]) + endif + call assert_equal('statusline', getcompletion('set showcmdloc=', 'cmdline')[1]) + if exists('+signcolumn') + call assert_equal('yes', getcompletion('set signcolumn=', 'cmdline')[1]) + endif + if exists('+spelloptions') + call assert_equal('camel', getcompletion('set spelloptions=', 'cmdline')[0]) + endif + if exists('+spellsuggest') + call assert_equal('best', getcompletion('set spellsuggest+=', 'cmdline')[0]) + endif + call assert_equal('screen', getcompletion('set splitkeep=', 'cmdline')[1]) + " call assert_equal('sync', getcompletion('set swapsync=', 'cmdline')[1]) + call assert_equal('usetab', getcompletion('set switchbuf=', 'cmdline')[1]) + call assert_equal('ignore', getcompletion('set tagcase=', 'cmdline')[1]) + if exists('+termwintype') + call assert_equal('conpty', getcompletion('set termwintype=', 'cmdline')[1]) + endif + if exists('+toolbar') + call assert_equal('text', getcompletion('set toolbar=', 'cmdline')[1]) + endif + if exists('+tbis') + call assert_equal('medium', getcompletion('set tbis=', 'cmdline')[2]) + endif + if exists('+ttymouse') + set ttymouse= + call assert_equal('xterm2', getcompletion('set ttymouse=', 'cmdline')[1]) + set ttymouse& + endif + call assert_equal('insert', getcompletion('set virtualedit=', 'cmdline')[1]) + call assert_equal('longest', getcompletion('set wildmode=', 'cmdline')[1]) + call assert_equal('full', getcompletion('set wildmode=list,longest:', 'cmdline')[0]) + call assert_equal('tagfile', getcompletion('set wildoptions=', 'cmdline')[1]) + if exists('+winaltkeys') + call assert_equal('yes', getcompletion('set winaltkeys=', 'cmdline')[1]) + endif + + " Other string options that queries the system rather than fixed enum names + call assert_equal(['all', 'BufAdd'], getcompletion('set eventignore=', 'cmdline')[0:1]) + call assert_equal('latin1', getcompletion('set fileencodings=', 'cmdline')[1]) + " call assert_equal('top', getcompletion('set printoptions=', 'cmdline')[0]) + " call assert_equal('SpecialKey', getcompletion('set wincolor=', 'cmdline')[0]) + + call assert_equal('eol', getcompletion('set listchars+=', 'cmdline')[0]) + call assert_equal(['multispace', 'leadmultispace'], getcompletion('set listchars+=', 'cmdline')[-2:]) + call assert_equal('eol', getcompletion('setl listchars+=', 'cmdline')[0]) + call assert_equal(['multispace', 'leadmultispace'], getcompletion('setl listchars+=', 'cmdline')[-2:]) + call assert_equal('stl', getcompletion('set fillchars+=', 'cmdline')[0]) + call assert_equal('stl', getcompletion('setl fillchars+=', 'cmdline')[0]) + + " + " Unique string options below + " + + " keyprotocol: only auto-complete when after ':' with known protocol types + " call assert_equal([&keyprotocol], getcompletion('set keyprotocol=', 'cmdline')) + " call feedkeys(":set keyprotocol+=someterm:m\<Tab>\<C-B>\"\<CR>", 'xt') + " call assert_equal('"set keyprotocol+=someterm:mok2', @:) + " set keyprotocol& + + " previewpopup / completepopup + " call assert_equal('height:', getcompletion('set previewpopup=', 'cmdline')[0]) + " call assert_equal('EndOfBuffer', getcompletion('set previewpopup=highlight:End*Buffer', 'cmdline')[0]) + " call feedkeys(":set previewpopup+=border:\<Tab>\<C-B>\"\<CR>", 'xt') + " call assert_equal('"set previewpopup+=border:on', @:) + " call feedkeys(":set completepopup=height:10,align:\<Tab>\<C-B>\"\<CR>", 'xt') + " call assert_equal('"set completepopup=height:10,align:item', @:) + " call assert_equal([], getcompletion('set completepopup=bogusname:', 'cmdline')) + " set previewpopup& completepopup& + + " diffopt: special handling of algorithm:<alg_list> + call assert_equal('filler', getcompletion('set diffopt+=', 'cmdline')[0]) + call assert_equal([], getcompletion('set diffopt+=iblank,foldcolumn:', 'cmdline')) + call assert_equal('patience', getcompletion('set diffopt+=iblank,algorithm:pat*', 'cmdline')[0]) + + " highlight: special parsing, including auto-completing highlight groups + " after ':' + " call assert_equal([&hl, '8'], getcompletion('set hl=', 'cmdline')[0:1]) + " call assert_equal('8', getcompletion('set hl+=', 'cmdline')[0]) + " call assert_equal(['8:', '8b', '8i'], getcompletion('set hl+=8', 'cmdline')[0:2]) + " call assert_equal('8bi', getcompletion('set hl+=8b', 'cmdline')[0]) + " call assert_equal('NonText', getcompletion('set hl+=8:No*ext', 'cmdline')[0]) + " If all the display modes are used up we should be suggesting nothing. Make + " a hl typed option with all the modes which will look like '8bi-nrsuc2d=t', + " and make sure nothing is suggested from that. + " let hl_display_modes = join( + " \ filter(map(getcompletion('set hl+=8', 'cmdline'), + " \ {idx, val -> val[1]}), + " \ {idx, val -> val != ':'}), + " \ '') + " call assert_equal([], getcompletion('set hl+=8'..hl_display_modes, 'cmdline')) + + " + " Test flag lists + " + + " Test set=. Show the original value if nothing is typed after '='. + " Otherwise, the list should avoid showing what's already typed. + set mouse=v + call assert_equal(['v','a','n','i','c','h','r'], getcompletion('set mouse=', 'cmdline')) + set mouse=nvi + call assert_equal(['nvi','a','n','v','i','c','h','r'], getcompletion('set mouse=', 'cmdline')) + call assert_equal(['a','v','i','c','r'], getcompletion('set mouse=hn', 'cmdline')) + + " Test set+=. Never show original value, and it also tries to avoid listing + " flags that's already in the option value. + call assert_equal(['a','c','h','r'], getcompletion('set mouse+=', 'cmdline')) + call assert_equal(['a','c','r'], getcompletion('set mouse+=hn', 'cmdline')) + call assert_equal([], getcompletion('set mouse+=acrhn', 'cmdline')) + + " Test that the position of the expansion is correct (even if there are + " additional values after the current cursor) + call feedkeys(":set mouse=hn\<Left>\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"set mouse=han', @:) + set mouse& + + " Test that other flag list options have auto-complete, but don't + " exhaustively validate their results. + if exists('+concealcursor') + call assert_equal('n', getcompletion('set cocu=', 'cmdline')[0]) + endif + call assert_equal('a', getcompletion('set cpo=', 'cmdline')[1]) + call assert_equal('t', getcompletion('set fo=', 'cmdline')[1]) + if exists('+guioptions') + call assert_equal('!', getcompletion('set go=', 'cmdline')[1]) + endif + call assert_equal('r', getcompletion('set shortmess=', 'cmdline')[1]) + call assert_equal('b', getcompletion('set whichwrap=', 'cmdline')[1]) + + " + "Test set-= + " + + " Normal single-value option just shows the existing value + set ambiwidth=double + call assert_equal(['double'], getcompletion('set ambw-=', 'cmdline')) + set ambiwidth& + + " Works on numbers and term options as well + call assert_equal([string(&laststatus)], getcompletion('set laststatus-=', 'cmdline')) + set t_Ce=testCe + " call assert_equal(['testCe'], getcompletion('set t_Ce-=', 'cmdline')) + set t_Ce& + + " Comma-separated lists should present each option + set diffopt=context:123,,,,,iblank,iwhiteall + call assert_equal(['context:123', 'iblank', 'iwhiteall'], getcompletion('set diffopt-=', 'cmdline')) + call assert_equal(['context:123', 'iblank'], getcompletion('set diffopt-=*n*', 'cmdline')) + call assert_equal(['iblank', 'iwhiteall'], getcompletion('set diffopt-=i', 'cmdline')) + " Don't present more than one option as it doesn't make sense in set-= + call assert_equal([], getcompletion('set diffopt-=iblank,', 'cmdline')) + " Test empty option + set diffopt= + call assert_equal([], getcompletion('set diffopt-=', 'cmdline')) + set diffopt& + + " Test escaping output + call assert_equal('vert:\|', getcompletion('set fillchars-=', 'cmdline')[0]) + + " Test files with commas in name are being parsed and escaped properly + set path=has\\\ space,file\\,with\\,comma,normal_file + if exists('+completeslash') + call assert_equal(['has\\\ space', 'file\,with\,comma', 'normal_file'], getcompletion('set path-=', 'cmdline')) + else + call assert_equal(['has\\\ space', 'file\\,with\\,comma', 'normal_file'], getcompletion('set path-=', 'cmdline')) + endif + set path& + + " Flag list should present orig value, then individual flags + set mouse=v + call assert_equal(['v'], getcompletion('set mouse-=', 'cmdline')) + set mouse=avn + call assert_equal(['avn','a','v','n'], getcompletion('set mouse-=', 'cmdline')) + " Don't auto-complete when we have at least one flags already + call assert_equal([], getcompletion('set mouse-=n', 'cmdline')) + " Test empty option + set mouse= + call assert_equal([], getcompletion('set mouse-=', 'cmdline')) + set mouse& + + " 'whichwrap' is an odd case where it's both flag list and comma-separated + set ww=b,h + call assert_equal(['b','h'], getcompletion('set ww-=', 'cmdline')) + set ww& +endfunc + func Test_set_option_errors() call assert_fails('set scroll=-1', 'E49:') call assert_fails('set backupcopy=', 'E474:') @@ -1433,7 +1719,7 @@ func Test_opt_cdhome() set cdhome& endfunc -func Test_set_completion_2() +func Test_set_completion_fuzzy() CheckOption termguicolors " Test default option completion |