1
0
forked from aniani/vim

patch 8.2.4387: command line completion doesn't always work properly

Problem:    Command line completion doesn't always work properly.
Solution:   Adjust triggering after a "|".  Add more tests. (Yegappan
            Lakshmanan, closes #9779)
This commit is contained in:
Yegappan Lakshmanan
2022-02-15 11:35:54 +00:00
committed by Bram Moolenaar
parent 8991be2ab4
commit e3846cf1eb
3 changed files with 124 additions and 22 deletions

View File

@@ -1473,16 +1473,21 @@ set_context_by_cmdname(
// skip "from" part // skip "from" part
++arg; ++arg;
arg = skip_regexp(arg, delim, magic_isset()); arg = skip_regexp(arg, delim, magic_isset());
}
// skip "to" part if (arg[0] != NUL && arg[0] == delim)
while (arg[0] != NUL && arg[0] != delim) {
{ // skip "to" part
if (arg[0] == '\\' && arg[1] != NUL)
++arg; ++arg;
++arg; while (arg[0] != NUL && arg[0] != delim)
{
if (arg[0] == '\\' && arg[1] != NUL)
++arg;
++arg;
}
if (arg[0] != NUL) // skip delimiter
++arg;
}
} }
if (arg[0] != NUL) // skip delimiter
++arg;
while (arg[0] && vim_strchr((char_u *)"|\"#", arg[0]) == NULL) while (arg[0] && vim_strchr((char_u *)"|\"#", arg[0]) == NULL)
++arg; ++arg;
if (arg[0] != NUL) if (arg[0] != NUL)
@@ -1508,7 +1513,8 @@ set_context_by_cmdname(
arg = skipwhite(arg + 1); arg = skipwhite(arg + 1);
// Check for trailing illegal characters // Check for trailing illegal characters
if (*arg && vim_strchr((char_u *)"|\"\n", *arg) == NULL) if (*arg == NUL ||
vim_strchr((char_u *)"|\"\n", *arg) == NULL)
xp->xp_context = EXPAND_NOTHING; xp->xp_context = EXPAND_NOTHING;
else else
return arg; return arg;
@@ -2408,6 +2414,8 @@ ExpandFromContext(
int len = (int)STRLEN(pat) + 20; int len = (int)STRLEN(pat) + 20;
tofree = alloc(len); tofree = alloc(len);
if (tofree == NULL)
return FAIL;
vim_snprintf((char *)tofree, len, "^<SNR>\\d\\+_%s", pat + 3); vim_snprintf((char *)tofree, len, "^<SNR>\\d\\+_%s", pat + 3);
pat = tofree; pat = tofree;
} }

View File

