aboutsummaryrefslogtreecommitdiff
path: root/test/functional/viml
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/viml')
-rw-r--r--test/functional/viml/completion_spec.lua802
-rw-r--r--test/functional/viml/errorlist_spec.lua30
-rw-r--r--test/functional/viml/function_spec.lua234
-rw-r--r--test/functional/viml/lang_spec.lua30
4 files changed, 750 insertions, 346 deletions
diff --git a/test/functional/viml/completion_spec.lua b/test/functional/viml/completion_spec.lua
index 33f481bae2..70b4717c32 100644
--- a/test/functional/viml/completion_spec.lua
+++ b/test/functional/viml/completion_spec.lua
@@ -2,7 +2,11 @@ local helpers = require('test.functional.helpers')(after_each)
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 feed_command, source, expect = helpers.feed_command, helpers.source, helpers.expect
+local curbufmeths = helpers.curbufmeths
+local command = helpers.command
+local meths = helpers.meths
+local wait = helpers.wait
describe('completion', function()
local screen
@@ -11,8 +15,8 @@ describe('completion', 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({
+ [0] = {bold=true, foreground=Screen.colors.Blue},
[1] = {background = Screen.colors.LightMagenta},
[2] = {background = Screen.colors.Grey},
[3] = {bold = true},
@@ -20,6 +24,8 @@ describe('completion', function()
[5] = {foreground = Screen.colors.Red},
[6] = {background = Screen.colors.Black},
[7] = {foreground = Screen.colors.White, background = Screen.colors.Red},
+ [8] = {reverse = true},
+ [9] = {bold = true, reverse = true},
})
end)
@@ -32,22 +38,22 @@ describe('completion', function()
screen:expect([[
foo |
foo^ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- Keyword Local completion (^N^P) The only match} |
]])
feed('<C-e>')
screen:expect([[
foo |
^ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- INSERT --} |
]])
feed('<ESC>')
@@ -56,38 +62,44 @@ describe('completion', function()
it('returns expected dict in normal completion', function()
feed('ifoo<ESC>o<C-x><C-n>')
eq('foo', eval('getline(2)'))
- eq({word = 'foo', abbr = '', menu = '', info = '', kind = ''},
+ eq({word = 'foo', abbr = '', menu = '',
+ info = '', kind = '', user_data = ''},
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"')
+ feed_command('let v:completed_item.word = "bar"')
neq(nil, string.find(eval('v:errmsg'), '^E46: '))
- execute('let v:errmsg = ""')
+ feed_command('let v:errmsg = ""')
- execute('let v:completed_item.abbr = "bar"')
+ feed_command('let v:completed_item.abbr = "bar"')
neq(nil, string.find(eval('v:errmsg'), '^E46: '))
- execute('let v:errmsg = ""')
+ feed_command('let v:errmsg = ""')
- execute('let v:completed_item.menu = "bar"')
+ feed_command('let v:completed_item.menu = "bar"')
neq(nil, string.find(eval('v:errmsg'), '^E46: '))
- execute('let v:errmsg = ""')
+ feed_command('let v:errmsg = ""')
- execute('let v:completed_item.info = "bar"')
+ feed_command('let v:completed_item.info = "bar"')
neq(nil, string.find(eval('v:errmsg'), '^E46: '))
- execute('let v:errmsg = ""')
+ feed_command('let v:errmsg = ""')
- execute('let v:completed_item.kind = "bar"')
+ feed_command('let v:completed_item.kind = "bar"')
neq(nil, string.find(eval('v:errmsg'), '^E46: '))
- execute('let v:errmsg = ""')
+ feed_command('let v:errmsg = ""')
+
+ feed_command('let v:completed_item.user_data = "bar"')
+ neq(nil, string.find(eval('v:errmsg'), '^E46: '))
+ feed_command('let v:errmsg = ""')
end)
it('returns expected dict in omni completion', function()
source([[
function! TestOmni(findstart, base) abort
return a:findstart ? 0 : [{'word': 'foo', 'abbr': 'bar',
\ 'menu': 'baz', 'info': 'foobar', 'kind': 'foobaz'},
- \ {'word': 'word', 'abbr': 'abbr', 'menu': 'menu', 'info': 'info', 'kind': 'kind'}]
+ \ {'word': 'word', 'abbr': 'abbr', 'menu': 'menu',
+ \ 'info': 'info', 'kind': 'kind'}]
endfunction
setlocal omnifunc=TestOmni
]])
@@ -95,16 +107,16 @@ describe('completion', function()
eq('foo', eval('getline(1)'))
screen:expect([[
foo^ |
- {2:bar foobaz baz } |
- {1:abbr kind menu } |
- ~ |
- ~ |
- ~ |
- ~ |
+ {2:bar foobaz baz }{0: }|
+ {1:abbr kind menu }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- Omni completion (^O^N^P) }{4:match 1 of 2} |
]])
eq({word = 'foo', abbr = 'bar', menu = 'baz',
- info = 'foobar', kind = 'foobaz'},
+ info = 'foobar', kind = 'foobaz', user_data = ''},
eval('v:completed_item'))
end)
end)
@@ -120,16 +132,16 @@ describe('completion', function()
end)
it('inserts the first candidate if default', function()
- execute('set completeopt+=menuone')
+ feed_command('set completeopt+=menuone')
feed('ifoo<ESC>o')
screen:expect([[
foo |
^ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- INSERT --} |
]])
feed('<C-x>')
@@ -137,22 +149,22 @@ describe('completion', function()
screen:expect([[
foo |
^ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)} |
]])
feed('<C-n>')
screen:expect([[
foo |
foo^ |
- {2:foo } |
- ~ |
- ~ |
- ~ |
- ~ |
+ {2:foo }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- Keyword Local completion (^N^P) The only match} |
]])
feed('bar<ESC>')
@@ -162,36 +174,36 @@ describe('completion', function()
foo |
foobar |
foo^ |
- {2:foo } |
- ~ |
- ~ |
- ~ |
+ {2:foo }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- INSERT --} |
]])
eq('foo', eval('getline(3)'))
end)
it('selects the first candidate if noinsert', function()
- execute('set completeopt+=menuone,noinsert')
+ feed_command('set completeopt+=menuone,noinsert')
feed('ifoo<ESC>o<C-x><C-n>')
screen:expect([[
foo |
^ |
- {2:foo } |
- ~ |
- ~ |
- ~ |
- ~ |
+ {2:foo }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- Keyword Local completion (^N^P) The only match} |
]])
feed('<C-y>')
screen:expect([[
foo |
foo^ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- INSERT --} |
]])
feed('<ESC>')
@@ -201,37 +213,37 @@ describe('completion', function()
foo |
foo |
^ |
- {2:foo } |
- ~ |
- ~ |
- ~ |
+ {2:foo }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{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_command('set completeopt+=menuone,noselect')
feed('ifoo<ESC>o<C-x><C-n>')
screen:expect([[
foo |
^ |
- {1:foo } |
- ~ |
- ~ |
- ~ |
- ~ |
+ {1:foo }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- Keyword Local completion (^N^P) }{5:Back at original} |
]])
feed('b')
screen:expect([[
foo |
b^ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- Keyword Local completion (^N^P) }{5:Back at original} |
]])
feed('ar<ESC>')
@@ -241,37 +253,37 @@ describe('completion', function()
foo |
bar |
^ |
- {1:foo } |
- ~ |
- ~ |
- ~ |
+ {1:foo }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{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_command('set completeopt+=menuone,noselect,noinsert')
feed('ifoo<ESC>o<C-x><C-n>')
screen:expect([[
foo |
^ |
- {1:foo } |
- ~ |
- ~ |
- ~ |
- ~ |
+ {1:foo }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- Keyword Local completion (^N^P) }{5:Back at original} |
]])
feed('<ESC>')
screen:expect([[
foo |
^ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
|
]])
eq('', eval('getline(2)'))
@@ -280,10 +292,10 @@ describe('completion', function()
foo |
|
^ |
- {1:foo } |
- ~ |
- ~ |
- ~ |
+ {1:foo }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- INSERT --} |
]])
feed('<ESC>')
@@ -291,28 +303,84 @@ describe('completion', function()
foo |
|
^ |
- ~ |
- ~ |
- ~ |
- ~ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
|
]])
eq('', eval('getline(3)'))
end)
it('does not change modified state if noinsert', function()
- execute('set completeopt+=menuone,noinsert')
- execute('setlocal nomodified')
+ feed_command('set completeopt+=menuone,noinsert')
+ feed_command('setlocal nomodified')
feed('i<C-r>=TestComplete()<CR><ESC>')
eq(0, eval('&l:modified'))
end)
it('does not change modified state if noselect', function()
- execute('set completeopt+=menuone,noselect')
- execute('setlocal nomodified')
+ feed_command('set completeopt+=menuone,noselect')
+ feed_command('setlocal nomodified')
feed('i<C-r>=TestComplete()<CR><ESC>')
eq(0, eval('&l:modified'))
end)
end)
+ describe('completeopt+=noinsert does not add blank undo items', function()
+ before_each(function()
+ source([[
+ function! TestComplete() abort
+ call complete(1, ['foo', 'bar'])
+ return ''
+ endfunction
+ ]])
+ feed_command('set completeopt+=noselect,noinsert')
+ feed_command('inoremap <right> <c-r>=TestComplete()<cr>')
+ end)
+
+ local tests = {
+ ['<up>, <down>, <cr>'] = {'<down><cr>', '<up><cr>'},
+ ['<c-n>, <c-p>, <c-y>'] = {'<c-n><c-y>', '<c-p><c-y>'},
+ }
+
+ for name, seq in pairs(tests) do
+ it('using ' .. name, function()
+ feed('iaaa<esc>')
+ feed('A<right>' .. seq[1] .. '<esc>')
+ feed('A<right><esc>A<right><esc>')
+ feed('A<cr>bbb<esc>')
+ feed('A<right>' .. seq[2] .. '<esc>')
+ feed('A<right><esc>A<right><esc>')
+ feed('A<cr>ccc<esc>')
+ feed('A<right>' .. seq[1] .. '<esc>')
+ feed('A<right><esc>A<right><esc>')
+
+ local expected = {
+ {'foo', 'bar', 'foo'},
+ {'foo', 'bar', 'ccc'},
+ {'foo', 'bar'},
+ {'foo', 'bbb'},
+ {'foo'},
+ {'aaa'},
+ {''},
+ }
+
+ for i = 1, #expected do
+ if i > 1 then
+ feed('u')
+ end
+ eq(expected[i], eval('getline(1, "$")'))
+ end
+
+ for i = #expected, 1, -1 do
+ if i < #expected then
+ feed('<c-r>')
+ end
+ eq(expected[i], eval('getline(1, "$")'))
+ end
+ end)
+ end
+ end)
+
describe("refresh:always", function()
before_each(function()
source([[
@@ -344,56 +412,56 @@ describe('completion', function()
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: } |
+ {1:January }{6: }{0: }|
+ {1:February }{6: }{0: }|
+ {1:March }{6: }{0: }|
+ {1:April }{2: }{0: }|
+ {1:May }{2: }{0: }|
+ {1:June }{2: }{0: }|
{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 } |
- ~ |
+ {1:January }{0: }|
+ {1:February }{0: }|
+ {1:June }{0: }|
+ {1:July }{0: }|
+ {1:August }{0: }|
+ {0:~ }|
{3:-- User defined completion (^U^N^P) }{5:Back at original} |
]])
feed('g')
screen:expect([[
ug^ |
- {1:August } |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
+ {1:August }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- User defined completion (^U^N^P) }{5:Back at original} |
]])
feed('<Down>')
screen:expect([[
ug^ |
- {2:August } |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
+ {2:August }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- User defined completion (^U^N^P) The only match} |
]])
feed('<C-y>')
screen:expect([[
August^ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- INSERT --} |
]])
expect('August')
@@ -403,55 +471,55 @@ describe('completion', function()
screen:expect([[
|
Ja^ |
- {1:January } |
- ~ |
- ~ |
- ~ |
- ~ |
+ {1:January }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- User defined completion (^U^N^P) }{5:Back at original} |
]])
feed('<BS>')
screen:expect([[
|
J^ |
- {1:January } |
- {1:June } |
- {1:July } |
- ~ |
- ~ |
+ {1:January }{0: }|
+ {1:June }{0: }|
+ {1:July }{0: }|
+ {0:~ }|
+ {0:~ }|
{3:-- User defined completion (^U^N^P) }{5:Back at original} |
]])
feed('<C-n>')
screen:expect([[
|
January^ |
- {2:January } |
- {1:June } |
- {1:July } |
- ~ |
- ~ |
+ {2:January }{0: }|
+ {1:June }{0: }|
+ {1:July }{0: }|
+ {0:~ }|
+ {0:~ }|
{3:-- User defined completion (^U^N^P) }{4:match 1 of 3} |
]])
feed('<C-n>')
screen:expect([[
|
June^ |
- {1:January } |
- {2:June } |
- {1:July } |
- ~ |
- ~ |
+ {1:January }{0: }|
+ {2:June }{0: }|
+ {1:July }{0: }|
+ {0:~ }|
+ {0:~ }|
{3:-- User defined completion (^U^N^P) }{4:match 2 of 3} |
]])
feed('<Esc>')
screen:expect([[
|
Jun^e |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
|
]])
feed('.')
@@ -459,14 +527,14 @@ describe('completion', function()
|
June |
Jun^e |
- ~ |
- ~ |
- ~ |
- ~ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
|
]])
expect([[
-
+
June
June]])
end)
@@ -480,52 +548,52 @@ describe('completion', function()
return ''
endfunction
]])
- execute("set completeopt=menuone,noselect")
+ feed_command("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: } |
+ {1:0 }{6: }{0: }|
+ {1:1 }{2: }{0: }|
+ {1:2 }{2: }{0: }|
+ {1:3 }{2: }{0: }|
+ {1:4 }{2: }{0: }|
+ {1:5 }{2: }{0: }|
{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: } |
+ {1:7 }{6: }{0: }|
+ {1:70 }{6: }{0: }|
+ {1:71 }{6: }{0: }|
+ {1:72 }{2: }{0: }|
+ {1:73 }{2: }{0: }|
+ {1:74 }{2: }{0: }|
{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: } |
+ {2:7 }{6: }{0: }|
+ {1:70 }{6: }{0: }|
+ {1:71 }{6: }{0: }|
+ {1:72 }{2: }{0: }|
+ {1:73 }{2: }{0: }|
+ {1:74 }{2: }{0: }|
{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: } |
+ {1:7 }{6: }{0: }|
+ {2:70 }{6: }{0: }|
+ {1:71 }{6: }{0: }|
+ {1:72 }{2: }{0: }|
+ {1:73 }{2: }{0: }|
+ {1:74 }{2: }{0: }|
{3:-- INSERT --} |
]])
end)
@@ -534,111 +602,111 @@ describe('completion', 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: } |
+ {1:0 }{6: }{0: }|
+ {1:1 }{2: }{0: }|
+ {1:2 }{2: }{0: }|
+ {1:3 }{2: }{0: }|
+ {1:4 }{2: }{0: }|
+ {1:5 }{2: }{0: }|
{3:-- INSERT --} |
]])
feed('<PageDown>')
screen:expect([[
^ |
- {1:0 }{6: } |
- {1:1 }{2: } |
- {1:2 }{2: } |
- {2:3 } |
- {1:4 }{2: } |
- {1:5 }{2: } |
+ {1:0 }{6: }{0: }|
+ {1:1 }{2: }{0: }|
+ {1:2 }{2: }{0: }|
+ {2:3 }{0: }|
+ {1:4 }{2: }{0: }|
+ {1:5 }{2: }{0: }|
{3:-- INSERT --} |
]])
feed('<PageDown>')
screen:expect([[
^ |
- {1:5 }{6: } |
- {1:6 }{2: } |
- {2:7 } |
- {1:8 }{2: } |
- {1:9 }{2: } |
- {1:10 }{2: } |
+ {1:5 }{6: }{0: }|
+ {1:6 }{2: }{0: }|
+ {2:7 }{0: }|
+ {1:8 }{2: }{0: }|
+ {1:9 }{2: }{0: }|
+ {1:10 }{2: }{0: }|
{3:-- INSERT --} |
]])
feed('<Down>')
screen:expect([[
^ |
- {1:5 }{6: } |
- {1:6 }{2: } |
- {1:7 }{2: } |
- {2:8 } |
- {1:9 }{2: } |
- {1:10 }{2: } |
+ {1:5 }{6: }{0: }|
+ {1:6 }{2: }{0: }|
+ {1:7 }{2: }{0: }|
+ {2:8 }{0: }|
+ {1:9 }{2: }{0: }|
+ {1:10 }{2: }{0: }|
{3:-- INSERT --} |
]])
feed('<PageUp>')
screen:expect([[
^ |
- {1:2 }{6: } |
- {1:3 }{2: } |
- {2:4 } |
- {1:5 }{2: } |
- {1:6 }{2: } |
- {1:7 }{2: } |
+ {1:2 }{6: }{0: }|
+ {1:3 }{2: }{0: }|
+ {2:4 }{0: }|
+ {1:5 }{2: }{0: }|
+ {1:6 }{2: }{0: }|
+ {1:7 }{2: }{0: }|
{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: } |
+ {2:0 }{6: }{0: }|
+ {1:1 }{2: }{0: }|
+ {1:2 }{2: }{0: }|
+ {1:3 }{2: }{0: }|
+ {1:4 }{2: }{0: }|
+ {1:5 }{2: }{0: }|
{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: } |
+ {1:0 }{6: }{0: }|
+ {1:1 }{2: }{0: }|
+ {1:2 }{2: }{0: }|
+ {1:3 }{2: }{0: }|
+ {1:4 }{2: }{0: }|
+ {1:5 }{2: }{0: }|
{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: } |
+ {1:95 }{2: }{0: }|
+ {1:96 }{2: }{0: }|
+ {1:97 }{2: }{0: }|
+ {1:98 }{2: }{0: }|
+ {1:99 }{2: }{0: }|
+ {2:100 }{6: }{0: }|
{3:-- INSERT --} |
]])
feed('<PageUp>')
screen:expect([[
^ |
- {1:94 }{2: } |
- {1:95 }{2: } |
- {2:96 } |
- {1:97 }{2: } |
- {1:98 }{2: } |
- {1:99 }{6: } |
+ {1:94 }{2: }{0: }|
+ {1:95 }{2: }{0: }|
+ {2:96 }{0: }|
+ {1:97 }{2: }{0: }|
+ {1:98 }{2: }{0: }|
+ {1:99 }{6: }{0: }|
{3:-- INSERT --} |
]])
feed('<cr>')
screen:expect([[
96^ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- INSERT --} |
]])
end)
@@ -646,74 +714,74 @@ describe('completion', function()
it('disables folding during completion', function ()
- execute("set foldmethod=indent")
+ feed_command("set foldmethod=indent")
feed('i<Tab>foo<CR><Tab>bar<Esc>gg')
screen:expect([[
^foo |
bar |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
|
]])
feed('A<C-x><C-l>')
screen:expect([[
foo^ |
bar |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{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 ()
- execute("set complete=.")
+ feed_command("set complete=.")
feed('ifoobar fooegg<cr>f<c-p>')
screen:expect([[
foobar fooegg |
fooegg^ |
- {1:foobar } |
- {2:fooegg } |
- ~ |
- ~ |
- ~ |
+ {1:foobar }{0: }|
+ {2:fooegg }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- Keyword completion (^N^P) }{4:match 1 of 2} |
]])
eval('1 + 1')
-- popupmenu still visible
- screen:expect([[
+ screen:expect{grid=[[
foobar fooegg |
fooegg^ |
- {1:foobar } |
- {2:fooegg } |
- ~ |
- ~ |
- ~ |
+ {1:foobar }{0: }|
+ {2:fooegg }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- Keyword completion (^N^P) }{4:match 1 of 2} |
- ]])
+ ]], unchanged=true}
feed('<c-p>')
-- Didn't restart completion: old matches still used
screen:expect([[
foobar fooegg |
foobar^ |
- {2:foobar } |
- {1:fooegg } |
- ~ |
- ~ |
- ~ |
+ {2:foobar }{0: }|
+ {1:fooegg }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{3:-- Keyword completion (^N^P) }{4:match 2 of 2} |
]])
end)
-
+
describe('from the commandline window', function()
it('is cleared after CTRL-C', function ()
@@ -722,43 +790,173 @@ describe('completion', function()
screen:expect([[
|
{8:[No Name] }|
- :foo faa fee f^ |
- :~ |
- :~ |
- :~ |
+ {0::}foo faa fee f^ |
+ {0::~ }|
+ {0::~ }|
+ {0::~ }|
{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 } |
+ {0::}foo faa fee foo^ |
+ {0::~ }{2: foo }{0: }|
+ {0::~ }{1: faa }{0: }|
+ {0::~ }{1: fee }{0: }|
{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 |
- :~ |
- :~ |
- :~ |
+ {0::}foo faa fee foo |
+ {0::~ }|
+ {0::~ }|
+ {0::~ }|
{9:[Command Line] }|
:foo faa fee foo^ |
- ]], {[8] = {reverse = true}, [9] = {bold = true, reverse = true}})
+ ]])
end)
end)
+
+ describe('with numeric items', function()
+ before_each(function()
+ source([[
+ function! TestComplete() abort
+ call complete(1, g:_complist)
+ return ''
+ endfunction
+ ]])
+ meths.set_option('completeopt', 'menuone,noselect')
+ meths.set_var('_complist', {{
+ word=0,
+ abbr=1,
+ menu=2,
+ kind=3,
+ info=4,
+ icase=5,
+ dup=6,
+ empty=7,
+ }})
+ end)
+
+ it('shows correct variant as word', function()
+ feed('i<C-r>=TestComplete()<CR>')
+ screen:expect([[
+ ^ |
+ {1:1 3 2 }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {3:-- INSERT --} |
+ ]])
+ end)
+ end)
+
+ it("'ignorecase' 'infercase' CTRL-X CTRL-N #6451", function()
+ feed_command('set ignorecase infercase')
+ feed_command('edit BACKERS.md')
+ feed('oX<C-X><C-N>')
+ screen:expect([[
+ # Bountysource Backers |
+ Xnull^ |
+ {2:Xnull }{6: } |
+ {1:Xoxomoon }{6: }ryone who backed our [Bountysource fundraise|
+ {1:Xu }{6: }ountysource.com/teams/neovim/fundraiser)! |
+ {1:Xpayn }{2: } |
+ {1:Xinity }{2: }d URL in BACKERS.md. |
+ {3:-- Keyword Local completion (^N^P) }{4:match 1 of 7} |
+ ]])
+ end)
+
+ it('TextChangedP autocommand', function()
+ curbufmeths.set_lines(0, 1, false, { 'foo', 'bar', 'foobar'})
+ source([[
+ set complete=. completeopt=menuone
+ let g:foo = []
+ autocmd! TextChanged * :call add(g:foo, "N")
+ autocmd! TextChangedI * :call add(g:foo, "I")
+ autocmd! TextChangedP * :call add(g:foo, "P")
+ call cursor(3, 1)
+ ]])
+
+ command('let g:foo = []')
+ feed('o')
+ wait()
+ feed('<esc>')
+ eq({'I'}, eval('g:foo'))
+
+ command('let g:foo = []')
+ feed('S')
+ wait()
+ feed('f')
+ wait()
+ eq({'I', 'I'}, eval('g:foo'))
+ feed('<esc>')
+
+ command('let g:foo = []')
+ feed('S')
+ wait()
+ feed('f')
+ wait()
+ feed('<C-N>')
+ wait()
+ eq({'I', 'I', 'P'}, eval('g:foo'))
+ feed('<esc>')
+
+ command('let g:foo = []')
+ feed('S')
+ wait()
+ feed('f')
+ wait()
+ feed('<C-N>')
+ wait()
+ feed('<C-N>')
+ wait()
+ eq({'I', 'I', 'P', 'P'}, eval('g:foo'))
+ feed('<esc>')
+
+ command('let g:foo = []')
+ feed('S')
+ wait()
+ feed('f')
+ wait()
+ feed('<C-N>')
+ wait()
+ feed('<C-N>')
+ wait()
+ feed('<C-N>')
+ wait()
+ eq({'I', 'I', 'P', 'P', 'P'}, eval('g:foo'))
+ feed('<esc>')
+
+ command('let g:foo = []')
+ feed('S')
+ wait()
+ feed('f')
+ wait()
+ feed('<C-N>')
+ wait()
+ feed('<C-N>')
+ wait()
+ feed('<C-N>')
+ wait()
+ feed('<C-N>')
+ eq({'I', 'I', 'P', 'P', 'P', 'P'}, eval('g:foo'))
+ feed('<esc>')
+
+ eq({'foo', 'bar', 'foobar', 'foo'}, eval('getline(1, "$")'))
+
+ source([[
+ au! TextChanged
+ au! TextChangedI
+ au! TextChangedP
+ set complete&vim completeopt&vim
+ ]])
+ end)
end)
diff --git a/test/functional/viml/errorlist_spec.lua b/test/functional/viml/errorlist_spec.lua
index 56d08771b7..6c5a63e6b1 100644
--- a/test/functional/viml/errorlist_spec.lua
+++ b/test/functional/viml/errorlist_spec.lua
@@ -18,29 +18,27 @@ describe('setqflist()', function()
end)
it('requires a string for {action}', function()
- eq('Vim(call):E114: String required', exc_exec('call setqflist([], 5)'))
- eq('Vim(call):E114: String required', exc_exec('call setqflist([], [])'))
- eq('Vim(call):E114: String required', exc_exec('call setqflist([], {})'))
+ eq('Vim(call):E928: String required', exc_exec('call setqflist([], 5)'))
+ eq('Vim(call):E928: String required', exc_exec('call setqflist([], [])'))
+ eq('Vim(call):E928: String required', exc_exec('call setqflist([], {})'))
end)
it('sets w:quickfix_title', function()
setqflist({''}, 'r', 'foo')
command('copen')
eq(':foo', get_cur_win_var('quickfix_title'))
+ setqflist({''}, 'r', {['title'] = 'qf_title'})
+ eq('qf_title', get_cur_win_var('quickfix_title'))
end)
- it('requires string or number for {title}', function()
- command('copen')
+ it('allows string {what} for backwards compatibility', function()
setqflist({}, 'r', '5')
+ command('copen')
eq(':5', get_cur_win_var('quickfix_title'))
- setqflist({}, 'r', 6)
- eq(':6', get_cur_win_var('quickfix_title'))
- local exc = exc_exec('call setqflist([], "r", function("function"))')
- eq('Vim(call):E729: using Funcref as a String', exc)
- exc = exc_exec('call setqflist([], "r", [])')
- eq('Vim(call):E730: using List as a String', exc)
- exc = exc_exec('call setqflist([], "r", {})')
- eq('Vim(call):E731: using Dictionary as a String', exc)
+ end)
+
+ it('requires a dict for {what}', function()
+ eq('Vim(call):E715: Dictionary required', exc_exec('call setqflist([], "r", function("function"))'))
end)
end)
@@ -56,9 +54,9 @@ describe('setloclist()', function()
end)
it('requires a string for {action}', function()
- eq('Vim(call):E114: String required', exc_exec('call setloclist(0, [], 5)'))
- eq('Vim(call):E114: String required', exc_exec('call setloclist(0, [], [])'))
- eq('Vim(call):E114: String required', exc_exec('call setloclist(0, [], {})'))
+ eq('Vim(call):E928: String required', exc_exec('call setloclist(0, [], 5)'))
+ eq('Vim(call):E928: String required', exc_exec('call setloclist(0, [], [])'))
+ eq('Vim(call):E928: String required', exc_exec('call setloclist(0, [], {})'))
end)
it('sets w:quickfix_title for the correct window', function()
diff --git a/test/functional/viml/function_spec.lua b/test/functional/viml/function_spec.lua
index f0a4406593..b8137038b1 100644
--- a/test/functional/viml/function_spec.lua
+++ b/test/functional/viml/function_spec.lua
@@ -1,38 +1,216 @@
local helpers = require('test.functional.helpers')(after_each)
-local clear = helpers.clear
local eq = helpers.eq
-local eval = helpers.eval
-local exc_exec = helpers.exc_exec
+local clear = helpers.clear
+local dedent = helpers.dedent
+local redir_exec = helpers.redir_exec
-describe('Up to MAX_FUNC_ARGS arguments are handled by', function()
- local max_func_args = 20 -- from eval.h
- local range = helpers.funcs.range
+before_each(clear)
- before_each(clear)
+local function check_func(fname, body, indent)
+ if type(body) == 'number' then
+ body = ('return %i'):format(body)
+ end
+ eq(dedent(([[
- it('printf()', function()
- local printf = helpers.funcs.printf
- local rep = helpers.funcs['repeat']
- local expected = '2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,'
- eq(expected, printf(rep('%d,', max_func_args-1), unpack(range(2, max_func_args))))
- local ret = exc_exec('call printf("", 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)')
- eq('Vim(call):E740: Too many arguments for function printf', ret)
- end)
+ function %s()%s
+ endfunction]]
+ ), 3):format(
+ fname,
+ body and ('\n1' .. (' '):rep(2 + (indent or 8)) .. body) or ''),
+ redir_exec('function ' .. fname))
+end
- it('rpcnotify()', function()
- local rpcnotify = helpers.funcs.rpcnotify
- local ret = rpcnotify(0, 'foo', unpack(range(3, max_func_args)))
- eq(1, ret)
- ret = exc_exec('call rpcnotify(0, "foo", 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)')
- eq('Vim(call):E740: Too many arguments for function rpcnotify', ret)
+describe(':endfunction', function()
+ it('accepts bang', function()
+ eq('', redir_exec([[
+ function F()
+ endfunction!
+ ]]))
+ check_func('F')
+ eq('', redir_exec([[
+ function! F()
+ return 1
+ endfunction!
+ ]]))
+ check_func('F', 1)
end)
-end)
-
-describe('api_info()', function()
- before_each(clear)
- it('has the right keys', function()
- local api_keys = eval("sort(keys(api_info()))")
- eq({'error_types', 'functions', 'types'}, api_keys)
+ it('accepts comments', function()
+ eq('', redir_exec([[
+ function F1()
+ endfunction " Comment
+ ]]))
+ check_func('F1')
+ eq('', redir_exec([[
+ function F2()
+ endfunction " }}}
+ ]]))
+ check_func('F2')
+ eq('', redir_exec([[
+ function F3()
+ endfunction " F3
+ ]]))
+ check_func('F3')
+ eq('', redir_exec([[
+ function F4()
+ endfunction! " F4
+ ]]))
+ check_func('F4')
+ eq('', redir_exec([[
+ function! F4()
+ return 2
+ endfunction! " F4
+ ]]))
+ check_func('F4', 2)
+ end)
+ it('accepts function name', function()
+ eq('', redir_exec([[
+ function F0()
+ endfunction F0
+ ]]))
+ check_func('F0')
+ eq('', redir_exec([[
+ function F1()
+ endfunction! F1
+ ]]))
+ check_func('F1')
+ eq('', redir_exec([[
+ function! F2()
+ endfunction! F2
+ ]]))
+ check_func('F2')
+ eq('', redir_exec([[
+ function! F2()
+ return 3
+ endfunction! F2
+ ]]))
+ check_func('F2', 3)
+ end)
+ it('accepts weird characters', function()
+ eq('', redir_exec([[
+ function F1()
+ endfunction: }}}
+ ]]))
+ check_func('F1')
+ -- From accurev
+ eq('', redir_exec([[
+ function F2()
+ endfunction :}}}
+ ]]))
+ check_func('F2')
+ -- From cream-vimabbrev
+ eq('', redir_exec([[
+ function F3()
+ endfunction 1}}}
+ ]]))
+ check_func('F3')
+ -- From pyunit
+ eq('', redir_exec([[
+ function F4()
+ endfunction # }}}
+ ]]))
+ check_func('F4')
+ -- From vim-lldb
+ eq('', redir_exec([[
+ function F5()
+ endfunction()
+ ]]))
+ check_func('F5')
+ -- From vim-mail
+ eq('', redir_exec([[
+ function F6()
+ endfunction;
+ ]]))
+ check_func('F6')
+ end)
+ it('accepts commented bar', function()
+ eq('', redir_exec([[
+ function F1()
+ endfunction " F1 | echo 42
+ ]]))
+ check_func('F1')
+ eq('', redir_exec([[
+ function! F1()
+ return 42
+ endfunction! " F1 | echo 42
+ ]]))
+ check_func('F1', 42)
+ end)
+ it('accepts uncommented bar', function()
+ eq('\n42', redir_exec([[
+ function F1()
+ endfunction | echo 42
+ ]]))
+ check_func('F1')
+ end)
+ it('allows running multiple commands', function()
+ eq('\n2', redir_exec([[
+ function F1()
+ echo 2
+ endfunction
+ call F1()
+ ]]))
+ check_func('F1', 'echo 2')
+ eq('\n2\n3\n4', redir_exec([[
+ function F2()
+ echo 2
+ endfunction F2
+ function F3()
+ echo 3
+ endfunction " F3
+ function! F4()
+ echo 4
+ endfunction!
+ call F2()
+ call F3()
+ call F4()
+ ]]))
+ check_func('F2', 'echo 2')
+ check_func('F3', 'echo 3')
+ check_func('F4', 'echo 4')
+ end)
+ it('allows running multiple commands with only one character in between',
+ function()
+ eq('\n3', redir_exec(dedent([[
+ function! F1()
+ echo 3
+ endfunction!
+ call F1()]])))
+ check_func('F1', 'echo 3', 2)
+ eq('\n4', redir_exec(dedent([[
+ function F5()
+ echo 4
+ endfunction
+ call F5()]])))
+ check_func('F5', 'echo 4', 2)
+ eq('\n5', redir_exec(dedent([[
+ function F6()
+ echo 5
+ endfunction " TEST
+ call F6()]])))
+ check_func('F6', 'echo 5', 2)
+ eq('\n6', redir_exec(dedent([[
+ function F7()
+ echo 6
+ endfunction F7
+ call F7()]])))
+ check_func('F7', 'echo 6', 2)
+ eq('\n2\n3\n4', redir_exec(dedent([[
+ function F2()
+ echo 2
+ endfunction F2
+ function F3()
+ echo 3
+ endfunction " F3
+ function! F4()
+ echo 4
+ endfunction!
+ call F2()
+ call F3()
+ call F4()]])))
+ check_func('F2', 'echo 2', 2)
+ check_func('F3', 'echo 3', 2)
+ check_func('F4', 'echo 4', 2)
end)
end)
+-- vim: foldmarker=▶,▲
diff --git a/test/functional/viml/lang_spec.lua b/test/functional/viml/lang_spec.lua
new file mode 100644
index 0000000000..6d603b8822
--- /dev/null
+++ b/test/functional/viml/lang_spec.lua
@@ -0,0 +1,30 @@
+local helpers = require('test.functional.helpers')(after_each)
+local clear, eval, eq = helpers.clear, helpers.eval, helpers.eq
+local exc_exec, source = helpers.exc_exec, helpers.source
+
+describe('viml', function()
+ before_each(clear)
+
+ it('parses `<SID>` with turkish locale', function()
+ if exc_exec('lang ctype tr_TR.UTF-8') ~= 0 then
+ pending("Locale tr_TR.UTF-8 not supported")
+ return
+ end
+ source([[
+ func! <sid>_dummy_function()
+ echo 1
+ endfunc
+ au VimEnter * call <sid>_dummy_function()
+ ]])
+ eq(nil, string.find(eval('v:errmsg'), '^E129'))
+ end)
+
+ it('str2float is not affected by locale', function()
+ if exc_exec('lang ctype sv_SE.UTF-8') ~= 0 then
+ pending("Locale sv_SE.UTF-8 not supported")
+ return
+ end
+ clear{env={LANG="", LC_NUMERIC="sv_SE.UTF-8"}}
+ eq(2.2, eval('str2float("2.2")'))
+ end)
+end)