vim-patch:9.1.1409: using f-flag in 'complete' conflicts with Neovim

Problem:  using f-flag in 'complete' conflicts with Neovims filename
          completion (glepnir, after v9.1.1301).
Solution: use upper-case "F" flag for completion functions
          (Girish Palya).

fixes: vim/vim#17347
closes: vim/vim#17378

14f6da5ba8

Co-authored-by: Girish Palya <girishji@gmail.com>
This commit is contained in:
zeertzjq
2025-05-31 19:03:41 +08:00
parent 13aec582b4
commit eeff6ca8ff
8 changed files with 68 additions and 70 deletions

View File

@@ -179,8 +179,8 @@ OPTIONS
• 'completefuzzycollect' enables fuzzy collection of candidates for (some)
|ins-completion| modes.
• 'complete' new flags:
• "f{func}" complete using given function
• "f" complete using 'completefunc'
• "F{func}" complete using given function
• "F" complete using 'completefunc'
• "o" complete using 'omnifunc'
• 'complete' allows limiting matches for sources using "{flag}^<limit>".
• 'completeopt' flag "nearset" sorts completion results by distance to cursor.

View File

@@ -1506,7 +1506,7 @@ A jump table for the options with a short description can be found at |Q_op|.
] tag completion
t same as "]"
f scan the buffer names (as opposed to buffer contents)
f{func} call the function {func}. Multiple "f" flags may be specified.
F{func} call the function {func}. Multiple "F" flags may be specified.
Refer to |complete-functions| for details on how the function
is invoked and what it should return. The value can be the
name of a function or a |Funcref|. For |Funcref| values,
@@ -1524,9 +1524,9 @@ A jump table for the options with a short description can be found at |Q_op|.
If generating matches is potentially slow, |complete_check()|
should be used to avoid blocking and preserve editor
responsiveness.
f equivalent to using "f{func}", where the function is taken from
F equivalent to using "F{func}", where the function is taken from
the 'completefunc' option.
o equivalent to using "f{func}", where the function is taken from
o equivalent to using "F{func}", where the function is taken from
the 'omnifunc' option.
Unloaded buffers are not loaded, thus their autocmds |:autocmd| are

View File

@@ -1027,7 +1027,7 @@ vim.bo.cms = vim.bo.commentstring
--- ] tag completion
--- t same as "]"
--- f scan the buffer names (as opposed to buffer contents)
--- f{func} call the function {func}. Multiple "f" flags may be specified.
--- F{func} call the function {func}. Multiple "F" flags may be specified.
--- Refer to `complete-functions` for details on how the function
--- is invoked and what it should return. The value can be the
--- name of a function or a `Funcref`. For `Funcref` values,
@@ -1045,9 +1045,9 @@ vim.bo.cms = vim.bo.commentstring
--- If generating matches is potentially slow, `complete_check()`
--- should be used to avoid blocking and preserve editor
--- responsiveness.
--- f equivalent to using "f{func}", where the function is taken from
--- F equivalent to using "F{func}", where the function is taken from
--- the 'completefunc' option.
--- o equivalent to using "f{func}", where the function is taken from
--- o equivalent to using "F{func}", where the function is taken from
--- the 'omnifunc' option.
---
--- Unloaded buffers are not loaded, thus their autocmds `:autocmd` are

View File