@@ -264,9 +264,11 @@ endfunc
func Test_match_completion() func Test_match_completion()
hi Aardig ctermfg=green hi Aardig ctermfg=green
call feedkeys(":match \<Tab>\<Home>\"\<CR>", 'xt') call feedkeys(":match \<Tab>\<Home>\"\<CR>", 'xt')
call assert_equal('"match Aardig', getreg(':')) call assert_equal('"match Aardig', @:)
call feedkeys(":match \<S-Tab>\<Home>\"\<CR>", 'xt') call feedkeys(":match \<S-Tab>\<Home>\"\<CR>", 'xt')
call assert_equal('"match none', getreg(':')) call assert_equal('"match none', @:)
call feedkeys(":match | chist\<Tab>\<C-B>\"\<CR>", 'xt')
call assert_equal('"match | chistory', @:)
endfunc endfunc
func Test_highlight_completion() func Test_highlight_completion()
@@ -387,6 +389,11 @@ func Test_getcompletion()
let l = getcompletion('run', 'file', 1) let l = getcompletion('run', 'file', 1)
call assert_true(index(l, 'runtest.vim') < 0) call assert_true(index(l, 'runtest.vim') < 0)
set wildignore& set wildignore&
" Directory name with space character
call mkdir('Xdir with space')
call assert_equal(['Xdir with space/'], getcompletion('Xdir\ w', 'shellcmd'))
call assert_equal(['./Xdir with space/'], getcompletion('./Xdir', 'shellcmd'))
call delete('Xdir with space', 'd')
let l = getcompletion('ha', 'filetype') let l = getcompletion('ha', 'filetype')
call assert_true(index(l, 'hamster') >= 0) call assert_true(index(l, 'hamster') >= 0)
@@ -608,7 +615,7 @@ func Test_expand_star_star()
call mkdir('a/b', 'p') call mkdir('a/b', 'p')
call writefile(['asdfasdf'], 'a/b/fileXname') call writefile(['asdfasdf'], 'a/b/fileXname')
call feedkeys(":find **/fileXname\<Tab>\<CR>", 'xt') call feedkeys(":find **/fileXname\<Tab>\<CR>", 'xt')
call assert_equal('find a/b/fileXname', getreg(':')) call assert_equal('find a/b/fileXname', @:)
bwipe! bwipe!
call delete('a', 'rf') call delete('a', 'rf')
endfunc endfunc
@@ -742,6 +749,12 @@ func Test_cmdline_complete_user_cmd()
call assert_equal('"Foo blue', @:) call assert_equal('"Foo blue', @:)
call feedkeys(":Foo b\<Tab>\<Home>\"\<cr>", 'tx') call feedkeys(":Foo b\<Tab>\<Home>\"\<cr>", 'tx')
call assert_equal('"Foo blue', @:) call assert_equal('"Foo blue', @:)
call feedkeys(":Foo a b\<Tab>\<Home>\"\<cr>", 'tx')
call assert_equal('"Foo a blue', @:)
call feedkeys(":Foo b\\\<Tab>\<Home>\"\<cr>", 'tx')
call assert_equal('"Foo b\', @:)
call feedkeys(":Foo b\\x\<Tab>\<Home>\"\<cr>", 'tx')
call assert_equal('"Foo b\x', @:)
delcommand Foo delcommand Foo
endfunc endfunc
@@ -953,14 +966,6 @@ func Test_cmdline_complete_various()
call feedkeys(":match Search /pat/\<C-A>\<C-B>\"\<CR>", 'xt') call feedkeys(":match Search /pat/\<C-A>\<C-B>\"\<CR>", 'xt')
call assert_equal("\"match Search /pat/\<C-A>", @:) call assert_equal("\"match Search /pat/\<C-A>", @:)
" completion for the :s command
call feedkeys(":s/from/to/g\<C-A>\<C-B>\"\<CR>", 'xt')
call assert_equal("\"s/from/to/g\<C-A>", @:)
" completion for the :dlist command
call feedkeys(":dlist 10 /pat/ a\<C-A>\<C-B>\"\<CR>", 'xt')
call assert_equal("\"dlist 10 /pat/ a\<C-A>", @:)
" completion for the :doautocmd command " completion for the :doautocmd command
call feedkeys(":doautocmd User MyCmd a.c\<C-A>\<C-B>\"\<CR>", 'xt') call feedkeys(":doautocmd User MyCmd a.c\<C-A>\<C-B>\"\<CR>", 'xt')
call assert_equal("\"doautocmd User MyCmd a.c\<C-A>", @:) call assert_equal("\"doautocmd User MyCmd a.c\<C-A>", @:)
@@ -1068,6 +1073,12 @@ func Test_cmdline_complete_various()
call feedkeys(":1,10 | chist\t\<C-B>\"\<CR>", 'xt') call feedkeys(":1,10 | chist\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"1,10 | chistory', @:) call assert_equal('"1,10 | chistory', @:)
" completion after a :global command
call feedkeys(":g/a/chist\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"g/a/chistory', @:)
call feedkeys(":g/a\\/chist\t\<C-B>\"\<CR>", 'xt')
call assert_equal("\"g/a\\/chist\t", @:)
" use <Esc> as the 'wildchar' for completion " use <Esc> as the 'wildchar' for completion
set wildchar=<Esc> set wildchar=<Esc>
call feedkeys(":g/a\\xb/clearj\<Esc>\<C-B>\"\<CR>", 'xt') call feedkeys(":g/a\\xb/clearj\<Esc>\<C-B>\"\<CR>", 'xt')
@@ -1077,12 +1088,18 @@ func Test_cmdline_complete_various()
call assert_equal('"g/a\xb/clearjumps', @:) call assert_equal('"g/a\xb/clearjumps', @:)
set wildchar& set wildchar&
" should be able to complete a file name that starts with a '~'.
if has('unix') if has('unix')
" should be able to complete a file name that starts with a '~'.
call writefile([], '~Xtest') call writefile([], '~Xtest')
call feedkeys(":e \\~X\<Tab>\<C-B>\"\<CR>", 'xt') call feedkeys(":e \\~X\<Tab>\<C-B>\"\<CR>", 'xt')
call assert_equal('"e \~Xtest', @:) call assert_equal('"e \~Xtest', @:)
call delete('~Xtest') call delete('~Xtest')
" should be able to complete a file name that has a '*'
call writefile([], 'Xx*Yy')
call feedkeys(":e Xx\*\<Tab>\<C-B>\"\<CR>", 'xt')
call assert_equal('"e Xx\*Yy', @:)
call delete('Xx*Yy')
endif endif
call feedkeys(":py3f\<Tab>\<C-B>\"\<CR>", 'xt') call feedkeys(":py3f\<Tab>\<C-B>\"\<CR>", 'xt')
@@ -1097,6 +1114,10 @@ func Test_cmdline_wildignorecase()
call feedkeys(":e xt\<Tab>\<C-B>\"\<CR>", 'xt') call feedkeys(":e xt\<Tab>\<C-B>\"\<CR>", 'xt')
call assert_equal('"e XTEST', @:) call assert_equal('"e XTEST', @:)
call assert_equal(['XTEST'], getcompletion('xt', 'file')) call assert_equal(['XTEST'], getcompletion('xt', 'file'))
let g:Sline = ''
call feedkeys(":e xt\<C-d>\<F4>\<C-B>\"\<CR>", 'xt')
call assert_equal('"e xt', @:)
call assert_equal('XTEST', g:Sline)
set wildignorecase& set wildignorecase&
call delete('XTEST') call delete('XTEST')
endfunc endfunc
@@ -1153,7 +1174,7 @@ func Test_tick_mark_in_range()
" If only the tick is passed as a range and no command is specified, there " If only the tick is passed as a range and no command is specified, there
" should not be an error " should not be an error
call feedkeys(":'\<CR>", 'xt') call feedkeys(":'\<CR>", 'xt')
call assert_equal("'", getreg(':')) call assert_equal("'", @:)
call assert_fails("',print", 'E78:') call assert_fails("',print", 'E78:')
endfunc endfunc
@@ -1725,6 +1746,26 @@ func Wildmode_tests()
call assert_equal('"e a1b2y3z4', @:) call assert_equal('"e a1b2y3z4', @:)
set wildmenu& set wildmenu&
" Test for longest file name completion with 'fileignorecase'
" On MS-Windows, file names are case insensitive.
if has('unix')
call writefile([], 'XTESTfoo')
call writefile([], 'Xtestbar')
set nofileignorecase
call feedkeys(":e XT\<Tab>\<C-B>\"\<CR>", 'xt')
call assert_equal('"e XTESTfoo', @:)
call feedkeys(":e Xt\<Tab>\<C-B>\"\<CR>", 'xt')
call assert_equal('"e Xtestbar', @:)
set fileignorecase
call feedkeys(":e XT\<Tab>\<C-B>\"\<CR>", 'xt')
call assert_equal('"e Xtest', @:)
call feedkeys(":e Xt\<Tab>\<C-B>\"\<CR>", 'xt')
call assert_equal('"e Xtest', @:)
set fileignorecase&
call delete('XTESTfoo')
call delete('Xtestbar')
endif
%argdelete %argdelete
delcommand MyCmd delcommand MyCmd
delfunc T delfunc T
@@ -1764,6 +1805,14 @@ func Test_interrupt_compl()
endtry endtry
call assert_equal(1, interrupted) call assert_equal(1, interrupted)
let interrupted = 0
try
call feedkeys(":Tcmd tw\<C-d>\<C-B>\"\<CR>", 'xt')
catch /^Vim:Interrupt$/
let interrupted = 1
endtry
call assert_equal(1, interrupted)
delcommand Tcmd delcommand Tcmd
delfunc F delfunc F
set wildmode& set wildmode&
@@ -2336,4 +2385,47 @@ func Test_wildmenumode_with_pum()
cunmap <F2> cunmap <F2>
endfunc endfunc
" Test for completion after a :substitute command followed by a pipe (|)
" character
func Test_cmdline_complete_substitute()
call feedkeys(":s | \t\<C-B>\"\<CR>", 'xt')
call assert_equal("\"s | \t", @:)
call feedkeys(":s/ | \t\<C-B>\"\<CR>", 'xt')
call assert_equal("\"s/ | \t", @:)
call feedkeys(":s/one | \t\<C-B>\"\<CR>", 'xt')
call assert_equal("\"s/one | \t", @:)
call feedkeys(":s/one/ | \t\<C-B>\"\<CR>", 'xt')
call assert_equal("\"s/one/ | \t", @:)
call feedkeys(":s/one/two | \t\<C-B>\"\<CR>", 'xt')
call assert_equal("\"s/one/two | \t", @:)
call feedkeys(":s/one/two/ | chist\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"s/one/two/ | chistory', @:)
call feedkeys(":s/one/two/g \t\<C-B>\"\<CR>", 'xt')
call assert_equal("\"s/one/two/g \t", @:)
call feedkeys(":s/one/two/g | chist\t\<C-B>\"\<CR>", 'xt')
call assert_equal("\"s/one/two/g | chistory", @:)
call feedkeys(":s/one/t\\/ | \t\<C-B>\"\<CR>", 'xt')
call assert_equal("\"s/one/t\\/ | \t", @:)
call feedkeys(":s/one/t\"o/ | chist\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"s/one/t"o/ | chistory', @:)
call feedkeys(":s/one/t|o/ | chist\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"s/one/t|o/ | chistory', @:)
call feedkeys(":&\t\<C-B>\"\<CR>", 'xt')
call assert_equal("\"&\t", @:)
endfunc
" Test for the :dlist command completion
func Test_cmdline_complete_dlist()
call feedkeys(":dlist 10 /pat/ a\<C-A>\<C-B>\"\<CR>", 'xt')
call assert_equal("\"dlist 10 /pat/ a\<C-A>", @:)
call feedkeys(":dlist 10 /pat/ \t\<C-B>\"\<CR>", 'xt')
call assert_equal("\"dlist 10 /pat/ \t", @:)
call feedkeys(":dlist 10 /pa\\t/\t\<C-B>\"\<CR>", 'xt')
call assert_equal("\"dlist 10 /pa\\t/\t", @:)
call feedkeys(":dlist 10 /pat\\\t\<C-B>\"\<CR>", 'xt')
call assert_equal("\"dlist 10 /pat\\\t", @:)
call feedkeys(":dlist 10 /pat/ | chist\<Tab>\<C-B>\"\<CR>", 'xt')
call assert_equal("\"dlist 10 /pat/ | chistory", @:)
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
4387,
/**/ /**/
4386, 4386,
/**/ /**/