2024-04-20 08:44:13 -07:00
|
|
|
local t = require('test.testutil')
|
|
|
|
local n = require('test.functional.testnvim')()
|
2016-03-16 13:43:51 -07:00
|
|
|
local Screen = require('test.functional.ui.screen')
|
2024-04-20 08:44:13 -07:00
|
|
|
|
|
|
|
local assert_alive = n.assert_alive
|
|
|
|
local clear, feed = n.clear, n.feed
|
|
|
|
local eval, eq, neq = n.eval, t.eq, t.neq
|
|
|
|
local feed_command, source, expect = n.feed_command, n.source, n.expect
|
|
|
|
local fn = n.fn
|
|
|
|
local command = n.command
|
|
|
|
local api = n.api
|
|
|
|
local poke_eventloop = n.poke_eventloop
|
2015-05-01 17:19:19 -07:00
|
|
|
|
2015-05-01 17:44:54 -07:00
|
|
|
describe('completion', function()
|
2016-04-13 14:54:08 -07:00
|
|
|
local screen
|
|
|
|
|
2015-05-01 17:19:19 -07:00
|
|
|
before_each(function()
|
|
|
|
clear()
|
2016-04-13 14:54:08 -07:00
|
|
|
screen = Screen.new(60, 8)
|
|
|
|
screen:attach()
|
2024-05-26 00:34:29 -07:00
|
|
|
screen:add_extra_attr_ids {
|
|
|
|
[100] = { foreground = Screen.colors.Gray0, background = Screen.colors.Yellow },
|
|
|
|
[101] = { background = Screen.colors.Gray0 },
|
|
|
|
}
|
2015-05-01 17:19:19 -07:00
|
|
|
end)
|
|
|
|
|
2015-05-01 17:44:54 -07:00
|
|
|
describe('v:completed_item', function()
|
2015-06-15 06:09:33 -07:00
|
|
|
it('is empty dict until completion', function()
|
|
|
|
eq({}, eval('v:completed_item'))
|
|
|
|
end)
|
|
|
|
it('is empty dict if the candidate is not inserted', function()
|
2016-04-13 14:54:08 -07:00
|
|
|
feed('ifoo<ESC>o<C-x><C-n>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
foo^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*5
|
|
|
|
{5:-- Keyword Local completion (^N^P) The only match} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<C-e>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*5
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<ESC>')
|
2015-06-15 06:09:33 -07:00
|
|
|
eq({}, eval('v:completed_item'))
|
|
|
|
end)
|
2015-05-01 17:19:19 -07:00
|
|
|
it('returns expected dict in normal completion', function()
|
2016-04-13 14:54:08 -07:00
|
|
|
feed('ifoo<ESC>o<C-x><C-n>')
|
2015-05-01 17:19:19 -07:00
|
|
|
eq('foo', eval('getline(2)'))
|
2018-02-18 15:56:59 -07:00
|
|
|
eq(
|
|
|
|
{ word = 'foo', abbr = '', menu = '', info = '', kind = '', user_data = '' },
|
2015-05-01 17:19:19 -07:00
|
|
|
eval('v:completed_item')
|
2024-01-02 18:09:18 -07:00
|
|
|
)
|
2015-05-01 17:19:19 -07:00
|
|
|
end)
|
|
|
|
it('is readonly', function()
|
2016-04-13 14:54:08 -07:00
|
|
|
screen:try_resize(80, 8)
|
2015-05-01 17:19:19 -07:00
|
|
|
feed('ifoo<ESC>o<C-x><C-n><ESC>')
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('let v:completed_item.word = "bar"')
|
2015-05-01 17:19:19 -07:00
|
|
|
neq(nil, string.find(eval('v:errmsg'), '^E46: '))
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('let v:errmsg = ""')
|
2015-05-01 17:19:19 -07:00
|
|
|
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('let v:completed_item.abbr = "bar"')
|
2015-05-01 17:19:19 -07:00
|
|
|
neq(nil, string.find(eval('v:errmsg'), '^E46: '))
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('let v:errmsg = ""')
|
2015-05-01 17:19:19 -07:00
|
|
|
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('let v:completed_item.menu = "bar"')
|
2015-05-01 17:19:19 -07:00
|
|
|
neq(nil, string.find(eval('v:errmsg'), '^E46: '))
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('let v:errmsg = ""')
|
2015-05-01 17:19:19 -07:00
|
|
|
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('let v:completed_item.info = "bar"')
|
2015-05-01 17:19:19 -07:00
|
|
|
neq(nil, string.find(eval('v:errmsg'), '^E46: '))
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('let v:errmsg = ""')
|
2015-05-01 17:19:19 -07:00
|
|
|
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('let v:completed_item.kind = "bar"')
|
2015-05-01 17:19:19 -07:00
|
|
|
neq(nil, string.find(eval('v:errmsg'), '^E46: '))
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('let v:errmsg = ""')
|
2018-02-18 15:56:59 -07:00
|
|
|
|
|
|
|
feed_command('let v:completed_item.user_data = "bar"')
|
|
|
|
neq(nil, string.find(eval('v:errmsg'), '^E46: '))
|
|
|
|
feed_command('let v:errmsg = ""')
|
2015-05-01 17:19:19 -07:00
|
|
|
end)
|
|
|
|
it('returns expected dict in omni completion', function()
|
|
|
|
source([[
|
|
|
|
function! TestOmni(findstart, base) abort
|
|
|
|
return a:findstart ? 0 : [{'word': 'foo', 'abbr': 'bar',
|
2016-04-13 14:54:08 -07:00
|
|
|
\ 'menu': 'baz', 'info': 'foobar', 'kind': 'foobaz'},
|
2018-02-18 15:56:59 -07:00
|
|
|
\ {'word': 'word', 'abbr': 'abbr', 'menu': 'menu',
|
|
|
|
\ 'info': 'info', 'kind': 'kind'}]
|
2015-05-01 17:19:19 -07:00
|
|
|
endfunction
|
|
|
|
setlocal omnifunc=TestOmni
|
|
|
|
]])
|
2016-04-13 14:54:08 -07:00
|
|
|
feed('i<C-x><C-o>')
|
2015-05-01 17:19:19 -07:00
|
|
|
eq('foo', eval('getline(1)'))
|
2016-04-13 14:54:08 -07:00
|
|
|
screen:expect([[
|
|
|
|
foo^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:bar foobaz baz }{1: }|
|
|
|
|
{4:abbr kind menu }{1: }|
|
|
|
|
{1:~ }|*4
|
|
|
|
{5:-- Omni completion (^O^N^P) }{6:match 1 of 2} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
2015-05-01 17:19:19 -07:00
|
|
|
eq({
|
|
|
|
word = 'foo',
|
|
|
|
abbr = 'bar',
|
|
|
|
menu = 'baz',
|
2018-02-18 15:56:59 -07:00
|
|
|
info = 'foobar',
|
|
|
|
kind = 'foobaz',
|
|
|
|
user_data = '',
|
2015-05-01 17:19:19 -07:00
|
|
|
}, eval('v:completed_item'))
|
|
|
|
end)
|
|
|
|
end)
|
2016-04-13 14:54:08 -07:00
|
|
|
|
2015-05-01 17:44:54 -07:00
|
|
|
describe('completeopt', function()
|
2015-06-05 06:41:22 -07:00
|
|
|
before_each(function()
|
|
|
|
source([[
|
|
|
|
function! TestComplete() abort
|
|
|
|
call complete(1, ['foo'])
|
|
|
|
return ''
|
|
|
|
endfunction
|
|
|
|
]])
|
|
|
|
end)
|
|
|
|
|
2015-05-01 17:44:54 -07:00
|
|
|
it('inserts the first candidate if default', function()
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('set completeopt+=menuone')
|
2016-04-13 14:54:08 -07:00
|
|
|
feed('ifoo<ESC>o')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*5
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<C-x>')
|
|
|
|
-- the ^X prompt, only test this once
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*5
|
|
|
|
{5:-- ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<C-n>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
foo^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:foo }{1: }|
|
|
|
|
{1:~ }|*4
|
|
|
|
{5:-- Keyword Local completion (^N^P) The only match} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('bar<ESC>')
|
2015-05-01 17:44:54 -07:00
|
|
|
eq('foobar', eval('getline(2)'))
|
2016-04-13 14:54:08 -07:00
|
|
|
feed('o<C-r>=TestComplete()<CR>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
foobar |
|
|
|
|
foo^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:foo }{1: }|
|
|
|
|
{1:~ }|*3
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
2015-06-05 06:41:22 -07:00
|
|
|
eq('foo', eval('getline(3)'))
|
2015-05-01 17:44:54 -07:00
|
|
|
end)
|
|
|
|
it('selects the first candidate if noinsert', function()
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('set completeopt+=menuone,noinsert')
|
2016-04-13 14:54:08 -07:00
|
|
|
feed('ifoo<ESC>o<C-x><C-n>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:foo }{1: }|
|
|
|
|
{1:~ }|*4
|
|
|
|
{5:-- Keyword Local completion (^N^P) The only match} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<C-y>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
foo^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*5
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<ESC>')
|
2015-05-01 17:44:54 -07:00
|
|
|
eq('foo', eval('getline(2)'))
|
2016-04-13 14:54:08 -07:00
|
|
|
feed('o<C-r>=TestComplete()<CR>')
|
|
|
|
screen:expect([[
|
2023-12-09 05:42:00 -07:00
|
|
|
foo |*2
|
2016-04-13 14:54:08 -07:00
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:foo }{1: }|
|
|
|
|
{1:~ }|*3
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<C-y><ESC>')
|
2015-06-05 06:41:22 -07:00
|
|
|
eq('foo', eval('getline(3)'))
|
2015-05-01 17:44:54 -07:00
|
|
|
end)
|
|
|
|
it('does not insert the first candidate if noselect', function()
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('set completeopt+=menuone,noselect')
|
2016-04-13 14:54:08 -07:00
|
|
|
feed('ifoo<ESC>o<C-x><C-n>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:foo }{1: }|
|
|
|
|
{1:~ }|*4
|
|
|
|
{5:-- Keyword Local completion (^N^P) }{19:Back at original} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('b')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
b^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*5
|
|
|
|
{5:-- Keyword Local completion (^N^P) }{19:Back at original} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('ar<ESC>')
|
2015-05-01 17:44:54 -07:00
|
|
|
eq('bar', eval('getline(2)'))
|
2016-04-13 14:54:08 -07:00
|
|
|
feed('o<C-r>=TestComplete()<CR>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
bar |
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:foo }{1: }|
|
|
|
|
{1:~ }|*3
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('bar<ESC>')
|
2015-06-05 06:41:22 -07:00
|
|
|
eq('bar', eval('getline(3)'))
|
2015-05-01 17:44:54 -07:00
|
|
|
end)
|
|
|
|
it('does not select/insert the first candidate if noselect and noinsert', function()
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('set completeopt+=menuone,noselect,noinsert')
|
2016-04-13 14:54:08 -07:00
|
|
|
feed('ifoo<ESC>o<C-x><C-n>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:foo }{1: }|
|
|
|
|
{1:~ }|*4
|
|
|
|
{5:-- Keyword Local completion (^N^P) }{19:Back at original} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<ESC>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*5
|
2016-04-13 14:54:08 -07:00
|
|
|
|
|
|
|
|
]])
|
2015-05-01 17:44:54 -07:00
|
|
|
eq('', eval('getline(2)'))
|
2016-04-13 14:54:08 -07:00
|
|
|
feed('o<C-r>=TestComplete()<CR>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
|
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:foo }{1: }|
|
|
|
|
{1:~ }|*3
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<ESC>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
|
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*4
|
2016-04-13 14:54:08 -07:00
|
|
|
|
|
|
|
|
]])
|
2015-06-05 06:41:22 -07:00
|
|
|
eq('', eval('getline(3)'))
|
2015-05-01 17:44:54 -07:00
|
|
|
end)
|
2016-03-31 04:52:56 -07:00
|
|
|
it('does not change modified state if noinsert', function()
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('set completeopt+=menuone,noinsert')
|
|
|
|
feed_command('setlocal nomodified')
|
2016-03-31 04:52:56 -07:00
|
|
|
feed('i<C-r>=TestComplete()<CR><ESC>')
|
|
|
|
eq(0, eval('&l:modified'))
|
|
|
|
end)
|
|
|
|
it('does not change modified state if noselect', function()
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('set completeopt+=menuone,noselect')
|
|
|
|
feed_command('setlocal nomodified')
|
2016-03-31 04:52:56 -07:00
|
|
|
feed('i<C-r>=TestComplete()<CR><ESC>')
|
|
|
|
eq(0, eval('&l:modified'))
|
|
|
|
end)
|
2015-05-01 17:44:54 -07:00
|
|
|
end)
|
2016-02-13 13:20:13 -07:00
|
|
|
|
2016-10-17 14:16:56 -07:00
|
|
|
describe('completeopt+=noinsert does not add blank undo items', function()
|
|
|
|
before_each(function()
|
|
|
|
source([[
|
|
|
|
function! TestComplete() abort
|
|
|
|
call complete(1, ['foo', 'bar'])
|
|
|
|
return ''
|
|
|
|
endfunction
|
|
|
|
]])
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('set completeopt+=noselect,noinsert')
|
|
|
|
feed_command('inoremap <right> <c-r>=TestComplete()<cr>')
|
2016-10-17 14:16:56 -07:00
|
|
|
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)
|
|
|
|
|
2016-02-13 13:20:13 -07:00
|
|
|
describe('refresh:always', function()
|
|
|
|
before_each(function()
|
2016-01-29 06:56:20 -07:00
|
|
|
source([[
|
2016-02-13 13:20:13 -07:00
|
|
|
function! TestCompletion(findstart, base) abort
|
|
|
|
if a:findstart
|
|
|
|
let line = getline('.')
|
|
|
|
let start = col('.') - 1
|
|
|
|
while start > 0 && line[start - 1] =~ '\a'
|
|
|
|
let start -= 1
|
|
|
|
endwhile
|
|
|
|
return start
|
|
|
|
else
|
|
|
|
let ret = []
|
|
|
|
for m in split("January February March April May June July August September October November December")
|
|
|
|
if m =~ a:base " match by regex
|
|
|
|
call add(ret, m)
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
return {'words':ret, 'refresh':'always'}
|
|
|
|
endif
|
|
|
|
endfunction
|
2016-01-29 06:56:20 -07:00
|
|
|
|
2016-02-13 13:20:13 -07:00
|
|
|
set completeopt=menuone,noselect
|
|
|
|
set completefunc=TestCompletion
|
2016-01-29 06:56:20 -07:00
|
|
|
]])
|
|
|
|
end)
|
|
|
|
|
2016-02-13 13:20:13 -07:00
|
|
|
it('completes on each input char', function()
|
2016-04-13 14:54:08 -07:00
|
|
|
feed('i<C-x><C-u>')
|
|
|
|
screen:expect([[
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:January }{101: }{1: }|
|
|
|
|
{4:February }{101: }{1: }|
|
|
|
|
{4:March }{101: }{1: }|
|
|
|
|
{4:April }{12: }{1: }|
|
|
|
|
{4:May }{12: }{1: }|
|
|
|
|
{4:June }{12: }{1: }|
|
|
|
|
{5:-- User defined completion (^U^N^P) }{19:Back at original} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('u')
|
|
|
|
screen:expect([[
|
|
|
|
u^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:January }{1: }|
|
|
|
|
{4:February }{1: }|
|
|
|
|
{4:June }{1: }|
|
|
|
|
{4:July }{1: }|
|
|
|
|
{4:August }{1: }|
|
|
|
|
{1:~ }|
|
|
|
|
{5:-- User defined completion (^U^N^P) }{19:Back at original} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('g')
|
|
|
|
screen:expect([[
|
|
|
|
ug^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:August }{1: }|
|
|
|
|
{1:~ }|*5
|
|
|
|
{5:-- User defined completion (^U^N^P) }{19:Back at original} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<Down>')
|
|
|
|
screen:expect([[
|
|
|
|
ug^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:August }{1: }|
|
|
|
|
{1:~ }|*5
|
|
|
|
{5:-- User defined completion (^U^N^P) The only match} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<C-y>')
|
|
|
|
screen:expect([[
|
|
|
|
August^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*6
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
2016-02-13 13:20:13 -07:00
|
|
|
expect('August')
|
2016-01-29 06:56:20 -07:00
|
|
|
end)
|
2018-05-02 15:22:25 -07:00
|
|
|
|
2016-02-13 13:20:13 -07:00
|
|
|
it('repeats correctly after backspace #2674', function()
|
2016-04-13 14:54:08 -07:00
|
|
|
feed('o<C-x><C-u>Ja')
|
|
|
|
screen:expect([[
|
|
|
|
|
|
|
|
|
Ja^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:January }{1: }|
|
|
|
|
{1:~ }|*4
|
|
|
|
{5:-- User defined completion (^U^N^P) }{19:Back at original} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<BS>')
|
|
|
|
screen:expect([[
|
|
|
|
|
|
|
|
|
J^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:January }{1: }|
|
|
|
|
{4:June }{1: }|
|
|
|
|
{4:July }{1: }|
|
|
|
|
{1:~ }|*2
|
|
|
|
{5:-- User defined completion (^U^N^P) }{19:Back at original} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<C-n>')
|
|
|
|
screen:expect([[
|
|
|
|
|
|
|
|
|
January^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:January }{1: }|
|
|
|
|
{4:June }{1: }|
|
|
|
|
{4:July }{1: }|
|
|
|
|
{1:~ }|*2
|
|
|
|
{5:-- User defined completion (^U^N^P) }{6:match 1 of 3} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<C-n>')
|
|
|
|
screen:expect([[
|
|
|
|
|
|
|
|
|
June^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:January }{1: }|
|
|
|
|
{12:June }{1: }|
|
|
|
|
{4:July }{1: }|
|
|
|
|
{1:~ }|*2
|
|
|
|
{5:-- User defined completion (^U^N^P) }{6:match 2 of 3} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<Esc>')
|
|
|
|
screen:expect([[
|
|
|
|
|
|
|
|
|
Jun^e |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*5
|
2016-04-13 14:54:08 -07:00
|
|
|
|
|
|
|
|
]])
|
2016-02-13 13:20:13 -07:00
|
|
|
feed('.')
|
2016-04-13 14:54:08 -07:00
|
|
|
screen:expect([[
|
|
|
|
|
|
|
|
|
June |
|
|
|
|
Jun^e |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*4
|
2016-04-13 14:54:08 -07:00
|
|
|
|
|
|
|
|
]])
|
2016-02-13 13:20:13 -07:00
|
|
|
expect([[
|
2016-11-16 16:33:45 -07:00
|
|
|
|
2016-02-13 13:20:13 -07:00
|
|
|
June
|
|
|
|
June]])
|
2016-01-29 06:56:20 -07:00
|
|
|
end)
|
|
|
|
end)
|
2016-03-04 13:06:48 -07:00
|
|
|
|
2016-04-13 14:54:08 -07:00
|
|
|
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
|
|
|
|
]])
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('set completeopt=menuone,noselect')
|
2016-04-13 14:54:08 -07:00
|
|
|
end)
|
|
|
|
|
|
|
|
it('works', function()
|
|
|
|
feed('i<C-r>=TestComplete()<CR>')
|
|
|
|
screen:expect([[
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:0 }{101: }{1: }|
|
|
|
|
{4:1 }{12: }{1: }|
|
|
|
|
{4:2 }{12: }{1: }|
|
|
|
|
{4:3 }{12: }{1: }|
|
|
|
|
{4:4 }{12: }{1: }|
|
|
|
|
{4:5 }{12: }{1: }|
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('7')
|
|
|
|
screen:expect([[
|
|
|
|
7^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:7 }{101: }{1: }|
|
|
|
|
{4:70 }{101: }{1: }|
|
|
|
|
{4:71 }{101: }{1: }|
|
|
|
|
{4:72 }{12: }{1: }|
|
|
|
|
{4:73 }{12: }{1: }|
|
|
|
|
{4:74 }{12: }{1: }|
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<c-n>')
|
|
|
|
screen:expect([[
|
|
|
|
7^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:7 }{101: }{1: }|
|
|
|
|
{4:70 }{101: }{1: }|
|
|
|
|
{4:71 }{101: }{1: }|
|
|
|
|
{4:72 }{12: }{1: }|
|
|
|
|
{4:73 }{12: }{1: }|
|
|
|
|
{4:74 }{12: }{1: }|
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<c-n>')
|
|
|
|
screen:expect([[
|
|
|
|
70^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:7 }{101: }{1: }|
|
|
|
|
{12:70 }{101: }{1: }|
|
|
|
|
{4:71 }{101: }{1: }|
|
|
|
|
{4:72 }{12: }{1: }|
|
|
|
|
{4:73 }{12: }{1: }|
|
|
|
|
{4:74 }{12: }{1: }|
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
end)
|
|
|
|
|
|
|
|
it('can be navigated with <PageDown>, <PageUp>', function()
|
|
|
|
feed('i<C-r>=TestComplete()<CR>')
|
|
|
|
screen:expect([[
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:0 }{101: }{1: }|
|
|
|
|
{4:1 }{12: }{1: }|
|
|
|
|
{4:2 }{12: }{1: }|
|
|
|
|
{4:3 }{12: }{1: }|
|
|
|
|
{4:4 }{12: }{1: }|
|
|
|
|
{4:5 }{12: }{1: }|
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<PageDown>')
|
|
|
|
screen:expect([[
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:0 }{101: }{1: }|
|
|
|
|
{4:1 }{12: }{1: }|
|
|
|
|
{4:2 }{12: }{1: }|
|
|
|
|
{12:3 }{1: }|
|
|
|
|
{4:4 }{12: }{1: }|
|
|
|
|
{4:5 }{12: }{1: }|
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<PageDown>')
|
|
|
|
screen:expect([[
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:5 }{101: }{1: }|
|
|
|
|
{4:6 }{12: }{1: }|
|
|
|
|
{12:7 }{1: }|
|
|
|
|
{4:8 }{12: }{1: }|
|
|
|
|
{4:9 }{12: }{1: }|
|
|
|
|
{4:10 }{12: }{1: }|
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<Down>')
|
|
|
|
screen:expect([[
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:5 }{101: }{1: }|
|
|
|
|
{4:6 }{12: }{1: }|
|
|
|
|
{4:7 }{12: }{1: }|
|
|
|
|
{12:8 }{1: }|
|
|
|
|
{4:9 }{12: }{1: }|
|
|
|
|
{4:10 }{12: }{1: }|
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<PageUp>')
|
|
|
|
screen:expect([[
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:2 }{101: }{1: }|
|
|
|
|
{4:3 }{12: }{1: }|
|
|
|
|
{12:4 }{1: }|
|
|
|
|
{4:5 }{12: }{1: }|
|
|
|
|
{4:6 }{12: }{1: }|
|
|
|
|
{4:7 }{12: }{1: }|
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<PageUp>') -- stop on first item
|
|
|
|
screen:expect([[
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:0 }{101: }{1: }|
|
|
|
|
{4:1 }{12: }{1: }|
|
|
|
|
{4:2 }{12: }{1: }|
|
|
|
|
{4:3 }{12: }{1: }|
|
|
|
|
{4:4 }{12: }{1: }|
|
|
|
|
{4:5 }{12: }{1: }|
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<PageUp>') -- when on first item, unselect
|
|
|
|
screen:expect([[
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:0 }{101: }{1: }|
|
|
|
|
{4:1 }{12: }{1: }|
|
|
|
|
{4:2 }{12: }{1: }|
|
|
|
|
{4:3 }{12: }{1: }|
|
|
|
|
{4:4 }{12: }{1: }|
|
|
|
|
{4:5 }{12: }{1: }|
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<PageUp>') -- when unselected, select last item
|
|
|
|
screen:expect([[
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:95 }{12: }{1: }|
|
|
|
|
{4:96 }{12: }{1: }|
|
|
|
|
{4:97 }{12: }{1: }|
|
|
|
|
{4:98 }{12: }{1: }|
|
|
|
|
{4:99 }{12: }{1: }|
|
|
|
|
{12:100 }{101: }{1: }|
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<PageUp>')
|
|
|
|
screen:expect([[
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:94 }{12: }{1: }|
|
|
|
|
{4:95 }{12: }{1: }|
|
|
|
|
{12:96 }{1: }|
|
|
|
|
{4:97 }{12: }{1: }|
|
|
|
|
{4:98 }{12: }{1: }|
|
|
|
|
{4:99 }{101: }{1: }|
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
feed('<cr>')
|
|
|
|
screen:expect([[
|
|
|
|
96^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*6
|
|
|
|
{5:-- INSERT --} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
|
|
|
end)
|
|
|
|
end)
|
|
|
|
|
2018-05-02 15:22:25 -07:00
|
|
|
it('does not indent until an item is selected #8345', function()
|
|
|
|
-- Indents on "ind", unindents on "unind".
|
|
|
|
source([[
|
|
|
|
function! TestIndent()
|
|
|
|
let line = getline(v:lnum)
|
|
|
|
if (line =~ '^\s*ind')
|
|
|
|
return indent(v:lnum-1) + shiftwidth()
|
|
|
|
elseif (line =~ '^\s*unind')
|
|
|
|
return indent(v:lnum-1) - shiftwidth()
|
|
|
|
else
|
|
|
|
return indent(v:lnum-1)
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
set indentexpr=TestIndent()
|
|
|
|
set indentkeys=o,O,!^F,=ind,=unind
|
|
|
|
set completeopt+=menuone
|
|
|
|
]])
|
|
|
|
|
|
|
|
-- Give some words to complete.
|
|
|
|
feed('iinc uninc indent unindent<CR>')
|
|
|
|
|
|
|
|
-- Does not indent when "ind" is typed.
|
|
|
|
feed('in<C-X><C-N>')
|
|
|
|
-- Completion list is generated incorrectly if we send everything at once
|
2020-10-19 11:17:51 -07:00
|
|
|
-- via nvim_input(). So poke_eventloop() before sending <BS>. #8480
|
|
|
|
poke_eventloop()
|
2018-05-02 15:22:25 -07:00
|
|
|
feed('<BS>d')
|
|
|
|
|
|
|
|
screen:expect([[
|
|
|
|
inc uninc indent unindent |
|
|
|
|
ind^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:indent }{1: }|
|
|
|
|
{1:~ }|*4
|
|
|
|
{5:-- Keyword Local completion (^N^P) }{6:match 1 of 2} |
|
2018-05-02 15:22:25 -07:00
|
|
|
]])
|
|
|
|
|
|
|
|
-- Indents when the item is selected
|
|
|
|
feed('<C-Y>')
|
|
|
|
screen:expect([[
|
|
|
|
inc uninc indent unindent |
|
|
|
|
indent^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*5
|
|
|
|
{5:-- INSERT --} |
|
2018-05-02 15:22:25 -07:00
|
|
|
]])
|
|
|
|
-- Indents when completion is exited using ESC.
|
|
|
|
feed('<CR>in<C-N><BS>d<Esc>')
|
|
|
|
screen:expect([[
|
|
|
|
inc uninc indent unindent |
|
|
|
|
indent |
|
|
|
|
in^d |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*4
|
2018-05-02 15:22:25 -07:00
|
|
|
|
|
|
|
|
]])
|
|
|
|
-- Works for unindenting too.
|
|
|
|
feed('ounin<C-X><C-N>')
|
2024-01-12 04:41:09 -07:00
|
|
|
poke_eventloop()
|
2018-05-02 15:22:25 -07:00
|
|
|
feed('<BS>d')
|
|
|
|
screen:expect([[
|
|
|
|
inc uninc indent unindent |
|
|
|
|
indent |
|
|
|
|
ind |
|
|
|
|
unind^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }{12: unindent }{1: }|
|
|
|
|
{1:~ }|*2
|
|
|
|
{5:-- Keyword Local completion (^N^P) }{6:match 1 of 2} |
|
2018-05-02 15:22:25 -07:00
|
|
|
]])
|
|
|
|
-- Works when going back and forth.
|
|
|
|
feed('<BS>c')
|
|
|
|
screen:expect([[
|
|
|
|
inc uninc indent unindent |
|
|
|
|
indent |
|
|
|
|
ind |
|
|
|
|
uninc^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }{12: uninc }{1: }|
|
|
|
|
{1:~ }|*2
|
|
|
|
{5:-- Keyword Local completion (^N^P) }{6:match 1 of 2} |
|
2018-05-02 15:22:25 -07:00
|
|
|
]])
|
|
|
|
feed('<BS>d')
|
|
|
|
screen:expect([[
|
|
|
|
inc uninc indent unindent |
|
|
|
|
indent |
|
|
|
|
ind |
|
|
|
|
unind^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }{12: unindent }{1: }|
|
|
|
|
{1:~ }|*2
|
|
|
|
{5:-- Keyword Local completion (^N^P) }{6:match 1 of 2} |
|
2018-05-02 15:22:25 -07:00
|
|
|
]])
|
|
|
|
feed('<C-N><C-N><C-Y><Esc>')
|
|
|
|
screen:expect([[
|
|
|
|
inc uninc indent unindent |
|
|
|
|
indent |
|
|
|
|
ind |
|
|
|
|
uninden^t |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*3
|
2018-05-02 15:22:25 -07:00
|
|
|
|
|
|
|
|
]])
|
|
|
|
end)
|
2016-04-13 14:54:08 -07:00
|
|
|
|
2016-03-04 13:06:48 -07:00
|
|
|
it('disables folding during completion', function()
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('set foldmethod=indent')
|
2016-04-13 14:54:08 -07:00
|
|
|
feed('i<Tab>foo<CR><Tab>bar<Esc>gg')
|
|
|
|
screen:expect([[
|
|
|
|
^foo |
|
|
|
|
bar |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*5
|
2016-04-13 14:54:08 -07:00
|
|
|
|
|
|
|
|
]])
|
|
|
|
feed('A<C-x><C-l>')
|
|
|
|
screen:expect([[
|
|
|
|
foo^ |
|
|
|
|
bar |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*5
|
|
|
|
{5:-- Whole line completion (^L^N^P) }{9:Pattern not found} |
|
2016-04-13 14:54:08 -07:00
|
|
|
]])
|
2016-03-16 13:43:51 -07:00
|
|
|
eq(-1, eval('foldclosed(1)'))
|
2016-03-04 13:06:48 -07:00
|
|
|
end)
|
2016-03-16 13:43:51 -07:00
|
|
|
|
|
|
|
it('popupmenu is not interrupted by events', function()
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('set complete=.')
|
2016-04-13 14:54:08 -07:00
|
|
|
|
2016-03-16 13:43:51 -07:00
|
|
|
feed('ifoobar fooegg<cr>f<c-p>')
|
|
|
|
screen:expect([[
|
2016-04-13 14:54:08 -07:00
|
|
|
foobar fooegg |
|
|
|
|
fooegg^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:foobar }{1: }|
|
|
|
|
{12:fooegg }{1: }|
|
|
|
|
{1:~ }|*3
|
|
|
|
{5:-- Keyword completion (^N^P) }{6:match 1 of 2} |
|
2016-03-16 13:43:51 -07:00
|
|
|
]])
|
|
|
|
|
2021-09-01 09:42:53 -07:00
|
|
|
assert_alive()
|
2016-03-16 13:43:51 -07:00
|
|
|
-- popupmenu still visible
|
2017-06-26 05:49:15 -07:00
|
|
|
screen:expect {
|
|
|
|
grid = [[
|
2016-04-13 14:54:08 -07:00
|
|
|
foobar fooegg |
|
|
|
|
fooegg^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:foobar }{1: }|
|
|
|
|
{12:fooegg }{1: }|
|
|
|
|
{1:~ }|*3
|
|
|
|
{5:-- Keyword completion (^N^P) }{6:match 1 of 2} |
|
2017-06-26 05:49:15 -07:00
|
|
|
]],
|
|
|
|
unchanged = true,
|
|
|
|
}
|
2016-03-16 13:43:51 -07:00
|
|
|
|
|
|
|
feed('<c-p>')
|
|
|
|
-- Didn't restart completion: old matches still used
|
|
|
|
screen:expect([[
|
2016-04-13 14:54:08 -07:00
|
|
|
foobar fooegg |
|
|
|
|
foobar^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:foobar }{1: }|
|
|
|
|
{4:fooegg }{1: }|
|
|
|
|
{1:~ }|*3
|
|
|
|
{5:-- Keyword completion (^N^P) }{6:match 2 of 2} |
|
2016-03-16 13:43:51 -07:00
|
|
|
]])
|
|
|
|
end)
|
2016-11-16 16:33:45 -07:00
|
|
|
|
2020-11-24 21:24:52 -07:00
|
|
|
describe('lua completion', function()
|
|
|
|
it('expands when there is only one match', function()
|
|
|
|
feed(':lua CURRENT_TESTING_VAR = 1<CR>')
|
|
|
|
feed(':lua CURRENT_TESTING_<TAB>')
|
|
|
|
screen:expect {
|
|
|
|
grid = [[
|
|
|
|
|
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*6
|
2020-11-24 21:24:52 -07:00
|
|
|
:lua CURRENT_TESTING_VAR^ |
|
|
|
|
]],
|
|
|
|
}
|
|
|
|
end)
|
2016-03-16 13:43:51 -07:00
|
|
|
|
2020-11-24 21:24:52 -07:00
|
|
|
it('expands when there is only one match', function()
|
|
|
|
feed(':lua CURRENT_TESTING_FOO = 1<CR>')
|
|
|
|
feed(':lua CURRENT_TESTING_BAR = 1<CR>')
|
|
|
|
feed(':lua CURRENT_TESTING_<TAB>')
|
|
|
|
screen:expect {
|
|
|
|
grid = [[
|
|
|
|
|
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*5
|
|
|
|
{100:CURRENT_TESTING_BAR}{3: CURRENT_TESTING_FOO }|
|
2020-11-24 21:24:52 -07:00
|
|
|
:lua CURRENT_TESTING_BAR^ |
|
|
|
|
]],
|
|
|
|
unchanged = true,
|
|
|
|
}
|
|
|
|
end)
|
|
|
|
|
2024-06-17 18:47:10 -07:00
|
|
|
it('prefix is not included in completion for cmdline mode', function()
|
|
|
|
feed(':lua math.a<Tab>')
|
|
|
|
screen:expect([[
|
|
|
|
|
|
2024-06-17 21:02:31 -07:00
|
|
|
{1:~ }|*5
|
2024-06-17 18:47:10 -07:00
|
|
|
{100:abs}{3: acos asin atan atan2 }|
|
|
|
|
:lua math.abs^ |
|
|
|
|
]])
|
|
|
|
feed('<Tab>')
|
|
|
|
screen:expect([[
|
|
|
|
|
|
2024-06-17 21:02:31 -07:00
|
|
|
{1:~ }|*5
|
2024-06-17 18:47:10 -07:00
|
|
|
{3:abs }{100:acos}{3: asin atan atan2 }|
|
|
|
|
:lua math.acos^ |
|
|
|
|
]])
|
|
|
|
end)
|
|
|
|
|
|
|
|
it('prefix is not included in completion for i_CTRL-X_CTRL-V #19623', function()
|
|
|
|
feed('ilua math.a<C-X><C-V>')
|
|
|
|
screen:expect([[
|
|
|
|
lua math.abs^ |
|
|
|
|
{1:~ }{12: abs }{1: }|
|
|
|
|
{1:~ }{4: acos }{1: }|
|
|
|
|
{1:~ }{4: asin }{1: }|
|
|
|
|
{1:~ }{4: atan }{1: }|
|
|
|
|
{1:~ }{4: atan2 }{1: }|
|
|
|
|
{1:~ }|
|
|
|
|
{5:-- Command-line completion (^V^N^P) }{6:match 1 of 5} |
|
|
|
|
]])
|
|
|
|
feed('<C-V>')
|
|
|
|
screen:expect([[
|
|
|
|
lua math.acos^ |
|
|
|
|
{1:~ }{4: abs }{1: }|
|
|
|
|
{1:~ }{12: acos }{1: }|
|
|
|
|
{1:~ }{4: asin }{1: }|
|
|
|
|
{1:~ }{4: atan }{1: }|
|
|
|
|
{1:~ }{4: atan2 }{1: }|
|
|
|
|
{1:~ }|
|
|
|
|
{5:-- Command-line completion (^V^N^P) }{6:match 2 of 5} |
|
|
|
|
]])
|
|
|
|
end)
|
|
|
|
|
2020-11-24 21:24:52 -07:00
|
|
|
it('provides completion from `getcompletion()`', function()
|
2024-01-12 10:59:57 -07:00
|
|
|
eq({ 'vim' }, fn.getcompletion('vi', 'lua'))
|
|
|
|
eq({ 'api' }, fn.getcompletion('vim.ap', 'lua'))
|
|
|
|
eq({ 'tbl_filter' }, fn.getcompletion('vim.tbl_fil', 'lua'))
|
|
|
|
eq({ 'vim' }, fn.getcompletion('print(vi', 'lua'))
|
2024-06-17 18:47:10 -07:00
|
|
|
eq({ 'abs', 'acos', 'asin', 'atan', 'atan2' }, fn.getcompletion('math.a', 'lua'))
|
|
|
|
eq({ 'abs', 'acos', 'asin', 'atan', 'atan2' }, fn.getcompletion('lua math.a', 'cmdline'))
|
2023-01-17 00:42:18 -07:00
|
|
|
-- fuzzy completion is not supported, so the result should be the same
|
|
|
|
command('set wildoptions+=fuzzy')
|
2024-01-12 10:59:57 -07:00
|
|
|
eq({ 'vim' }, fn.getcompletion('vi', 'lua'))
|
2020-11-24 21:24:52 -07:00
|
|
|
end)
|
|
|
|
end)
|
|
|
|
|
2023-10-01 04:07:16 -07:00
|
|
|
it('cmdline completion supports various string options', function()
|
2024-01-12 10:59:57 -07:00
|
|
|
eq('auto', fn.getcompletion('set foldcolumn=', 'cmdline')[2])
|
|
|
|
eq({ 'nosplit', 'split' }, fn.getcompletion('set inccommand=', 'cmdline'))
|
|
|
|
eq({ 'ver:3,hor:6', 'hor:', 'ver:' }, fn.getcompletion('set mousescroll=', 'cmdline'))
|
|
|
|
eq('BS', fn.getcompletion('set termpastefilter=', 'cmdline')[2])
|
|
|
|
eq('SpecialKey', fn.getcompletion('set winhighlight=', 'cmdline')[1])
|
|
|
|
eq('SpecialKey', fn.getcompletion('set winhighlight=NonText:', 'cmdline')[1])
|
2023-10-01 04:07:16 -07:00
|
|
|
end)
|
|
|
|
|
2020-11-24 21:24:52 -07:00
|
|
|
describe('from the commandline window', function()
|
2016-04-25 13:17:54 -07:00
|
|
|
it('is cleared after CTRL-C', function()
|
|
|
|
feed('q:')
|
|
|
|
feed('ifoo faa fee f')
|
|
|
|
screen:expect([[
|
|
|
|
|
|
2024-05-26 00:34:29 -07:00
|
|
|
{2:[No Name] }|
|
|
|
|
{1::}foo faa fee f^ |
|
|
|
|
{1:~ }|*3
|
|
|
|
{3:[Command Line] }|
|
|
|
|
{5:-- INSERT --} |
|
2016-08-09 07:18:55 -07:00
|
|
|
]])
|
2016-04-25 13:17:54 -07:00
|
|
|
feed('<c-x><c-n>')
|
|
|
|
screen:expect([[
|
|
|
|
|
|
2024-05-26 00:34:29 -07:00
|
|
|
{2:[No Name] }|
|
|
|
|
{1::}foo faa fee foo^ |
|
|
|
|
{1:~ }{12: foo }{1: }|
|
|
|
|
{1:~ }{4: faa }{1: }|
|
|
|
|
{1:~ }{4: fee }{1: }|
|
|
|
|
{3:[Command Line] }|
|
|
|
|
{5:-- Keyword Local completion (^N^P) }{6:match 1 of 3} |
|
2016-08-09 07:18:55 -07:00
|
|
|
]])
|
2016-04-25 13:17:54 -07:00
|
|
|
feed('<c-c>')
|
|
|
|
screen:expect([[
|
|
|
|
|
|
2024-05-26 00:34:29 -07:00
|
|
|
{2:[No Name] }|
|
|
|
|
{1::}foo faa fee foo |
|
|
|
|
{1:~ }|*3
|
|
|
|
{3:[Command Line] }|
|
2016-04-25 13:17:54 -07:00
|
|
|
:foo faa fee foo^ |
|
2016-08-09 07:18:55 -07:00
|
|
|
]])
|
2016-04-25 13:17:54 -07:00
|
|
|
end)
|
|
|
|
end)
|
2016-06-08 02:26:06 -07:00
|
|
|
|
2016-08-20 12:24:34 -07:00
|
|
|
describe('with numeric items', function()
|
|
|
|
before_each(function()
|
|
|
|
source([[
|
|
|
|
function! TestComplete() abort
|
|
|
|
call complete(1, g:_complist)
|
|
|
|
return ''
|
|
|
|
endfunction
|
|
|
|
]])
|
2024-01-12 10:59:57 -07:00
|
|
|
api.nvim_set_option_value('completeopt', 'menuone,noselect', {})
|
|
|
|
api.nvim_set_var('_complist', {
|
2024-01-02 18:09:18 -07:00
|
|
|
{
|
2016-08-20 12:24:34 -07:00
|
|
|
word = 0,
|
|
|
|
abbr = 1,
|
|
|
|
menu = 2,
|
|
|
|
kind = 3,
|
|
|
|
info = 4,
|
|
|
|
icase = 5,
|
|
|
|
dup = 6,
|
|
|
|
empty = 7,
|
2024-01-02 18:09:18 -07:00
|
|
|
},
|
2016-08-20 12:24:34 -07:00
|
|
|
})
|
|
|
|
end)
|
|
|
|
|
|
|
|
it('shows correct variant as word', function()
|
|
|
|
feed('i<C-r>=TestComplete()<CR>')
|
|
|
|
screen:expect([[
|
|
|
|
^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:1 3 2 }{1: }|
|
|
|
|
{1:~ }|*5
|
|
|
|
{5:-- INSERT --} |
|
2016-08-20 12:24:34 -07:00
|
|
|
]])
|
|
|
|
end)
|
|
|
|
end)
|
2017-04-06 12:35:03 -07:00
|
|
|
|
|
|
|
it("'ignorecase' 'infercase' CTRL-X CTRL-N #6451", function()
|
2017-04-08 14:12:26 -07:00
|
|
|
feed_command('set ignorecase infercase')
|
2023-12-27 05:43:48 -07:00
|
|
|
feed_command('edit runtime/doc/backers.txt')
|
2017-04-06 12:35:03 -07:00
|
|
|
feed('oX<C-X><C-N>')
|
2023-12-27 05:43:48 -07:00
|
|
|
screen:expect {
|
|
|
|
grid = [[
|
|
|
|
*backers.txt* Nvim |
|
2017-04-06 12:35:03 -07:00
|
|
|
Xnull^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:Xnull }{101: } |
|
|
|
|
{4:Xoxomoon }{101: } |
|
|
|
|
{4:Xu }{101: } NVIM REFERENCE MANUAL |
|
|
|
|
{4:Xpayn }{12: } |
|
|
|
|
{4:Xinity }{12: } |
|
|
|
|
{5:-- Keyword Local completion (^N^P) }{6:match 1 of 7} |
|
2023-12-27 05:43:48 -07:00
|
|
|
]],
|
|
|
|
}
|
2017-04-06 12:35:03 -07:00
|
|
|
end)
|
2018-02-11 06:37:14 -07:00
|
|
|
|
2019-03-30 17:15:41 -07:00
|
|
|
it('CompleteChanged autocommand', function()
|
2024-01-12 10:59:57 -07:00
|
|
|
api.nvim_buf_set_lines(0, 0, 1, false, { 'foo', 'bar', 'foobar', '' })
|
2019-02-15 13:54:10 -07:00
|
|
|
source([[
|
|
|
|
set complete=. completeopt=noinsert,noselect,menuone
|
|
|
|
function! OnPumChange()
|
|
|
|
let g:event = copy(v:event)
|
|
|
|
let g:item = get(v:event, 'completed_item', {})
|
|
|
|
let g:word = get(g:item, 'word', v:null)
|
|
|
|
endfunction
|
2019-03-30 17:15:41 -07:00
|
|
|
autocmd! CompleteChanged * :call OnPumChange()
|
2019-02-15 13:54:10 -07:00
|
|
|
call cursor(4, 1)
|
|
|
|
]])
|
|
|
|
|
2022-10-14 08:08:00 -07:00
|
|
|
-- v:event.size should be set with ext_popupmenu #20646
|
|
|
|
screen:set_option('ext_popupmenu', true)
|
|
|
|
feed('Sf<C-N>')
|
|
|
|
screen:expect({
|
|
|
|
grid = [[
|
|
|
|
foo |
|
|
|
|
bar |
|
|
|
|
foobar |
|
|
|
|
f^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*3
|
|
|
|
{5:-- Keyword completion (^N^P) }{19:Back at original} |
|
2022-10-14 08:08:00 -07:00
|
|
|
]],
|
|
|
|
popupmenu = {
|
|
|
|
anchor = { 1, 3, 0 },
|
|
|
|
items = { { 'foo', '', '', '' }, { 'foobar', '', '', '' } },
|
|
|
|
pos = -1,
|
2024-01-02 18:09:18 -07:00
|
|
|
},
|
2022-10-14 08:08:00 -07:00
|
|
|
})
|
|
|
|
eq(
|
|
|
|
{ completed_item = {}, width = 0, height = 2, size = 2, col = 0, row = 4, scrollbar = false },
|
|
|
|
eval('g:event')
|
2024-01-02 18:09:18 -07:00
|
|
|
)
|
2022-10-14 08:08:00 -07:00
|
|
|
feed('oob')
|
|
|
|
screen:expect({
|
|
|
|
grid = [[
|
|
|
|
foo |
|
|
|
|
bar |
|
|
|
|
foobar |
|
|
|
|
foob^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*3
|
|
|
|
{5:-- Keyword completion (^N^P) }{19:Back at original} |
|
2022-10-14 08:08:00 -07:00
|
|
|
]],
|
|
|
|
popupmenu = {
|
|
|
|
anchor = { 1, 3, 0 },
|
|
|
|
items = { { 'foobar', '', '', '' } },
|
|
|
|
pos = -1,
|
2024-01-02 18:09:18 -07:00
|
|
|
},
|
2022-10-14 08:08:00 -07:00
|
|
|
})
|
|
|
|
eq(
|
|
|
|
{ completed_item = {}, width = 0, height = 1, size = 1, col = 0, row = 4, scrollbar = false },
|
|
|
|
eval('g:event')
|
2024-01-02 18:09:18 -07:00
|
|
|
)
|
2022-10-14 08:08:00 -07:00
|
|
|
feed('<Esc>')
|
|
|
|
screen:set_option('ext_popupmenu', false)
|
|
|
|
|
2019-02-15 13:54:10 -07:00
|
|
|
feed('Sf<C-N>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
bar |
|
|
|
|
foobar |
|
|
|
|
f^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:foo }{1: }|
|
|
|
|
{4:foobar }{1: }|
|
|
|
|
{1:~ }|
|
|
|
|
{5:-- Keyword completion (^N^P) }{19:Back at original} |
|
2019-02-15 13:54:10 -07:00
|
|
|
]])
|
|
|
|
eq(
|
|
|
|
{ completed_item = {}, width = 15, height = 2, size = 2, col = 0, row = 4, scrollbar = false },
|
|
|
|
eval('g:event')
|
2024-01-02 18:09:18 -07:00
|
|
|
)
|
2019-02-15 13:54:10 -07:00
|
|
|
feed('<C-N>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
bar |
|
|
|
|
foobar |
|
|
|
|
foo^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:foo }{1: }|
|
|
|
|
{4:foobar }{1: }|
|
|
|
|
{1:~ }|
|
|
|
|
{5:-- Keyword completion (^N^P) }{6:match 1 of 2} |
|
2019-02-15 13:54:10 -07:00
|
|
|
]])
|
|
|
|
eq('foo', eval('g:word'))
|
|
|
|
feed('<C-N>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
bar |
|
|
|
|
foobar |
|
|
|
|
foobar^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:foo }{1: }|
|
|
|
|
{12:foobar }{1: }|
|
|
|
|
{1:~ }|
|
|
|
|
{5:-- Keyword completion (^N^P) }{6:match 2 of 2} |
|
2019-02-15 13:54:10 -07:00
|
|
|
]])
|
|
|
|
eq('foobar', eval('g:word'))
|
|
|
|
feed('<up>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
bar |
|
|
|
|
foobar |
|
|
|
|
foobar^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:foo }{1: }|
|
|
|
|
{4:foobar }{1: }|
|
|
|
|
{1:~ }|
|
|
|
|
{5:-- Keyword completion (^N^P) }{6:match 1 of 2} |
|
2019-02-15 13:54:10 -07:00
|
|
|
]])
|
|
|
|
eq('foo', eval('g:word'))
|
|
|
|
feed('<down>')
|
|
|
|
screen:expect([[
|
|
|
|
foo |
|
|
|
|
bar |
|
|
|
|
foobar |
|
|
|
|
foobar^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:foo }{1: }|
|
|
|
|
{12:foobar }{1: }|
|
|
|
|
{1:~ }|
|
|
|
|
{5:-- Keyword completion (^N^P) }{6:match 2 of 2} |
|
2019-02-15 13:54:10 -07:00
|
|
|
]])
|
|
|
|
eq('foobar', eval('g:word'))
|
|
|
|
feed('<esc>')
|
|
|
|
end)
|
2022-03-10 01:57:54 -07:00
|
|
|
|
2022-04-03 23:53:47 -07:00
|
|
|
it('is stopped by :stopinsert from timer #12976', function()
|
|
|
|
screen:try_resize(32, 14)
|
|
|
|
command([[call setline(1, ['hello', 'hullo', 'heeee', ''])]])
|
|
|
|
feed('Gah<c-x><c-n>')
|
|
|
|
screen:expect([[
|
|
|
|
hello |
|
|
|
|
hullo |
|
|
|
|
heeee |
|
|
|
|
hello^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:hello }{1: }|
|
|
|
|
{4:hullo }{1: }|
|
|
|
|
{4:heeee }{1: }|
|
|
|
|
{1:~ }|*6
|
|
|
|
{5:-- }{6:match 1 of 3} |
|
2022-04-03 23:53:47 -07:00
|
|
|
]])
|
|
|
|
command([[call timer_start(100, { -> execute('stopinsert') })]])
|
2024-01-12 04:41:09 -07:00
|
|
|
vim.uv.sleep(200)
|
2022-04-03 23:53:47 -07:00
|
|
|
feed('k') -- cursor should move up in Normal mode
|
|
|
|
screen:expect([[
|
|
|
|
hello |
|
|
|
|
hullo |
|
|
|
|
heee^e |
|
|
|
|
hello |
|
2024-05-26 00:34:29 -07:00
|
|
|
{1:~ }|*9
|
2022-04-03 23:53:47 -07:00
|
|
|
|
|
|
|
|
]])
|
|
|
|
end)
|
|
|
|
|
2024-01-29 16:34:37 -07:00
|
|
|
-- oldtest: Test_complete_changed_complete_info()
|
|
|
|
it('no crash calling complete_info() in CompleteChanged', function()
|
|
|
|
source([[
|
|
|
|
set completeopt=menuone
|
|
|
|
autocmd CompleteChanged * call complete_info(['items'])
|
|
|
|
call feedkeys("iii\<cr>\<c-p>")
|
|
|
|
]])
|
|
|
|
screen:expect([[
|
|
|
|
ii |
|
|
|
|
ii^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:ii }{1: }|
|
|
|
|
{1:~ }|*4
|
|
|
|
{5:-- Keyword completion (^N^P) The only match} |
|
2024-01-29 16:34:37 -07:00
|
|
|
]])
|
|
|
|
assert_alive()
|
|
|
|
end)
|
|
|
|
|
|
|
|
it('no crash if text changed by first call to complete function #17489', function()
|
2022-03-10 01:57:54 -07:00
|
|
|
source([[
|
|
|
|
func Complete(findstart, base) abort
|
|
|
|
if a:findstart
|
|
|
|
let col = col('.')
|
|
|
|
call complete_add('#')
|
|
|
|
return col - 1
|
|
|
|
else
|
|
|
|
return []
|
|
|
|
endif
|
|
|
|
endfunc
|
|
|
|
|
|
|
|
set completeopt=longest
|
|
|
|
set completefunc=Complete
|
|
|
|
]])
|
|
|
|
feed('ifoo#<C-X><C-U>')
|
|
|
|
assert_alive()
|
|
|
|
end)
|
2022-08-03 06:50:14 -07:00
|
|
|
|
2024-01-29 16:34:37 -07:00
|
|
|
it('no crash using i_CTRL-X_CTRL-V to complete non-existent colorscheme', function()
|
2022-08-03 06:50:14 -07:00
|
|
|
feed('icolorscheme NOSUCHCOLORSCHEME<C-X><C-V>')
|
|
|
|
expect('colorscheme NOSUCHCOLORSCHEME')
|
|
|
|
assert_alive()
|
|
|
|
end)
|
2023-10-12 23:49:01 -07:00
|
|
|
|
|
|
|
it('complete with f flag #25598', function()
|
|
|
|
screen:try_resize(20, 9)
|
2023-11-17 21:26:52 -07:00
|
|
|
command('set complete+=f | edit foo | edit bar |edit foa |edit .hidden')
|
2023-10-12 23:49:01 -07:00
|
|
|
feed('i<C-n>')
|
|
|
|
screen:expect {
|
|
|
|
grid = [[
|
|
|
|
foo^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:foo }{1: }|
|
|
|
|
{4:bar }{1: }|
|
|
|
|
{4:foa }{1: }|
|
|
|
|
{4:.hidden }{1: }|
|
|
|
|
{1:~ }|*3
|
|
|
|
{5:-- }{6:match 1 of 4} |
|
2023-11-17 21:26:52 -07:00
|
|
|
]],
|
|
|
|
}
|
|
|
|
feed('<Esc>ccf<C-n>')
|
|
|
|
screen:expect {
|
|
|
|
grid = [[
|
|
|
|
foo^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{12:foo }{1: }|
|
|
|
|
{4:foa }{1: }|
|
|
|
|
{1:~ }|*5
|
|
|
|
{5:-- }{6:match 1 of 2} |
|
2023-10-12 23:49:01 -07:00
|
|
|
]],
|
|
|
|
}
|
|
|
|
end)
|
2023-05-22 07:57:30 -07:00
|
|
|
|
|
|
|
it('restores extmarks if original text is restored #23653', function()
|
|
|
|
screen:try_resize(screen._width, 4)
|
|
|
|
command([[
|
|
|
|
call setline(1, ['aaaa'])
|
|
|
|
let ns_id = nvim_create_namespace('extmark')
|
|
|
|
let mark_id = nvim_buf_set_extmark(0, ns_id, 0, 0, { 'end_col':2, 'hl_group':'Error'})
|
|
|
|
let mark = nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })
|
|
|
|
inoremap <C-x> <C-r>=Complete()<CR>
|
|
|
|
function Complete() abort
|
|
|
|
call complete(1, [{ 'word': 'aaaaa' }])
|
|
|
|
return ''
|
|
|
|
endfunction
|
|
|
|
]])
|
|
|
|
feed('A<C-X><C-E><Esc>')
|
|
|
|
eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })"))
|
|
|
|
feed('A<C-N>')
|
|
|
|
eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })"))
|
|
|
|
feed('<Esc>0Yppia<Esc>ggI<C-N>')
|
|
|
|
screen:expect([[
|
2024-05-26 00:34:29 -07:00
|
|
|
aaaa{9:^aa}aa |
|
|
|
|
{12:aaaa } |
|
|
|
|
{4:aaaaa } |
|
|
|
|
{5:-- Keyword completion (^N^P) }{6:match 1 of 2} |
|
2023-05-22 07:57:30 -07:00
|
|
|
]])
|
|
|
|
feed('<C-N><C-N><Esc>')
|
|
|
|
eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })"))
|
|
|
|
feed('A<C-N>')
|
|
|
|
eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })"))
|
|
|
|
feed('<C-N>')
|
|
|
|
screen:expect([[
|
|
|
|
aaaaa^ |
|
2024-05-26 00:34:29 -07:00
|
|
|
{4:aaaa } |
|
|
|
|
{12:aaaaa } |
|
|
|
|
{5:-- Keyword completion (^N^P) }{6:match 2 of 2} |
|
2023-05-22 07:57:30 -07:00
|
|
|
]])
|
|
|
|
feed('<C-E>')
|
|
|
|
screen:expect([[
|
2024-05-26 00:34:29 -07:00
|
|
|
{9:aa}aa^ |
|
2023-05-22 07:57:30 -07:00
|
|
|
aaaa |
|
|
|
|
aaaaa |
|
2024-05-26 00:34:29 -07:00
|
|
|
{5:-- INSERT --} |
|
2023-05-22 07:57:30 -07:00
|
|
|
]])
|
|
|
|
end)
|
2015-05-01 17:19:19 -07:00
|
|
|
end)
|