aboutsummaryrefslogtreecommitdiff
path: root/test/functional
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional')
-rw-r--r--test/functional/api/tabpage_spec.lua1
-rw-r--r--test/functional/api/vim_spec.lua1
-rw-r--r--test/functional/autocmd/textyankpost_spec.lua2
-rw-r--r--test/functional/eval/json_functions_spec.lua1
-rw-r--r--test/functional/eval/special_vars_spec.lua4
-rw-r--r--test/functional/eval/string_spec.lua1
-rw-r--r--test/functional/ex_cmds/append_spec.lua54
-rw-r--r--test/functional/ex_cmds/cd_spec.lua152
-rw-r--r--test/functional/ex_cmds/write_spec.lua38
-rw-r--r--test/functional/helpers.lua4
-rw-r--r--test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua9
-rw-r--r--test/functional/legacy/057_sort_spec.lua18
-rw-r--r--test/functional/legacy/backspace_opt_spec.lua67
-rw-r--r--test/functional/legacy/delete_spec.lua99
-rw-r--r--test/functional/legacy/function_sort_spec.lua29
-rw-r--r--test/functional/legacy/searchpos_spec.lua35
-rw-r--r--test/functional/legacy/tagcase_spec.lua150
-rw-r--r--test/functional/options/defaults_spec.lua5
-rw-r--r--test/functional/options/shortmess_spec.lua2
-rw-r--r--test/functional/plugin/matchparen_spec.lua36
-rw-r--r--test/functional/plugin/msgpack_spec.lua1
-rw-r--r--test/functional/ui/highlight_spec.lua69
-rw-r--r--test/functional/ui/mouse_spec.lua31
-rw-r--r--test/functional/ui/wildmode_spec.lua32
-rw-r--r--test/functional/viml/completion_spec.lua653
25 files changed, 1432 insertions, 62 deletions
diff --git a/test/functional/api/tabpage_spec.lua b/test/functional/api/tabpage_spec.lua
index 0f59bbea7b..c782107714 100644
--- a/test/functional/api/tabpage_spec.lua
+++ b/test/functional/api/tabpage_spec.lua
@@ -3,7 +3,6 @@ local helpers = require('test.functional.helpers')
local clear, nvim, tabpage, curtab, eq, ok =
helpers.clear, helpers.nvim, helpers.tabpage, helpers.curtab, helpers.eq,
helpers.ok
-local wait = helpers.wait
local curtabmeths = helpers.curtabmeths
local funcs = helpers.funcs
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 389badb423..20de6d0072 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -1,6 +1,7 @@
-- Sanity checks for vim_* API calls via msgpack-rpc
local helpers = require('test.functional.helpers')
local Screen = require('test.functional.ui.screen')
+local NIL = helpers.NIL
local clear, nvim, eq, neq = helpers.clear, helpers.nvim, helpers.eq, helpers.neq
local ok, nvim_async, feed = helpers.ok, helpers.nvim_async, helpers.feed
local os_name = helpers.os_name
diff --git a/test/functional/autocmd/textyankpost_spec.lua b/test/functional/autocmd/textyankpost_spec.lua
index 0e46aa5641..c26ceeaedc 100644
--- a/test/functional/autocmd/textyankpost_spec.lua
+++ b/test/functional/autocmd/textyankpost_spec.lua
@@ -1,5 +1,5 @@
local helpers = require('test.functional.helpers')
-local clear, eval, eq, insert = helpers.clear, helpers.eval, helpers.eq, helpers.insert
+local clear, eval, eq = helpers.clear, helpers.eval, helpers.eq
local feed, execute, expect, command = helpers.feed, helpers.execute, helpers.expect, helpers.command
local curbufmeths, funcs, neq = helpers.curbufmeths, helpers.funcs, helpers.neq
diff --git a/test/functional/eval/json_functions_spec.lua b/test/functional/eval/json_functions_spec.lua
index 1cece78ce1..b32688a9d2 100644
--- a/test/functional/eval/json_functions_spec.lua
+++ b/test/functional/eval/json_functions_spec.lua
@@ -7,6 +7,7 @@ local eval = helpers.eval
local execute = helpers.execute
local exc_exec = helpers.exc_exec
local redir_exec = helpers.redir_exec
+local NIL = helpers.NIL
describe('json_decode() function', function()
local restart = function(cmd)
diff --git a/test/functional/eval/special_vars_spec.lua b/test/functional/eval/special_vars_spec.lua
index 6ab4e6a7d7..2526483830 100644
--- a/test/functional/eval/special_vars_spec.lua
+++ b/test/functional/eval/special_vars_spec.lua
@@ -1,12 +1,12 @@
local helpers = require('test.functional.helpers')
local exc_exec = helpers.exc_exec
local execute = helpers.execute
-local meths = helpers.meths
local funcs = helpers.funcs
-local meths = helpers.meths
local clear = helpers.clear
local eval = helpers.eval
local eq = helpers.eq
+local meths = helpers.meths
+local NIL = helpers.NIL
describe('Special values', function()
before_each(clear)
diff --git a/test/functional/eval/string_spec.lua b/test/functional/eval/string_spec.lua
index 0fd7587edb..abda2c59cb 100644
--- a/test/functional/eval/string_spec.lua
+++ b/test/functional/eval/string_spec.lua
@@ -8,6 +8,7 @@ local exc_exec = helpers.exc_exec
local redir_exec = helpers.redir_exec
local funcs = helpers.funcs
local write_file = helpers.write_file
+local NIL = helpers.NIL
describe('string() function', function()
before_each(clear)
diff --git a/test/functional/ex_cmds/append_spec.lua b/test/functional/ex_cmds/append_spec.lua
new file mode 100644
index 0000000000..2d5ab8e8c8
--- /dev/null
+++ b/test/functional/ex_cmds/append_spec.lua
@@ -0,0 +1,54 @@
+local helpers = require('test.functional.helpers')
+
+local eq = helpers.eq
+local feed = helpers.feed
+local clear = helpers.clear
+local funcs = helpers.funcs
+local command = helpers.command
+local curbufmeths = helpers.curbufmeths
+
+before_each(function()
+ clear()
+ curbufmeths.set_lines(0, 1, true, { 'foo', 'bar', 'baz' })
+end)
+
+local buffer_contents = function()
+ return curbufmeths.get_lines(0, -1, false)
+end
+
+local cmdtest = function(cmd, prep, ret1)
+ describe(':' .. cmd, function()
+ it(cmd .. 's' .. prep .. ' the current line by default', function()
+ command(cmd .. '\nabc\ndef\n')
+ eq(ret1, buffer_contents())
+ end)
+ -- Used to crash because this invokes history processing which uses
+ -- hist_char2type which after fdb68e35e4c729c7ed097d8ade1da29e5b3f4b31
+ -- crashed.
+ it(cmd .. 's' .. prep .. ' the current line by default when feeding',
+ function()
+ feed(':' .. cmd .. '\nabc\ndef\n.\n')
+ eq(ret1, buffer_contents())
+ end)
+ -- This used to crash since that commit as well.
+ it('opens empty cmdline window', function()
+ local hisline = '" Some comment to be stored in history'
+ feed(':' .. hisline .. '<CR>')
+ feed(':' .. cmd .. '<CR>abc<CR>def<C-f>')
+ eq({ 'def' }, buffer_contents())
+ eq(hisline, funcs.histget(':', -2))
+ eq(cmd, funcs.histget(':'))
+ -- Test that command-line window was launched
+ eq('nofile', curbufmeths.get_option('buftype'))
+ eq('n', funcs.mode(1))
+ feed('<CR>')
+ eq('c', funcs.mode(1))
+ feed('.<CR>')
+ eq('n', funcs.mode(1))
+ eq(ret1, buffer_contents())
+ end)
+ end)
+end
+cmdtest('insert', ' before', { 'abc', 'def', 'foo', 'bar', 'baz' })
+cmdtest('append', ' after', { 'foo', 'abc', 'def', 'bar', 'baz' })
+cmdtest('change', '', { 'abc', 'def', 'bar', 'baz' })
diff --git a/test/functional/ex_cmds/cd_spec.lua b/test/functional/ex_cmds/cd_spec.lua
new file mode 100644
index 0000000000..69467632a4
--- /dev/null
+++ b/test/functional/ex_cmds/cd_spec.lua
@@ -0,0 +1,152 @@
+-- Specs for :cd, :tcd, :lcd and getcwd()
+
+local helpers = require('test.functional.helpers')
+local execute, eq, clear, eval, exc_exec =
+ helpers.execute, helpers.eq, helpers.clear, helpers.eval, helpers.exc_exec
+local lfs = require('lfs')
+
+-- These directories will be created for testing
+local directories = {
+ 'Xtest-functional-ex_cmds-cd_spec.1', -- Tab
+ 'Xtest-functional-ex_cmds-cd_spec.2', -- Window
+ 'Xtest-functional-ex_cmds-cd_spec.3', -- New global
+}
+
+-- Shorthand writing to get the current working directory
+local cwd = function() return eval('getcwd( )') end -- effective working dir
+local wcwd = function() return eval('getcwd( 0 )') end -- window dir
+local tcwd = function() return eval('getcwd(-1, 0)') end -- tab dir
+--local gcwd = function() return eval('getcwd(-1, -1)') end -- global dir
+
+-- Same, except these tell us if there is a working directory at all
+--local lwd = function() return eval('haslocaldir( )') end -- effective working dir
+local wlwd = function() return eval('haslocaldir( 0 )') end -- window dir
+local tlwd = function() return eval('haslocaldir(-1, 0)') end -- tab dir
+--local glwd = function() return eval('haslocaldir(-1, -1)') end -- global dir
+
+-- Test both the `cd` and `chdir` variants
+for _, cmd in ipairs {'cd', 'chdir'} do
+ describe(':*' .. cmd, function()
+ before_each(function()
+ clear()
+ for _, d in ipairs(directories) do
+ lfs.mkdir(d)
+ end
+ end)
+
+ after_each(function()
+ for _, d in ipairs(directories) do
+ lfs.rmdir(d)
+ end
+ end)
+
+ it('works', function()
+ -- Store the initial working directory
+ local globalDir = cwd()
+
+ -- Create a new tab first and verify that is has the same working dir
+ execute('tabnew')
+ eq(globalDir, cwd())
+ eq(globalDir, tcwd()) -- has no tab-local directory
+ eq(0, tlwd())
+ eq(globalDir, wcwd()) -- has no window-local directory
+ eq(0, wlwd())
+
+ -- Change tab-local working directory and verify it is different
+ execute('silent t' .. cmd .. ' ' .. directories[1])
+ eq(globalDir .. '/' .. directories[1], cwd())
+ eq(cwd(), tcwd()) -- working directory maches tab directory
+ eq(1, tlwd())
+ eq(cwd(), wcwd()) -- still no window-directory
+ eq(0, wlwd())
+
+ -- Create a new window in this tab to test `:lcd`
+ execute('new')
+ eq(1, tlwd()) -- Still tab-local working directory
+ eq(0, wlwd()) -- Still no window-local working directory
+ eq(globalDir .. '/' .. directories[1], cwd())
+ execute('silent l' .. cmd .. ' ../' .. directories[2])
+ eq(globalDir .. '/' .. directories[2], cwd())
+ eq(globalDir .. '/' .. directories[1], tcwd())
+ eq(1, wlwd())
+
+ -- Verify the first window still has the tab local directory
+ execute('wincmd w')
+ eq(globalDir .. '/' .. directories[1], cwd())
+ eq(globalDir .. '/' .. directories[1], tcwd())
+ eq(0, wlwd()) -- No window-local directory
+
+ -- Change back to initial tab and verify working directory has stayed
+ execute('tabnext')
+ eq(globalDir, cwd() )
+ eq(0, tlwd())
+ eq(0, wlwd())
+
+ -- Verify global changes don't affect local ones
+ execute('silent ' .. cmd .. ' ' .. directories[3])
+ eq(globalDir .. '/' .. directories[3], cwd())
+ execute('tabnext')
+ eq(globalDir .. '/' .. directories[1], cwd())
+ eq(globalDir .. '/' .. directories[1], tcwd())
+ eq(0, wlwd()) -- Still no window-local directory in this window
+
+ -- Unless the global change happened in a tab with local directory
+ execute('silent ' .. cmd .. ' ..')
+ eq(globalDir, cwd() )
+ eq(0 , tlwd())
+ eq(0 , wlwd())
+ -- Which also affects the first tab
+ execute('tabnext')
+ eq(globalDir, cwd())
+
+ -- But not in a window with its own local directory
+ execute('tabnext | wincmd w')
+ eq(globalDir .. '/' .. directories[2], cwd() )
+ eq(0 , tlwd())
+ eq(globalDir .. '/' .. directories[2], wcwd())
+ end)
+ end)
+end
+
+-- Test legal parameters for 'getcwd' and 'haslocaldir'
+for _, cmd in ipairs {'getcwd', 'haslocaldir'} do
+ describe(cmd..'()', function()
+ before_each(function()
+ clear()
+ end)
+
+ -- Test invalid argument types
+ local err474 = 'Vim(call):E474: Invalid argument'
+ it('fails on string', function()
+ eq(err474, exc_exec('call ' .. cmd .. '("some string")'))
+ end)
+ it('fails on float', function()
+ eq(err474, exc_exec('call ' .. cmd .. '(1.0)'))
+ end)
+ it('fails on list', function()
+ eq(err474, exc_exec('call ' .. cmd .. '([1, 2])'))
+ end)
+ it('fails on dictionary', function()
+ eq(err474, exc_exec('call ' .. cmd .. '({"key": "value"})'))
+ end)
+ it('fails on funcref', function()
+ eq(err474, exc_exec('call ' .. cmd .. '(function("tr"))'))
+ end)
+
+ -- Test invalid numbers
+ it('fails on number less than -1', function()
+ eq(err474, exc_exec('call ' .. cmd .. '(-2)'))
+ end)
+ local err5001 = 'Vim(call):E5001: Higher scope cannot be -1 if lower scope is >= 0.'
+ it('fails on -1 if previous arg is >=0', function()
+ eq(err5001, exc_exec('call ' .. cmd .. '(0, -1)'))
+ end)
+
+ -- Test wrong number of arguments
+ local err118 = 'Vim(call):E118: Too many arguments for function: ' .. cmd
+ it('fails to parse more than one argument', function()
+ eq(err118, exc_exec('call ' .. cmd .. '(0, 0, 0)'))
+ end)
+ end)
+end
+
diff --git a/test/functional/ex_cmds/write_spec.lua b/test/functional/ex_cmds/write_spec.lua
new file mode 100644
index 0000000000..d90b297ca8
--- /dev/null
+++ b/test/functional/ex_cmds/write_spec.lua
@@ -0,0 +1,38 @@
+-- Specs for :write
+
+local helpers = require('test.functional.helpers')
+local eq, eval, clear, write_file, execute, source =
+ helpers.eq, helpers.eval, helpers.clear, helpers.write_file,
+ helpers.execute, helpers.source
+
+describe(':write', function()
+ it('&backupcopy=auto preserves symlinks', function()
+ clear('set backupcopy=auto')
+ os.remove('test_bkc_file.txt')
+ os.remove('test_bkc_link.txt')
+ write_file('test_bkc_file.txt', 'content0')
+ execute("silent !ln -s test_bkc_file.txt test_bkc_link.txt")
+ source([[
+ edit test_bkc_link.txt
+ call setline(1, ['content1'])
+ write
+ ]])
+ eq(eval("['content1']"), eval("readfile('test_bkc_file.txt')"))
+ eq(eval("['content1']"), eval("readfile('test_bkc_link.txt')"))
+ end)
+
+ it('&backupcopy=no replaces symlink with new file', function()
+ clear('set backupcopy=no')
+ os.remove('test_bkc_file.txt')
+ os.remove('test_bkc_link.txt')
+ write_file('test_bkc_file.txt', 'content0')
+ execute("silent !ln -s test_bkc_file.txt test_bkc_link.txt")
+ source([[
+ edit test_bkc_link.txt
+ call setline(1, ['content1'])
+ write
+ ]])
+ eq(eval("['content0']"), eval("readfile('test_bkc_file.txt')"))
+ eq(eval("['content1']"), eval("readfile('test_bkc_link.txt')"))
+ end)
+end)
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index a382641cff..6ccadda72d 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -1,5 +1,4 @@
require('coxpcall')
-NIL = require('mpack').NIL
local lfs = require('lfs')
local assert = require('luassert')
local ChildProcessStream = require('nvim.child_process_stream')
@@ -10,6 +9,8 @@ local nvim_argv = {nvim_prog, '-u', 'NONE', '-i', 'NONE', '-N',
'--cmd', 'set shortmess+=I background=light noswapfile noautoindent laststatus=1 undodir=. directory=. viewdir=. backupdir=.',
'--embed'}
+local mpack = require('mpack')
+
-- Formulate a path to the directory containing nvim. We use this to
-- help run test executables. It helps to keep the tests working, even
-- when the build is not in the default location.
@@ -452,4 +453,5 @@ return {
curbufmeths = curbufmeths,
curwinmeths = curwinmeths,
curtabmeths = curtabmeths,
+ NIL = mpack.NIL
}
diff --git a/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua b/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
index 1359b45228..2a4c0149fa 100644
--- a/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
+++ b/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
@@ -31,7 +31,8 @@ local function run_test_with_regexpengine(regexpengine)
h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐẔ
i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑẕ
j 0123❤x
- k combinations]])
+ k combinations
+ l ä ö ü ᾱ̆́]])
execute('set re=' .. regexpengine)
@@ -85,6 +86,11 @@ local function run_test_with_regexpengine(regexpengine)
execute([[let @w=':%s#comb[i]nations#œ̄ṣ́m̥̄ᾱ̆́#g']])
execute('@w')
+ -- Line l. Ex command ":s/ \?/ /g" should NOT split multi-byte characters
+ -- into bytes (fixed by vim-7.3.192).
+ execute([[/^l]])
+ execute([[s/ \?/ /g]])
+
-- Additional tests. Test matchstr() with multi-byte characters.
feed('G')
execute([[put =matchstr(\"אבגד\", \".\", 0, 2)]]) -- ב
@@ -123,6 +129,7 @@ local function run_test_with_regexpengine(regexpengine)
i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑ
j 012❤
k œ̄ṣ́m̥̄ᾱ̆́
+ l ä ö ü ᾱ̆́
ב
בג
א
diff --git a/test/functional/legacy/057_sort_spec.lua b/test/functional/legacy/057_sort_spec.lua
index 7eed31e292..36062ded3a 100644
--- a/test/functional/legacy/057_sort_spec.lua
+++ b/test/functional/legacy/057_sort_spec.lua
@@ -668,4 +668,22 @@ describe(':sort', function()
b0b101100
b0b111000]])
end)
+
+ it('float', function()
+ insert([[
+ 1.234
+ 0.88
+ 123.456
+ 1.15e-6
+ -1.1e3
+ -1.01e3]])
+ execute([[sort f]])
+ expect([[
+ -1.1e3
+ -1.01e3
+ 1.15e-6
+ 0.88
+ 1.234
+ 123.456]])
+ end)
end)
diff --git a/test/functional/legacy/backspace_opt_spec.lua b/test/functional/legacy/backspace_opt_spec.lua
new file mode 100644
index 0000000000..b40019a410
--- /dev/null
+++ b/test/functional/legacy/backspace_opt_spec.lua
@@ -0,0 +1,67 @@
+local helpers = require('test.functional.helpers')
+local call, clear = helpers.call, helpers.clear
+local source, eq, nvim = helpers.source, helpers.eq, helpers.meths
+
+describe("test 'backspace' settings", function()
+ before_each(function()
+ clear()
+
+ source([[
+ func Exec(expr)
+ let str=''
+ try
+ exec a:expr
+ catch /.*/
+ let str=v:exception
+ endtry
+ return str
+ endfunc
+
+ func Test_backspace_option()
+ set backspace=
+ call assert_equal('', &backspace)
+ set backspace=indent
+ call assert_equal('indent', &backspace)
+ set backspace=eol
+ call assert_equal('eol', &backspace)
+ set backspace=start
+ call assert_equal('start', &backspace)
+ " Add the value
+ set backspace=
+ set backspace=indent
+ call assert_equal('indent', &backspace)
+ set backspace+=eol
+ call assert_equal('indent,eol', &backspace)
+ set backspace+=start
+ call assert_equal('indent,eol,start', &backspace)
+ " Delete the value
+ set backspace-=indent
+ call assert_equal('eol,start', &backspace)
+ set backspace-=start
+ call assert_equal('eol', &backspace)
+ set backspace-=eol
+ call assert_equal('', &backspace)
+ " Check the error
+ call assert_equal(0, match(Exec('set backspace=ABC'), '.*E474'))
+ call assert_equal(0, match(Exec('set backspace+=def'), '.*E474'))
+ " NOTE: Vim doesn't check following error...
+ "call assert_equal(0, match(Exec('set backspace-=ghi'), '.*E474'))
+
+ " Check backwards compatibility with version 5.4 and earlier
+ set backspace=0
+ call assert_equal('0', &backspace)
+ set backspace=1
+ call assert_equal('1', &backspace)
+ set backspace=2
+ call assert_equal('2', &backspace)
+ call assert_false(match(Exec('set backspace=3'), '.*E474'))
+ call assert_false(match(Exec('set backspace=10'), '.*E474'))
+ endfunc
+ ]])
+ end)
+
+ it('works', function()
+ call('Test_backspace_option')
+ eq({}, nvim.get_vvar('errors'))
+ end)
+end)
diff --git a/test/functional/legacy/delete_spec.lua b/test/functional/legacy/delete_spec.lua
new file mode 100644
index 0000000000..cd18a8f750
--- /dev/null
+++ b/test/functional/legacy/delete_spec.lua
@@ -0,0 +1,99 @@
+local helpers = require('test.functional.helpers')
+local clear, source = helpers.clear, helpers.source
+local eq, eval, execute = helpers.eq, helpers.eval, helpers.execute
+
+describe('Test for delete()', function()
+ before_each(clear)
+
+ it('file delete', function()
+ execute('split Xfile')
+ execute("call setline(1, ['a', 'b'])")
+ execute('wq')
+ eq(eval("['a', 'b']"), eval("readfile('Xfile')"))
+ eq(0, eval("delete('Xfile')"))
+ eq(-1, eval("delete('Xfile')"))
+ end)
+
+ it('directory delete', function()
+ execute("call mkdir('Xdir1')")
+ eq(1, eval("isdirectory('Xdir1')"))
+ eq(0, eval("delete('Xdir1', 'd')"))
+ eq(0, eval("isdirectory('Xdir1')"))
+ eq(-1, eval("delete('Xdir1', 'd')"))
+ end)
+ it('recursive delete', function()
+ execute("call mkdir('Xdir1')")
+ execute("call mkdir('Xdir1/subdir')")
+ execute("call mkdir('Xdir1/empty')")
+ execute('split Xdir1/Xfile')
+ execute("call setline(1, ['a', 'b'])")
+ execute('w')
+ execute('w Xdir1/subdir/Xfile')
+ execute('close')
+
+ eq(1, eval("isdirectory('Xdir1')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir1/Xfile')"))
+ eq(1, eval("isdirectory('Xdir1/subdir')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir1/subdir/Xfile')"))
+ eq(1, eval("isdirectory('Xdir1/empty')"))
+ eq(0, eval("delete('Xdir1', 'rf')"))
+ eq(0, eval("isdirectory('Xdir1')"))
+ eq(-1, eval("delete('Xdir1', 'd')"))
+ end)
+
+ it('symlink delete', function()
+ source([[
+ split Xfile
+ call setline(1, ['a', 'b'])
+ wq
+ silent !ln -s Xfile Xlink
+ ]])
+ -- Delete the link, not the file
+ eq(0, eval("delete('Xlink')"))
+ eq(-1, eval("delete('Xlink')"))
+ eq(0, eval("delete('Xfile')"))
+ end)
+
+ it('symlink directory delete', function()
+ execute("call mkdir('Xdir1')")
+ execute("silent !ln -s Xdir1 Xlink")
+ eq(1, eval("isdirectory('Xdir1')"))
+ eq(1, eval("isdirectory('Xlink')"))
+ -- Delete the link, not the directory
+ eq(0, eval("delete('Xlink')"))
+ eq(-1, eval("delete('Xlink')"))
+ eq(0, eval("delete('Xdir1', 'd')"))
+ end)
+
+ it('symlink recursive delete', function()
+ source([[
+ call mkdir('Xdir3')
+ call mkdir('Xdir3/subdir')
+ call mkdir('Xdir4')
+ split Xdir3/Xfile
+ call setline(1, ['a', 'b'])
+ w
+ w Xdir3/subdir/Xfile
+ w Xdir4/Xfile
+ close
+ silent !ln -s ../Xdir4 Xdir3/Xlink
+ ]])
+
+ eq(1, eval("isdirectory('Xdir3')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir3/Xfile')"))
+ eq(1, eval("isdirectory('Xdir3/subdir')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir3/subdir/Xfile')"))
+ eq(1, eval("isdirectory('Xdir4')"))
+ eq(1, eval("isdirectory('Xdir3/Xlink')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir4/Xfile')"))
+
+ eq(0, eval("delete('Xdir3', 'rf')"))
+ eq(0, eval("isdirectory('Xdir3')"))
+ eq(-1, eval("delete('Xdir3', 'd')"))
+ -- symlink is deleted, not the directory it points to
+ eq(1, eval("isdirectory('Xdir4')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir4/Xfile')"))
+ eq(0, eval("delete('Xdir4/Xfile')"))
+ eq(0, eval("delete('Xdir4', 'd')"))
+ end)
+end)
diff --git a/test/functional/legacy/function_sort_spec.lua b/test/functional/legacy/function_sort_spec.lua
new file mode 100644
index 0000000000..9083911021
--- /dev/null
+++ b/test/functional/legacy/function_sort_spec.lua
@@ -0,0 +1,29 @@
+local helpers = require('test.functional.helpers')
+local clear = helpers.clear
+local eq = helpers.eq
+local eval = helpers.eval
+
+describe('sort', function()
+ before_each(clear)
+
+ it('numbers compared as strings', function()
+ eq({1, 2, 3}, eval('sort([3, 2, 1])'))
+ eq({13, 28, 3}, eval('sort([3, 28, 13])'))
+ end)
+
+ it('numbers compared as numeric', function()
+ eq({1, 2, 3}, eval("sort([3, 2, 1], 'n')"))
+ eq({3, 13, 28}, eval("sort([3, 28, 13], 'n')"))
+ -- Strings are not sorted.
+ eq({'13', '28', '3'}, eval("sort(['13', '28', '3'], 'n')"))
+ end)
+
+ it('numbers compared as numbers', function()
+ eq({3, 13, 28}, eval("sort([13, 28, 3], 'N')"))
+ eq({'3', '13', '28'}, eval("sort(['13', '28', '3'], 'N')"))
+ end)
+
+ it('numbers compared as float', function()
+ eq({0.28, 3, 13.5}, eval("sort([13.5, 0.28, 3], 'f')"))
+ end)
+end)
diff --git a/test/functional/legacy/searchpos_spec.lua b/test/functional/legacy/searchpos_spec.lua
new file mode 100644
index 0000000000..1c9b1ccee6
--- /dev/null
+++ b/test/functional/legacy/searchpos_spec.lua
@@ -0,0 +1,35 @@
+local helpers = require('test.functional.helpers')
+local call = helpers.call
+local clear = helpers.clear
+local execute = helpers.execute
+local eq = helpers.eq
+local eval = helpers.eval
+local insert = helpers.insert
+
+describe('searchpos', function()
+ before_each(clear)
+
+ it('is working', function()
+ insert([[
+ 1a3
+ 123xyz]])
+
+ call('cursor', 1, 1)
+ eq({1, 1, 2}, eval([[searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW')]]))
+ call('cursor', 1, 2)
+ eq({2, 1, 1}, eval([[searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW')]]))
+
+ execute('set cpo-=c')
+ call('cursor', 1, 2)
+ eq({1, 2, 2}, eval([[searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW')]]))
+ call('cursor', 1, 3)
+ eq({1, 3, 1}, eval([[searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW')]]))
+
+ -- Now with \zs, first match is in column 0, "a" is matched.
+ call('cursor', 1, 3)
+ eq({2, 4, 2}, eval([[searchpos('\%(\([a-z]\)\|\_.\)\{-}\zsxyz', 'pcW')]]))
+ -- With z flag start at cursor column, don't see the "a".
+ call('cursor', 1, 3)
+ eq({2, 4, 1}, eval([[searchpos('\%(\([a-z]\)\|\_.\)\{-}\zsxyz', 'pcWz')]]))
+ end)
+end)
diff --git a/test/functional/legacy/tagcase_spec.lua b/test/functional/legacy/tagcase_spec.lua
new file mode 100644
index 0000000000..9a8c6fbe42
--- /dev/null
+++ b/test/functional/legacy/tagcase_spec.lua
@@ -0,0 +1,150 @@
+local helpers = require('test.functional.helpers')
+local clear = helpers.clear
+local eq = helpers.eq
+local eval = helpers.eval
+local exc_exec = helpers.exc_exec
+local expect = helpers.expect
+local insert = helpers.insert
+local source = helpers.source
+local write_file = helpers.write_file
+
+describe("'tagcase' option", function()
+ setup(function()
+ write_file('Xtags', [[
+ Bar Xtext 3
+ Foo Xtext 2
+ foo Xtext 4]])
+ end)
+
+ before_each(function()
+ clear()
+ source([[
+ lang mess C
+ set tags=Xtags]])
+ end)
+
+ teardown(function()
+ os.remove('Xtags')
+ end)
+
+ it('should have correct default values', function()
+ source([[
+ set ic&
+ setg tc&
+ setl tc&
+ ]])
+
+ eq(0, eval('&ic'))
+ eq('followic', eval('&g:tc'))
+ eq('followic', eval('&l:tc'))
+ eq('followic', eval('&tc'))
+ end)
+
+ it('should accept <empty> only for setlocal', function()
+ -- Verify that the local setting accepts <empty> but that the global setting
+ -- does not. The first of these (setting the local value to <empty>) should
+ -- succeed; the other two should fail.
+ eq(0, exc_exec('setl tc='))
+ eq('Vim(setglobal):E474: Invalid argument: tc=', exc_exec('setg tc='))
+ eq('Vim(set):E474: Invalid argument: tc=', exc_exec('set tc='))
+ end)
+
+ it("should work with 'ignorecase' correctly in all combinations", function()
+ -- Verify that the correct number of matching tags is found for all values of
+ -- 'ignorecase' and global and local values 'tagcase', in all combinations.
+ insert([[
+
+ Foo
+ Bar
+ foo
+
+ end text]])
+
+ source([[
+ for &ic in [0, 1]
+ for &g:tc in ["followic", "ignore", "match"]
+ for &l:tc in ["", "followic", "ignore", "match"]
+ call append('$', "ic=".&ic." g:tc=".&g:tc." l:tc=".&l:tc." tc=".&tc)
+ call append('$', len(taglist("^foo$")))
+ call append('$', len(taglist("^Foo$")))
+ endfor
+ endfor
+ endfor
+
+ 1,/^end text$/d]])
+
+ expect([[
+ ic=0 g:tc=followic l:tc= tc=followic
+ 1
+ 1
+ ic=0 g:tc=followic l:tc=followic tc=followic
+ 1
+ 1
+ ic=0 g:tc=followic l:tc=ignore tc=ignore
+ 2
+ 2
+ ic=0 g:tc=followic l:tc=match tc=match
+ 1
+ 1
+ ic=0 g:tc=ignore l:tc= tc=ignore
+ 2
+ 2
+ ic=0 g:tc=ignore l:tc=followic tc=followic
+ 1
+ 1
+ ic=0 g:tc=ignore l:tc=ignore tc=ignore
+ 2
+ 2
+ ic=0 g:tc=ignore l:tc=match tc=match
+ 1
+ 1
+ ic=0 g:tc=match l:tc= tc=match
+ 1
+ 1
+ ic=0 g:tc=match l:tc=followic tc=followic
+ 1
+ 1
+ ic=0 g:tc=match l:tc=ignore tc=ignore
+ 2
+ 2
+ ic=0 g:tc=match l:tc=match tc=match
+ 1
+ 1
+ ic=1 g:tc=followic l:tc= tc=followic
+ 2
+ 2
+ ic=1 g:tc=followic l:tc=followic tc=followic
+ 2
+ 2
+ ic=1 g:tc=followic l:tc=ignore tc=ignore
+ 2
+ 2
+ ic=1 g:tc=followic l:tc=match tc=match
+ 1
+ 1
+ ic=1 g:tc=ignore l:tc= tc=ignore
+ 2
+ 2
+ ic=1 g:tc=ignore l:tc=followic tc=followic
+ 2
+ 2
+ ic=1 g:tc=ignore l:tc=ignore tc=ignore
+ 2
+ 2
+ ic=1 g:tc=ignore l:tc=match tc=match
+ 1
+ 1
+ ic=1 g:tc=match l:tc= tc=match
+ 1
+ 1
+ ic=1 g:tc=match l:tc=followic tc=followic
+ 2
+ 2
+ ic=1 g:tc=match l:tc=ignore tc=ignore
+ 2
+ 2
+ ic=1 g:tc=match l:tc=match tc=match
+ 1
+ 1]])
+ end)
+end)
diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua
index 7f0892ee3a..d4c3267997 100644
--- a/test/functional/options/defaults_spec.lua
+++ b/test/functional/options/defaults_spec.lua
@@ -1,8 +1,7 @@
local helpers = require('test.functional.helpers')
local Screen = require('test.functional.ui.screen')
-local clear, feed = helpers.clear, helpers.feed
-local eval, eq, neq = helpers.eval, helpers.eq, helpers.neq
-local execute, source, expect = helpers.execute, helpers.source, helpers.expect
+local clear, eval, eq = helpers.clear, helpers.eval, helpers.eq
+local execute = helpers.execute
local function init_session(...)
local args = { helpers.nvim_prog, '-i', 'NONE', '--embed',
diff --git a/test/functional/options/shortmess_spec.lua b/test/functional/options/shortmess_spec.lua
index 04a64d2943..4455ef663f 100644
--- a/test/functional/options/shortmess_spec.lua
+++ b/test/functional/options/shortmess_spec.lua
@@ -1,6 +1,6 @@
local helpers = require('test.functional.helpers')
local Screen = require('test.functional.ui.screen')
-local clear, feed, execute = helpers.clear, helpers.feed, helpers.execute
+local clear, execute = helpers.clear, helpers.execute
describe("'shortmess'", function()
local screen
diff --git a/test/functional/plugin/matchparen_spec.lua b/test/functional/plugin/matchparen_spec.lua
new file mode 100644
index 0000000000..d8c1f2d392
--- /dev/null
+++ b/test/functional/plugin/matchparen_spec.lua
@@ -0,0 +1,36 @@
+local helpers = require('test.functional.helpers')
+local Screen = require('test.functional.ui.screen')
+local clear, feed, execute = helpers.clear, helpers.feed, helpers.execute
+
+describe('matchparen', function()
+ local screen
+
+ before_each(function()
+ clear()
+ screen = Screen.new(20,5)
+ screen:attach()
+ screen:set_default_attr_ignore( {{bold=true, foreground=Screen.colors.Blue}} )
+ end)
+
+ it('uses correct column after i_<Up>. Vim patch 7.4.1296', function()
+ execute('set noai nosi nocin')
+ execute('runtime plugin/matchparen.vim')
+ feed('ivoid f_test()<cr>')
+ feed('{<cr>')
+ feed('}')
+
+ -- critical part: up + cr should result in an empty line inbetween the
+ -- brackets... if the bug is there, the empty line will be before the '{'
+ feed('<up>')
+ feed('<cr>')
+
+ screen:expect([[
+ void f_test() |
+ { |
+ ^ |
+ } |
+ {1:-- INSERT --} |
+ ]], {[1] = {bold = true}})
+
+ end)
+end)
diff --git a/test/functional/plugin/msgpack_spec.lua b/test/functional/plugin/msgpack_spec.lua
index 246b26188f..60ba88e55b 100644
--- a/test/functional/plugin/msgpack_spec.lua
+++ b/test/functional/plugin/msgpack_spec.lua
@@ -3,6 +3,7 @@ local meths = helpers.meths
local eq, nvim_eval, nvim_command, exc_exec =
helpers.eq, helpers.eval, helpers.command, helpers.exc_exec
local ok = helpers.ok
+local NIL = helpers.NIL
local plugin_helpers = require('test.functional.plugin.helpers')
local reset = plugin_helpers.reset
diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua
index 6a89b0983d..4b0173fa89 100644
--- a/test/functional/ui/highlight_spec.lua
+++ b/test/functional/ui/highlight_spec.lua
@@ -1,5 +1,6 @@
local helpers = require('test.functional.helpers')
local Screen = require('test.functional.ui.screen')
+local os = require('os')
local clear, feed = helpers.clear, helpers.feed
local execute, request, eq = helpers.execute, helpers.request, helpers.eq
@@ -16,6 +17,73 @@ describe('color scheme compatibility', function()
end)
end)
+describe('manual syntax highlight', function()
+ -- When using manual syntax highlighting, it should be preserved even when
+ -- switching buffers... bug did only occur without :set hidden
+ -- Ref: vim patch 7.4.1236
+ local screen
+
+ before_each(function()
+ clear()
+ screen = Screen.new(20,5)
+ screen:attach()
+ --ignore highligting of ~-lines
+ screen:set_default_attr_ignore( {{bold=true, foreground=Screen.colors.Blue}} )
+ --syntax highlight for vimcscripts "echo"
+ screen:set_default_attr_ids( {[1] = {bold=true, foreground=Screen.colors.Brown}} )
+ end)
+
+ after_each(function()
+ screen:detach()
+ os.remove('Xtest-functional-ui-highlight.tmp.vim')
+ end)
+
+ -- test with "set hidden" even if the bug did not occur this way
+ it("works with buffer switch and 'hidden'", function()
+ execute('e tmp1.vim')
+ execute('e Xtest-functional-ui-highlight.tmp.vim')
+ execute('filetype on')
+ execute('syntax manual')
+ execute('set ft=vim')
+ execute('set syntax=ON')
+ feed('iecho 1<esc>0')
+
+ execute('set hidden')
+ execute('w')
+ execute('bn')
+ execute('bp')
+ screen:expect([[
+ {1:^echo} 1 |
+ ~ |
+ ~ |
+ ~ |
+ <f 1 --100%-- col 1 |
+ ]])
+ end)
+
+ it("works with buffer switch and 'nohidden'", function()
+ execute('e tmp1.vim')
+ execute('e Xtest-functional-ui-highlight.tmp.vim')
+ execute('filetype on')
+ execute('syntax manual')
+ execute('set ft=vim')
+ execute('set syntax=ON')
+ feed('iecho 1<esc>0')
+
+ execute('set nohidden')
+ execute('w')
+ execute('bn')
+ execute('bp')
+ screen:expect([[
+ {1:^echo} 1 |
+ ~ |
+ ~ |
+ ~ |
+ <ht.tmp.vim" 1L, 7C |
+ ]])
+ end)
+end)
+
describe('Default highlight groups', function()
-- Test the default attributes for highlight groups shown by the :highlight
@@ -38,6 +106,7 @@ describe('Default highlight groups', function()
after_each(function()
screen:detach()
end)
+
it('window status bar', function()
screen:set_default_attr_ids({
[1] = {reverse = true, bold = true}, -- StatusLine
diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua
index da9d6a0cd2..d0d791308b 100644
--- a/test/functional/ui/mouse_spec.lua
+++ b/test/functional/ui/mouse_spec.lua
@@ -426,4 +426,35 @@ describe('Mouse input', function()
|
]])
end)
+
+ it('horizontal scrolling', function()
+ feed("<esc>:set nowrap<cr>")
+
+ feed("a <esc>20Ab<esc>")
+ screen:expect([[
+ |
+ |
+ bbbbbbbbbbbbbbb^b |
+ ~ |
+ |
+ ]])
+
+ feed("<ScrollWheelLeft><0,0>")
+ screen:expect([[
+ |
+ |
+ n bbbbbbbbbbbbbbbbbbb^b |
+ ~ |
+ |
+ ]])
+
+ feed("^<ScrollWheelRight><0,0>")
+ screen:expect([[
+ g |
+ |
+ ^t and selection bbbbbbbbb|
+ ~ |
+ |
+ ]])
+ end)
end)
diff --git a/test/functional/ui/wildmode_spec.lua b/test/functional/ui/wildmode_spec.lua
index de2f3e469d..c57d4abcbf 100644
--- a/test/functional/ui/wildmode_spec.lua
+++ b/test/functional/ui/wildmode_spec.lua
@@ -1,6 +1,7 @@
local helpers = require('test.functional.helpers')
local Screen = require('test.functional.ui.screen')
local clear, feed, execute = helpers.clear, helpers.feed, helpers.execute
+local funcs = helpers.funcs
describe("'wildmode'", function()
local screen
@@ -30,3 +31,34 @@ describe("'wildmode'", function()
end)
end)
end)
+
+describe('command line completion', function()
+ local screen
+
+ before_each(function()
+ clear()
+ screen = Screen.new(40, 5)
+ screen:attach()
+ screen:set_default_attr_ignore({{bold=true, foreground=Screen.colors.Blue}})
+ end)
+
+ after_each(function()
+ os.remove('Xtest-functional-viml-compl-dir')
+ end)
+
+ it('lists directories with empty PATH', function()
+ local tmp = funcs.tempname()
+ execute('e '.. tmp)
+ execute('cd %:h')
+ execute("call mkdir('Xtest-functional-viml-compl-dir')")
+ execute('let $PATH=""')
+ feed(':!<tab><bs>')
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ :!Xtest-functional-viml-compl-dir^ |
+ ]])
+ end)
+end)
diff --git a/test/functional/viml/completion_spec.lua b/test/functional/viml/completion_spec.lua
index 8b507c8ffc..0271540fe3 100644
--- a/test/functional/viml/completion_spec.lua
+++ b/test/functional/viml/completion_spec.lua
@@ -1,13 +1,27 @@
-
local helpers = require('test.functional.helpers')
local Screen = require('test.functional.ui.screen')
local clear, feed = helpers.clear, helpers.feed
local eval, eq, neq = helpers.eval, helpers.eq, helpers.neq
+local insert = helpers.insert
local execute, source, expect = helpers.execute, helpers.source, helpers.expect
describe('completion', function()
+ local screen
+
before_each(function()
clear()
+ screen = Screen.new(60, 8)
+ screen:attach()
+ screen:set_default_attr_ignore({{bold=true, foreground=Screen.colors.Blue}})
+ screen:set_default_attr_ids({
+ [1] = {background = Screen.colors.LightMagenta},
+ [2] = {background = Screen.colors.Grey},
+ [3] = {bold = true},
+ [4] = {bold = true, foreground = Screen.colors.SeaGreen},
+ [5] = {foreground = Screen.colors.Red},
+ [6] = {background = Screen.colors.Black},
+ [7] = {foreground = Screen.colors.White, background = Screen.colors.Red},
+ })
end)
describe('v:completed_item', function()
@@ -15,18 +29,40 @@ describe('completion', function()
eq({}, eval('v:completed_item'))
end)
it('is empty dict if the candidate is not inserted', function()
- feed('ifoo<ESC>o<C-x><C-n><C-e><ESC>')
+ feed('ifoo<ESC>o<C-x><C-n>')
+ screen:expect([[
+ foo |
+ foo^ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- Keyword Local completion (^N^P) The only match} |
+ ]])
+ feed('<C-e>')
+ screen:expect([[
+ foo |
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- INSERT --} |
+ ]])
+ feed('<ESC>')
eq({}, eval('v:completed_item'))
end)
it('returns expected dict in normal completion', function()
- feed('ifoo<ESC>o<C-x><C-n><ESC>')
+ feed('ifoo<ESC>o<C-x><C-n>')
eq('foo', eval('getline(2)'))
eq({word = 'foo', abbr = '', menu = '', info = '', kind = ''},
eval('v:completed_item'))
end)
it('is readonly', function()
+ screen:try_resize(80, 8)
feed('ifoo<ESC>o<C-x><C-n><ESC>')
-
execute('let v:completed_item.word = "bar"')
neq(nil, string.find(eval('v:errmsg'), '^E46: '))
execute('let v:errmsg = ""')
@@ -51,17 +87,29 @@ describe('completion', function()
source([[
function! TestOmni(findstart, base) abort
return a:findstart ? 0 : [{'word': 'foo', 'abbr': 'bar',
- \ 'menu': 'baz', 'info': 'foobar', 'kind': 'foobaz'}]
+ \ 'menu': 'baz', 'info': 'foobar', 'kind': 'foobaz'},
+ \ {'word': 'word', 'abbr': 'abbr', 'menu': 'menu', 'info': 'info', 'kind': 'kind'}]
endfunction
setlocal omnifunc=TestOmni
]])
- feed('i<C-x><C-o><ESC>')
+ feed('i<C-x><C-o>')
eq('foo', eval('getline(1)'))
+ screen:expect([[
+ foo^ |
+ {2:bar foobaz baz } |
+ {1:abbr kind menu } |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- Omni completion (^O^N^P) }{4:match 1 of 2} |
+ ]])
eq({word = 'foo', abbr = 'bar', menu = 'baz',
info = 'foobar', kind = 'foobaz'},
eval('v:completed_item'))
end)
end)
+
describe('completeopt', function()
before_each(function()
source([[
@@ -74,30 +122,182 @@ describe('completion', function()
it('inserts the first candidate if default', function()
execute('set completeopt+=menuone')
- feed('ifoo<ESC>o<C-x><C-n>bar<ESC>')
+ feed('ifoo<ESC>o')
+ screen:expect([[
+ foo |
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- INSERT --} |
+ ]])
+ feed('<C-x>')
+ -- the ^X prompt, only test this once
+ screen:expect([[
+ foo |
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)} |
+ ]])
+ feed('<C-n>')
+ screen:expect([[
+ foo |
+ foo^ |
+ {2:foo } |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- Keyword Local completion (^N^P) The only match} |
+ ]])
+ feed('bar<ESC>')
eq('foobar', eval('getline(2)'))
- feed('o<C-r>=TestComplete()<CR><ESC>')
+ feed('o<C-r>=TestComplete()<CR>')
+ screen:expect([[
+ foo |
+ foobar |
+ foo^ |
+ {2:foo } |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- INSERT --} |
+ ]])
eq('foo', eval('getline(3)'))
end)
it('selects the first candidate if noinsert', function()
execute('set completeopt+=menuone,noinsert')
- feed('ifoo<ESC>o<C-x><C-n><C-y><ESC>')
+ feed('ifoo<ESC>o<C-x><C-n>')
+ screen:expect([[
+ foo |
+ ^ |
+ {2:foo } |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- Keyword Local completion (^N^P) The only match} |
+ ]])
+ feed('<C-y>')
+ screen:expect([[
+ foo |
+ foo^ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- INSERT --} |
+ ]])
+ feed('<ESC>')
eq('foo', eval('getline(2)'))
- feed('o<C-r>=TestComplete()<CR><C-y><ESC>')
+ feed('o<C-r>=TestComplete()<CR>')
+ screen:expect([[
+ foo |
+ foo |
+ ^ |
+ {2:foo } |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- INSERT --} |
+ ]])
+ feed('<C-y><ESC>')
eq('foo', eval('getline(3)'))
end)
it('does not insert the first candidate if noselect', function()
execute('set completeopt+=menuone,noselect')
- feed('ifoo<ESC>o<C-x><C-n>bar<ESC>')
+ feed('ifoo<ESC>o<C-x><C-n>')
+ screen:expect([[
+ foo |
+ ^ |
+ {1:foo } |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- Keyword Local completion (^N^P) }{5:Back at original} |
+ ]])
+ feed('b')
+ screen:expect([[
+ foo |
+ b^ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- Keyword Local completion (^N^P) }{5:Back at original} |
+ ]])
+ feed('ar<ESC>')
eq('bar', eval('getline(2)'))
- feed('o<C-r>=TestComplete()<CR>bar<ESC>')
+ feed('o<C-r>=TestComplete()<CR>')
+ screen:expect([[
+ foo |
+ bar |
+ ^ |
+ {1:foo } |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- INSERT --} |
+ ]])
+ feed('bar<ESC>')
eq('bar', eval('getline(3)'))
end)
it('does not select/insert the first candidate if noselect and noinsert', function()
execute('set completeopt+=menuone,noselect,noinsert')
- feed('ifoo<ESC>o<C-x><C-n><ESC>')
+ feed('ifoo<ESC>o<C-x><C-n>')
+ screen:expect([[
+ foo |
+ ^ |
+ {1:foo } |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- Keyword Local completion (^N^P) }{5:Back at original} |
+ ]])
+ feed('<ESC>')
+ screen:expect([[
+ foo |
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]])
eq('', eval('getline(2)'))
- feed('o<C-r>=TestComplete()<CR><ESC>')
+ feed('o<C-r>=TestComplete()<CR>')
+ screen:expect([[
+ foo |
+ |
+ ^ |
+ {1:foo } |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- INSERT --} |
+ ]])
+ feed('<ESC>')
+ screen:expect([[
+ foo |
+ |
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]])
eq('', eval('getline(3)'))
end)
it('does not change modified state if noinsert', function()
@@ -142,12 +342,130 @@ describe('completion', function()
end )
it('completes on each input char', function ()
- feed('i<C-x><C-u>gu<Down><C-y>')
+ feed('i<C-x><C-u>')
+ screen:expect([[
+ ^ |
+ {1:January }{6: } |
+ {1:February }{6: } |
+ {1:March }{6: } |
+ {1:April }{2: } |
+ {1:May }{2: } |
+ {1:June }{2: } |
+ {3:-- User defined completion (^U^N^P) }{5:Back at original} |
+ ]])
+ feed('u')
+ screen:expect([[
+ u^ |
+ {1:January } |
+ {1:February } |
+ {1:June } |
+ {1:July } |
+ {1:August } |
+ ~ |
+ {3:-- User defined completion (^U^N^P) }{5:Back at original} |
+ ]])
+ feed('g')
+ screen:expect([[
+ ug^ |
+ {1:August } |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- User defined completion (^U^N^P) }{5:Back at original} |
+ ]])
+ feed('<Down>')
+ screen:expect([[
+ ug^ |
+ {2:August } |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- User defined completion (^U^N^P) The only match} |
+ ]])
+ feed('<C-y>')
+ screen:expect([[
+ August^ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- INSERT --} |
+ ]])
expect('August')
end)
it("repeats correctly after backspace #2674", function ()
- feed('o<C-x><C-u>Ja<BS><C-n><C-n><Esc>')
+ feed('o<C-x><C-u>Ja')
+ screen:expect([[
+ |
+ Ja^ |
+ {1:January } |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- User defined completion (^U^N^P) }{5:Back at original} |
+ ]])
+ feed('<BS>')
+ screen:expect([[
+ |
+ J^ |
+ {1:January } |
+ {1:June } |
+ {1:July } |
+ ~ |
+ ~ |
+ {3:-- User defined completion (^U^N^P) }{5:Back at original} |
+ ]])
+ feed('<C-n>')
+ screen:expect([[
+ |
+ January^ |
+ {2:January } |
+ {1:June } |
+ {1:July } |
+ ~ |
+ ~ |
+ {3:-- User defined completion (^U^N^P) }{4:match 1 of 3} |
+ ]])
+ feed('<C-n>')
+ screen:expect([[
+ |
+ June^ |
+ {1:January } |
+ {2:June } |
+ {1:July } |
+ ~ |
+ ~ |
+ {3:-- User defined completion (^U^N^P) }{4:match 2 of 3} |
+ ]])
+ feed('<Esc>')
+ screen:expect([[
+ |
+ Jun^e |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]])
feed('.')
+ screen:expect([[
+ |
+ June |
+ Jun^e |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]])
expect([[
June
@@ -155,62 +473,293 @@ describe('completion', function()
end)
end)
+ describe('with a lot of items', function()
+ before_each(function()
+ source([[
+ function! TestComplete() abort
+ call complete(1, map(range(0,100), "string(v:val)"))
+ return ''
+ endfunction
+ ]])
+ execute("set completeopt=menuone,noselect")
+ end)
+
+ it("works", function()
+ feed('i<C-r>=TestComplete()<CR>')
+ screen:expect([[
+ ^ |
+ {1:0 }{6: } |
+ {1:1 }{2: } |
+ {1:2 }{2: } |
+ {1:3 }{2: } |
+ {1:4 }{2: } |
+ {1:5 }{2: } |
+ {3:-- INSERT --} |
+ ]])
+ feed('7')
+ screen:expect([[
+ 7^ |
+ {1:7 }{6: } |
+ {1:70 }{6: } |
+ {1:71 }{6: } |
+ {1:72 }{2: } |
+ {1:73 }{2: } |
+ {1:74 }{2: } |
+ {3:-- INSERT --} |
+ ]])
+ feed('<c-n>')
+ screen:expect([[
+ 7^ |
+ {2:7 }{6: } |
+ {1:70 }{6: } |
+ {1:71 }{6: } |
+ {1:72 }{2: } |
+ {1:73 }{2: } |
+ {1:74 }{2: } |
+ {3:-- INSERT --} |
+ ]])
+ feed('<c-n>')
+ screen:expect([[
+ 70^ |
+ {1:7 }{6: } |
+ {2:70 }{6: } |
+ {1:71 }{6: } |
+ {1:72 }{2: } |
+ {1:73 }{2: } |
+ {1:74 }{2: } |
+ {3:-- INSERT --} |
+ ]])
+ end)
+
+ it('can be navigated with <PageDown>, <PageUp>', function()
+ feed('i<C-r>=TestComplete()<CR>')
+ screen:expect([[
+ ^ |
+ {1:0 }{6: } |
+ {1:1 }{2: } |
+ {1:2 }{2: } |
+ {1:3 }{2: } |
+ {1:4 }{2: } |
+ {1:5 }{2: } |
+ {3:-- INSERT --} |
+ ]])
+ feed('<PageDown>')
+ screen:expect([[
+ ^ |
+ {1:0 }{6: } |
+ {1:1 }{2: } |
+ {1:2 }{2: } |
+ {2:3 } |
+ {1:4 }{2: } |
+ {1:5 }{2: } |
+ {3:-- INSERT --} |
+ ]])
+ feed('<PageDown>')
+ screen:expect([[
+ ^ |
+ {1:5 }{6: } |
+ {1:6 }{2: } |
+ {2:7 } |
+ {1:8 }{2: } |
+ {1:9 }{2: } |
+ {1:10 }{2: } |
+ {3:-- INSERT --} |
+ ]])
+ feed('<Down>')
+ screen:expect([[
+ ^ |
+ {1:5 }{6: } |
+ {1:6 }{2: } |
+ {1:7 }{2: } |
+ {2:8 } |
+ {1:9 }{2: } |
+ {1:10 }{2: } |
+ {3:-- INSERT --} |
+ ]])
+ feed('<PageUp>')
+ screen:expect([[
+ ^ |
+ {1:2 }{6: } |
+ {1:3 }{2: } |
+ {2:4 } |
+ {1:5 }{2: } |
+ {1:6 }{2: } |
+ {1:7 }{2: } |
+ {3:-- INSERT --} |
+ ]])
+ feed('<PageUp>') -- stop on first item
+ screen:expect([[
+ ^ |
+ {2:0 }{6: } |
+ {1:1 }{2: } |
+ {1:2 }{2: } |
+ {1:3 }{2: } |
+ {1:4 }{2: } |
+ {1:5 }{2: } |
+ {3:-- INSERT --} |
+ ]])
+ feed('<PageUp>') -- when on first item, unselect
+ screen:expect([[
+ ^ |
+ {1:0 }{6: } |
+ {1:1 }{2: } |
+ {1:2 }{2: } |
+ {1:3 }{2: } |
+ {1:4 }{2: } |
+ {1:5 }{2: } |
+ {3:-- INSERT --} |
+ ]])
+ feed('<PageUp>') -- when unselected, select last item
+ screen:expect([[
+ ^ |
+ {1:95 }{2: } |
+ {1:96 }{2: } |
+ {1:97 }{2: } |
+ {1:98 }{2: } |
+ {1:99 }{2: } |
+ {2:100 }{6: } |
+ {3:-- INSERT --} |
+ ]])
+ feed('<PageUp>')
+ screen:expect([[
+ ^ |
+ {1:94 }{2: } |
+ {1:95 }{2: } |
+ {2:96 } |
+ {1:97 }{2: } |
+ {1:98 }{2: } |
+ {1:99 }{6: } |
+ {3:-- INSERT --} |
+ ]])
+ feed('<cr>')
+ screen:expect([[
+ 96^ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- INSERT --} |
+ ]])
+ end)
+ end)
+
+
it('disables folding during completion', function ()
execute("set foldmethod=indent")
- feed('i<Tab>foo<CR><Tab>bar<Esc>ggA<C-x><C-l>')
+ feed('i<Tab>foo<CR><Tab>bar<Esc>gg')
+ screen:expect([[
+ ^foo |
+ bar |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]])
+ feed('A<C-x><C-l>')
+ screen:expect([[
+ foo^ |
+ bar |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- Whole line completion (^L^N^P) }{7:Pattern not found} |
+ ]])
eq(-1, eval('foldclosed(1)'))
end)
it('popupmenu is not interrupted by events', function ()
- local screen = Screen.new(40, 8)
- screen:attach()
- screen:set_default_attr_ignore({{bold=true, foreground=Screen.colors.Blue}})
- screen:set_default_attr_ids({
- [1] = {background = Screen.colors.LightMagenta},
- [2] = {background = Screen.colors.Grey},
- [3] = {bold = true},
- [4] = {bold = true, foreground = Screen.colors.SeaGreen},
- })
-
execute("set complete=.")
+
feed('ifoobar fooegg<cr>f<c-p>')
screen:expect([[
- foobar fooegg |
- fooegg^ |
- {1:foobar } |
- {2:fooegg } |
- ~ |
- ~ |
- ~ |
- {3:-- }{4:match 1 of 2} |
+ foobar fooegg |
+ fooegg^ |
+ {1:foobar } |
+ {2:fooegg } |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- Keyword completion (^N^P) }{4:match 1 of 2} |
]])
eval('1 + 1')
-- popupmenu still visible
screen:expect([[
- foobar fooegg |
- fooegg^ |
- {1:foobar } |
- {2:fooegg } |
- ~ |
- ~ |
- ~ |
- {3:-- }{4:match 1 of 2} |
+ foobar fooegg |
+ fooegg^ |
+ {1:foobar } |
+ {2:fooegg } |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- Keyword completion (^N^P) }{4:match 1 of 2} |
]])
feed('<c-p>')
-- Didn't restart completion: old matches still used
screen:expect([[
- foobar fooegg |
- foobar^ |
- {2:foobar } |
- {1:fooegg } |
- ~ |
- ~ |
- ~ |
- {3:-- }{4:match 2 of 2} |
+ foobar fooegg |
+ foobar^ |
+ {2:foobar } |
+ {1:fooegg } |
+ ~ |
+ ~ |
+ ~ |
+ {3:-- Keyword completion (^N^P) }{4:match 2 of 2} |
]])
end)
+
+ describe('from the commandline window', function()
+ it('is cleared after CTRL-C', function ()
+ feed('q:')
+ feed('ifoo faa fee f')
+ screen:expect([[
+ |
+ {8:[No Name] }|
+ :foo faa fee f^ |
+ :~ |
+ :~ |
+ :~ |
+ {9:[Command Line] }|
+ {3:-- INSERT --} |
+ ]], {[3] = {bold = true},
+ [4] = {bold = true, foreground = Screen.colors.SeaGreen},
+ [8] = {reverse = true},
+ [9] = {bold = true, reverse = true}})
+ feed('<c-x><c-n>')
+ screen:expect([[
+ |
+ {8:[No Name] }|
+ :foo faa fee foo^ |
+ :~ {2: foo } |
+ :~ {1: faa } |
+ :~ {1: fee } |
+ {9:[Command Line] }|
+ {3:-- Keyword Local completion (^N^P) }{4:match 1 of 3} |
+ ]],{[1] = {background = Screen.colors.LightMagenta},
+ [2] = {background = Screen.colors.Grey},
+ [3] = {bold = true},
+ [4] = {bold = true, foreground = Screen.colors.SeaGreen},
+ [8] = {reverse = true},
+ [9] = {bold = true, reverse = true}})
+ feed('<c-c>')
+ screen:expect([[
+ |
+ {8:[No Name] }|
+ :foo faa fee foo |
+ :~ |
+ :~ |
+ :~ |
+ {9:[Command Line] }|
+ :foo faa fee foo^ |
+ ]], {[8] = {reverse = true}, [9] = {bold = true, reverse = true}})
+ end)
+ end)
end)
-