@@ -3548,7 +3548,7 @@ static int process_next_cpt_value(ins_compl_next_state_T *st, int *compl_type_ar
st->dict = st->e_cpt;
st->dict_f = DICT_FIRST;
}
} else if (*st->e_cpt == 'f' || *st->e_cpt == 'o') {
} else if (*st->e_cpt == 'F' || *st->e_cpt == 'o') {
compl_type = CTRL_X_FUNCTION;
if (*st->e_cpt == 'o') {
st->func_cb = &curbuf->b_ofu_cb;
@@ -3563,10 +3563,8 @@ static int process_next_cpt_value(ins_compl_next_state_T *st, int *compl_type_ar
compl_type = CTRL_X_PATH_PATTERNS;
} else if (*st->e_cpt == 'd') {
compl_type = CTRL_X_PATH_DEFINES;
#if 0
} else if (*st->e_cpt == 'f') {
compl_type = CTRL_X_BUFNAMES;
#endif
} else if (*st->e_cpt == ']' || *st->e_cpt == 't') {
compl_type = CTRL_X_TAGS;
if (!shortmess(SHM_COMPLETIONSCAN)) {
@@ -5934,7 +5932,7 @@ static void cpt_compl_refresh(void)
if (cpt_sources_array[cpt_sources_index].refresh_always) {
if (*p == 'o') {
cb = &curbuf->b_ofu_cb;
} else if (*p == 'f') {
} else if (*p == 'F') {
cb = (*(p + 1) != ',' && *(p + 1) != NUL)
? get_cpt_func_callback(p + 1) : &curbuf->b_cfu_cb;
}

View File

@@ -1412,7 +1412,7 @@ local options = {
abbreviation = 'cpt',
cb = 'did_set_complete',
defaults = '.,w,b,u,t',
values = { '.', 'w', 'b', 'u', 'k', 'kspell', 's', 'i', 'd', ']', 't', 'U', 'f', 'o' },
values = { '.', 'w', 'b', 'u', 'k', 'kspell', 's', 'i', 'd', ']', 't', 'U', 'f', 'F', 'o' },
deny_duplicates = true,
desc = [=[
This option specifies how keyword completion |ins-completion| works
@@ -1438,7 +1438,7 @@ local options = {
] tag completion
t same as "]"
f scan the buffer names (as opposed to buffer contents)
f{func} call the function {func}. Multiple "f" flags may be specified.
F{func} call the function {func}. Multiple "F" flags may be specified.
Refer to |complete-functions| for details on how the function
is invoked and what it should return. The value can be the
name of a function or a |Funcref|. For |Funcref| values,
@@ -1456,9 +1456,9 @@ local options = {
If generating matches is potentially slow, |complete_check()|
should be used to avoid blocking and preserve editor
responsiveness.
f equivalent to using "f{func}", where the function is taken from
F equivalent to using "F{func}", where the function is taken from
the 'completefunc' option.
o equivalent to using "f{func}", where the function is taken from
o equivalent to using "F{func}", where the function is taken from
the 'omnifunc' option.
Unloaded buffers are not loaded, thus their autocmds |:autocmd| are

View File

@@ -864,11 +864,11 @@ const char *did_set_complete(optset_T *args)
}
*buf_ptr = NUL;
if (vim_strchr(".wbuksid]tUfo", (uint8_t)(*buffer)) == NULL) {
if (vim_strchr(".wbuksid]tUfFo", (uint8_t)(*buffer)) == NULL) {
return illegal_char(args->os_errbuf, args->os_errbuflen, (uint8_t)(*buffer));
}
if (vim_strchr("ksf", (uint8_t)(*buffer)) == NULL && *(buffer + 1) != NUL
if (vim_strchr("ksF", (uint8_t)(*buffer)) == NULL && *(buffer + 1) != NUL
&& *(buffer + 1) != '^') {
char_before = (uint8_t)(*buffer);
} else {

View File

@@ -199,7 +199,7 @@ func Test_completefunc_args()
call assert_equal(0, s:args[1][0])
set omnifunc=
set complete=fCompleteFunc
set complete=FCompleteFunc
call feedkeys("i\<C-N>\<Esc>", 'x')
call assert_equal([1, 1], s:args[0])
call assert_equal(0, s:args[1][0])
@@ -275,7 +275,7 @@ func Test_CompleteDoneNone()
call assert_equal(oldline, newline)
let s:called_completedone = 0
set complete=f<SID>CompleteDone_CompleteFuncNone
set complete=F<SID>CompleteDone_CompleteFuncNone
execute "normal a\<C-N>\<C-Y>"
set complete&
let newline = join(map(range(&columns), 'nr2char(screenchar(&lines-1, v:val+1))'), '')
@@ -302,7 +302,7 @@ func Test_CompleteDone_vevent_keys()
endfunc
set omnifunc=CompleteFunc
set completefunc=CompleteFunc
set complete=.,fCompleteFunc
set complete=.,FCompleteFunc
set completeopt+=menuone
new
@@ -394,7 +394,7 @@ func Test_CompleteDoneDict()
au CompleteDonePre * :call <SID>CompleteDone_CheckCompletedItemDict(2)
au CompleteDone * :call <SID>CompleteDone_CheckCompletedItemDict(0)
set complete=.,f<SID>CompleteDone_CompleteFuncDict
set complete=.,F<SID>CompleteDone_CompleteFuncDict
execute "normal a\<C-N>\<C-Y>"
set complete&
@@ -447,7 +447,7 @@ func Test_CompleteDoneDictNoUserData()
let s:called_completedone = 0
set complete=.,f<SID>CompleteDone_CompleteFuncDictNoUserData
set complete=.,F<SID>CompleteDone_CompleteFuncDictNoUserData
execute "normal a\<C-N>\<C-Y>"
set complete&
@@ -489,7 +489,7 @@ func Test_CompleteDoneList()
let s:called_completedone = 0
set complete=.,f<SID>CompleteDone_CompleteFuncList
set complete=.,F<SID>CompleteDone_CompleteFuncList
execute "normal a\<C-N>\<C-Y>"
set complete&
@@ -498,7 +498,7 @@ func Test_CompleteDoneList()
let s:called_completedone = 0
set complete=.,f
set complete=.,F
execute "normal a\<C-N>\<C-Y>"
set complete&
@@ -549,11 +549,11 @@ func Test_completefunc_info()
call feedkeys("i\<C-X>\<C-U>\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx")
call assert_equal("matched{'pum_visible': 1, 'mode': 'function', 'selected': 0, 'items': [{'word': 'matched', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}]}", getline(1))
%d
set complete=.,fCompleteTest
set complete=.,FCompleteTest
call feedkeys("i\<C-N>\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx")
call assert_equal("matched{'pum_visible': 1, 'mode': 'keyword', 'selected': 0, 'items': [{'word': 'matched', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}]}", getline(1))
%d
set complete=.,f
set complete=.,F
call feedkeys("i\<C-N>\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx")
call assert_equal("matched{'pum_visible': 1, 'mode': 'keyword', 'selected': 0, 'items': [{'word': 'matched', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}]}", getline(1))
set completeopt&
@@ -573,7 +573,7 @@ func Test_cpt_func_cursorcol()
" return v:none
endfunc
set complete=fCptColTest
set complete=FCptColTest
new
call feedkeys("ifoo bar\<C-N>", "tx")
bwipe!
@@ -666,12 +666,12 @@ func CompleteInfoTestUserDefinedFn(mvmt, idx, noselect)
let completed = a:idx != -1 ? ['foo', 'bar', 'baz', 'qux']->get(a:idx) : ''
call assert_equal(completed. "{'pum_visible': 1, 'mode': 'function', 'selected': " . a:idx . ", 'items': " . items . "}", getline(1))
%d
set complete=.,fCompleteInfoUserDefinedFn
set complete=.,FCompleteInfoUserDefinedFn
call feedkeys("i\<C-N>" . a:mvmt . "\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx")
let completed = a:idx != -1 ? ['foo', 'bar', 'baz', 'qux']->get(a:idx) : ''
call assert_equal(completed. "{'pum_visible': 1, 'mode': 'keyword', 'selected': " . a:idx . ", 'items': " . items . "}", getline(1))
%d
set complete=.,f
set complete=.,F
call feedkeys("i\<C-N>" . a:mvmt . "\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx")
let completed = a:idx != -1 ? ['foo', 'bar', 'baz', 'qux']->get(a:idx) : ''
call assert_equal(completed. "{'pum_visible': 1, 'mode': 'keyword', 'selected': " . a:idx . ", 'items': " . items . "}", getline(1))
@@ -1044,9 +1044,9 @@ func Test_completefunc_error()
set completefunc=CompleteFunc
call setline(1, ['', 'abcd', ''])
call assert_fails('exe "normal 2G$a\<C-X>\<C-U>"', 'E565:')
set complete=fCompleteFunc
set complete=FCompleteFunc
call assert_fails('exe "normal 2G$a\<C-N>"', 'E565:')
set complete=f
set complete=F
call assert_fails('exe "normal 2G$a\<C-N>"', 'E565:')
" delete text when called for the second time
@@ -1060,9 +1060,9 @@ func Test_completefunc_error()
set completefunc=CompleteFunc2
call setline(1, ['', 'abcd', ''])
call assert_fails('exe "normal 2G$a\<C-X>\<C-U>"', 'E565:')
set complete=fCompleteFunc2
set complete=FCompleteFunc2
call assert_fails('exe "normal 2G$a\<C-N>"', 'E565:')
set complete=f
set complete=F
call assert_fails('exe "normal 2G$a\<C-N>"', 'E565:')
" Jump to a different window from the complete function
@@ -1077,10 +1077,10 @@ func Test_completefunc_error()
new
call assert_fails('exe "normal a\<C-X>\<C-U>"', 'E565:')
%d
set complete=fCompleteFunc3
set complete=FCompleteFunc3
call assert_fails('exe "normal a\<C-N>"', 'E565:')
%d
set complete=f
set complete=F
call assert_fails('exe "normal a\<C-N>"', 'E565:')
close!
@@ -1104,11 +1104,11 @@ func Test_completefunc_invalid_data()
exe "normal i\<C-X>\<C-U>"
call assert_equal('moon', getline(1))
%d
set complete=fCompleteFunc
set complete=FCompleteFunc
exe "normal i\<C-N>"
call assert_equal('moon', getline(1))
%d
set complete=f
set complete=F
exe "normal i\<C-N>"
call assert_equal('moon', getline(1))
set completefunc& complete&
@@ -1796,13 +1796,13 @@ func Test_complete_item_refresh_always()
call assert_equal(6, g:CallCount)
%d
let g:CallCount = 0
set complete=fTcomplete
set complete=FTcomplete
exe "normal! iup\<C-N>\<BS>\<BS>\<BS>\<BS>\<BS>"
call assert_equal('up', getline(1))
call assert_equal(6, g:CallCount)
%d
let g:CallCount = 0
set complete=f
set complete=F
exe "normal! iup\<C-N>\<BS>\<BS>\<BS>\<BS>\<BS>"
call assert_equal('up', getline(1))
call assert_equal(6, g:CallCount)
@@ -1829,10 +1829,10 @@ func Test_cpt_func_refresh_always_fail()
call assert_equal(-999, a:findstart) " Should not reach here
endfunc
new
set complete=ffunction('CompleteFail'\\,\ [-2])
set complete=Ffunction('CompleteFail'\\,\ [-2])
exe "normal! ia\<C-N>"
%d
set complete=ffunction('CompleteFail'\\,\ [-3])
set complete=Ffunction('CompleteFail'\\,\ [-3])
exe "normal! ia\<C-N>"
bw!
@@ -1850,7 +1850,7 @@ func Test_cpt_func_refresh_always_fail()
endfunc
new
set completeopt=menuone,noselect
set complete=ffunction('CompleteFailIntermittent'\\,\ [-2])
set complete=Ffunction('CompleteFailIntermittent'\\,\ [-2])
let g:CallCount = 0
exe "normal! if\<C-N>\<c-r>=complete_info([\"items\"])\<cr>"
call assert_match('''word'': ''foo''.*''word'': ''fbar''', getline(1))
@@ -1861,13 +1861,13 @@ func Test_cpt_func_refresh_always_fail()
call assert_match('''selected'': -1.*''word'': ''foo1''.*''word'': ''foo2''', getline(1))
call assert_equal(2, g:CallCount)
%d
set complete=ffunction('CompleteFailIntermittent'\\,\ [-3])
set complete=Ffunction('CompleteFailIntermittent'\\,\ [-3])
let g:CallCount = 0
exe "normal! if\<C-N>o\<c-r>=complete_info([\"items\", \"selected\"])\<cr>"
call assert_match('''selected'': -1.*''word'': ''foo1''.*''word'': ''foo2''', getline(1))
call assert_equal(2, g:CallCount)
%d
set complete=ffunction('CompleteFailIntermittent'\\,\ [-2])
set complete=Ffunction('CompleteFailIntermittent'\\,\ [-2])
" completion mode is dismissed when there are no matches in list
let g:CallCount = 0
exe "normal! if\<C-N>oo\<c-r>=complete_info([\"items\"])\<cr>"
@@ -1880,7 +1880,7 @@ func Test_cpt_func_refresh_always_fail()
call assert_equal(3, g:CallCount)
%d
" completion mode continues when matches from other sources present
set complete=.,ffunction('CompleteFailIntermittent'\\,\ [-2])
set complete=.,Ffunction('CompleteFailIntermittent'\\,\ [-2])
call setline(1, 'fooo1')
let g:CallCount = 0
exe "normal! Gof\<C-N>oo\<c-r>=complete_info([\"items\", \"selected\"])\<cr>"
@@ -1896,7 +1896,7 @@ func Test_cpt_func_refresh_always_fail()
call assert_equal(4, g:CallCount)
%d
" refresh will stop when -3 is returned
set complete=.,,\ ffunction('CompleteFailIntermittent'\\,\ [-3])
set complete=.,,\ Ffunction('CompleteFailIntermittent'\\,\ [-3])
call setline(1, 'fooo1')
let g:CallCount = 0
exe "normal! Gof\<C-N>o\<bs>\<c-r>=complete_info([\"items\", \"selected\"])\<cr>"
@@ -1941,7 +1941,7 @@ func Test_cpt_select_item_refresh_always()
endfunc
new
set complete=.,ffunction('CompleteItemsSelect'\\,\ [[]])
set complete=.,Ffunction('CompleteItemsSelect'\\,\ [[]])
call setline(1, "foobarbar")
let g:CallCount = 0
exe "normal! Gof\<c-n>\<c-n>\<c-r>=CompleteMenuWords()\<cr>"
@@ -1973,7 +1973,7 @@ func Test_cpt_select_item_refresh_always()
call assert_equal(2, g:CallCount)
%d
set complete=.,ffunction('CompleteItemsSelect'\\,\ [['foonext']])
set complete=.,Ffunction('CompleteItemsSelect'\\,\ [['foonext']])
call setline(1, "foobarbar")
let g:CallCount = 0
exe "normal! Gof\<c-n>\<c-n>\<bs>\<c-r>=CompleteMenuWords()\<cr>"
@@ -2013,7 +2013,7 @@ func Test_cpt_select_item_refresh_always()
call assert_equal(3, g:CallCount)
%d
set complete=.,ffunction('CompleteItemsSelect'\\,\ [['fo'\\,\ 'foonext']])
set complete=.,Ffunction('CompleteItemsSelect'\\,\ [['fo'\\,\ 'foonext']])
call setline(1, "foobarbar")
let g:CallCount = 0
exe "normal! Gof\<c-n>\<c-n>\<bs>\<c-r>=CompleteMenuWords()\<cr>"
@@ -2065,7 +2065,7 @@ func Test_cpt_multi_func_refresh_always()
call assert_equal("f\x0e" . '{''matches'': [], ''selected'': -1}', getline(1))
set completeopt=menuone,noselect
set complete=fCompleteItems1,fCompleteItems2
set complete=FCompleteItems1,FCompleteItems2
new
let g:CallCount1 = 0
@@ -2197,7 +2197,7 @@ func Test_cpt_func_callback()
let lines =<< trim END
#" Test for using a global function name
set complete=fg:CompleteFunc2
set complete=Fg:CompleteFunc2
new
call setline(1, 'global')
LET g:CompleteFunc2Args = []
@@ -2207,7 +2207,7 @@ func Test_cpt_func_callback()
bw!
#" Test for using a function()
set complete=ffunction('g:CompleteFunc1'\\,\ [10])
set complete=Ffunction('g:CompleteFunc1'\\,\ [10])
new
call setline(1, 'one')
LET g:CompleteFunc1Args = []
@@ -2217,7 +2217,7 @@ func Test_cpt_func_callback()
bw!
#" Using a funcref variable
set complete=ffuncref('g:CompleteFunc1'\\,\ [11])
set complete=Ffuncref('g:CompleteFunc1'\\,\ [11])
new
call setline(1, 'two')
LET g:CompleteFunc1Args = []
@@ -2234,7 +2234,7 @@ func Test_cpt_func_callback()
call add(g:CompleteFunc3Args, [a:findstart, a:base])
return a:findstart ? 0 : []
endfunc
set complete=fs:CompleteFunc3
set complete=Fs:CompleteFunc3
new
call setline(1, 'script1')
let g:CompleteFunc3Args = []
@@ -2243,7 +2243,7 @@ func Test_cpt_func_callback()
set complete&
bw!
let &complete = 'fs:CompleteFunc3'
let &complete = 'Fs:CompleteFunc3'
new
call setline(1, 'script2')
let g:CompleteFunc3Args = []
@@ -2261,7 +2261,7 @@ func Test_cpt_func_callback()
add(CompleteFunc4Args, [findstart, base])
return findstart ? 0 : []
enddef
set complete=fCompleteFunc4
set complete=FCompleteFunc4
new
setline(1, 'script1')
feedkeys("A\<C-N>\<Esc>", 'x')
@@ -2281,7 +2281,7 @@ func Test_cpt_func_callback()
enddef
# Test for using a def function with completefunc
set complete=ffunction('Vim9CompleteFunc'\\,\ [60])
set complete=Ffunction('Vim9CompleteFunc'\\,\ [60])
new | only
setline(1, 'one')
g:Vim9completeFuncArgs = []
@@ -2290,7 +2290,7 @@ func Test_cpt_func_callback()
bw!
# Test for using a global function name
&complete = 'fg:CompleteFunc2'
&complete = 'Fg:CompleteFunc2'
new | only
setline(1, 'two')
g:CompleteFunc2Args = []
@@ -2303,7 +2303,7 @@ func Test_cpt_func_callback()
add(g:LocalCompleteFuncArgs, [findstart, base])
return findstart ? 0 : []
enddef
&complete = 'fLocalCompleteFunc'
&complete = 'FLocalCompleteFunc'
new | only
setline(1, 'three')
g:LocalCompleteFuncArgs = []
@@ -3202,12 +3202,12 @@ func Test_complete_smartindent()
let result = getline(1,'$')
call assert_equal(['', '{','}',''], result)
%d
setlocal complete=fFooBarComplete
setlocal complete=FFooBarComplete
exe "norm! o{\<cr>\<c-n>\<c-p>}\<cr>\<esc>"
let result = getline(1,'$')
call assert_equal(['', '{','}',''], result)
%d
setlocal complete=f
setlocal complete=F
exe "norm! o{\<cr>\<c-n>\<c-p>}\<cr>\<esc>"
let result = getline(1,'$')
call assert_equal(['', '{','}',''], result)
@@ -4202,7 +4202,7 @@ func Test_complete_match_count()
%d
set completefunc=ComplFunc
set cpt=.^1,f^2
set cpt=.^1,F^2
call setline(1, ["fo", "foo", "foobar", "fobarbaz"])
exe "normal! Gof\<c-n>\<c-r>=PrintMenuWords()\<cr>"
call assert_equal('fo{''matches'': [''fo'', ''foo1'', ''foo2''], ''selected'': 0}', getline(5))
@@ -4237,7 +4237,7 @@ func Test_complete_match_count()
%d
call setline(1, ["foo"])
set cpt=fComplFunc^2,.
set cpt=FComplFunc^2,.
exe "normal! Gof\<c-n>\<c-r>=PrintMenuWords()\<cr>"
call assert_equal('foo1{''matches'': [''foo1'', ''foo2'', ''foo''], ''selected'': 0}', getline(2))
bw!
@@ -4254,7 +4254,7 @@ func Test_complete_match_count()
endfunc
new
set complete=.,ffunction('CompleteItemsSelect')^2
set complete=.,Ffunction('CompleteItemsSelect')^2
call setline(1, "foobarbar")
let g:CallCount = 0
exe "normal! Gof\<c-n>\<c-n>\<c-r>=PrintMenuWords()\<cr>"

View File

@@ -279,7 +279,7 @@ func Test_complete()
call assert_fails('set complete=ix', 'E535:')
call assert_fails('set complete=x', 'E539:')
call assert_fails('set complete=..', 'E535:')
set complete=.,w,b,u,k,\ s,i,d,],t,U,f,o
set complete=.,w,b,u,k,\ s,i,d,],t,U,F,o
call assert_fails('set complete=i^-10', 'E535:')
call assert_fails('set complete=i^x', 'E535:')
call assert_fails('set complete=k^2,t^-1,s^', 'E535:')
@@ -287,13 +287,13 @@ func Test_complete()
call assert_fails('set complete=kfoo^foo2', 'E535:')
call assert_fails('set complete=kfoo^', 'E535:')
call assert_fails('set complete=.^', 'E535:')
set complete=.,w,b,u,k,s,i,d,],t,U,f,o
set complete=.,w,b,u,k,s,i,d,],t,U,F,o
set complete=.
set complete=.^10,t^0
set complete+=ffuncref('foo'\\,\ [10])
set complete=ffuncref('foo'\\,\ [10])^10
set complete+=Ffuncref('foo'\\,\ [10])
set complete=Ffuncref('foo'\\,\ [10])^10
set complete&
set complete+=ffunction('g:foo'\\,\ [10\\,\ 20])
set complete+=Ffunction('g:foo'\\,\ [10\\,\ 20])
set complete&
endfun