1
0
forked from aniani/vim

patch 9.0.2037: A few remaining cmdline completion issues with C-E/Y

Problem:  A few remaining cmdline completion issues with C-E/Y
Solution: Fix cmdline completion fuzzy/Ctrl-E/Ctrl-Y/options when not
          used at the end

Fix cmdline completion fuzzy/Ctrl-E/Ctrl-Y/options when not used at the end

A few places in the cmdline completion code only works properly when the
user hits Tab (or 'wildchar') at the end of the cmdline, even though
it's supposed to work even in the middle of the line.

For fuzzy search, `:e ++ff`, and `:set hl=`, fix completion code to make
sure to use `xp_pattern_len` instead of assuming the entire `xp_pattern`
is the search pattern (since it contains texts after the cursor).

Fix Ctrl-E / Ctrl-Y to not jump to the end when canceling/accepting a
wildmenu completion. Also, make them work even when not using
`set wildoptions+=pum` as there is no drawback to doing so.
(Related issue where this was brought up: #13331)

closes: #13362

Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Yee Cheng Chin <ychin.git@gmail.com>
This commit is contained in:
Yee Cheng Chin
2023-10-17 10:56:25 +02:00
committed by Christian Brabandt
parent 396058acd0
commit 209ec90b9b
12 changed files with 88 additions and 13 deletions

View File

@@ -260,7 +260,7 @@ nextwild(
{
if (cmdline_fuzzy_completion_supported(xp))
// If fuzzy matching, don't modify the search string
p1 = vim_strsave(xp->xp_pattern);
p1 = vim_strnsave(xp->xp_pattern, xp->xp_pattern_len);
else
p1 = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);

View File

@@ -5590,7 +5590,8 @@ expand_argopt(
// Special handling of "ff" which acts as a short form of
// "fileformat", as "ff" is not a substring of it.
if (STRCMP(xp->xp_pattern, "ff") == 0)
if (xp->xp_pattern_len == 2
&& STRNCMP(xp->xp_pattern, "ff", xp->xp_pattern_len) == 0)
{
*matches = ALLOC_MULT(char_u *, 1);
if (*matches == NULL)

View File

@@ -1599,7 +1599,7 @@ getcmdline_int(
cmdline_info_T save_ccline;
int did_save_ccline = FALSE;
int cmdline_type;
int wild_type;
int wild_type = 0;
// one recursion level deeper
++depth;
@@ -1878,7 +1878,7 @@ getcmdline_int(
c = wildmenu_translate_key(&ccline, c, &xpc, did_wild_list);
int key_is_wc = (c == p_wc && KeyTyped) || c == p_wcm;
if (cmdline_pum_active() && !key_is_wc)
if ((cmdline_pum_active() || did_wild_list) && !key_is_wc)
{
// Ctrl-Y: Accept the current selection and close the popup menu.
// Ctrl-E: cancel the cmdline popup menu and return the original
@@ -1889,7 +1889,6 @@ getcmdline_int(
if (nextwild(&xpc, wild_type, WILD_NO_BEEP,
firstc != '@') == FAIL)
break;
c = Ctrl_E;
}
}
@@ -2016,6 +2015,14 @@ getcmdline_int(
do_abbr = TRUE; // default: check for abbreviation
// If already used to cancel/accept wildmenu, don't process the key
// further.
if (wild_type == WILD_CANCEL || wild_type == WILD_APPLY)
{
wild_type = 0;
goto cmdline_not_changed;
}
/*
* Big switch for a typed command line character.
*/

View File

@@ -2582,12 +2582,13 @@ expand_set_highlight(optexpand_T *args, int *numMatches, char_u ***matches)
if (*matches == NULL)
return FAIL;
size_t pattern_len = STRLEN(xp->xp_pattern);
int pattern_len = xp->xp_pattern_len;
for (i = 0; i < num_hl_modes; i++)
{
// Don't allow duplicates as these are unique flags
if (vim_strchr(xp->xp_pattern + 1, p_hl_mode_values[i]) != NULL)
char_u *dup = vim_strchr(xp->xp_pattern + 1, p_hl_mode_values[i]);
if (dup != NULL && (int)(dup - xp->xp_pattern) < pattern_len)
continue;
// ':' only works by itself, not with other flags.

View File

@@ -0,0 +1,10 @@
| +0&#ffffff0@74
|~+0#4040ff13&| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @2| +0#0000001#e0e0e08|w|i|l|d|c|h|a|r| @6| +0#4040ff13#ffffff0@54
|~| @2| +0#0000001#ffd7ff255|w|i|l|d|c|h|a|r|m| @5| +0#4040ff13#ffffff0@54
|:+0#0000000&|s|e|t| |w|i|l|d|c|h|a|r>z@1| @59

View File

@@ -0,0 +1,10 @@
| +0&#ffffff0@74
|~+0#4040ff13&| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|:+0#0000000&|s|e|t| |w|i|l|d|c|h|a>z@1| @60

View File

@@ -0,0 +1,10 @@
| +0&#ffffff0@74
|~+0#4040ff13&| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|:+0#0000000&|s|e|t| |w|i|l|d|c|h|a|r>z@1| @59

View File

@@ -158,6 +158,13 @@ func Test_complete_wildmenu()
call feedkeys(":sign \<Tab>\<PageUp>\<Left>\<Right>\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"TestWildMenu', @:)
" Test for Ctrl-E/Ctrl-Y being able to cancel / accept a match
call feedkeys(":sign un zz\<Left>\<Left>\<Left>\<Tab>\<C-E> yy\<C-B>\"\<CR>", 'tx')
call assert_equal('"sign un yy zz', @:)
call feedkeys(":sign un zz\<Left>\<Left>\<Left>\<Tab>\<Tab>\<C-Y> yy\<C-B>\"\<CR>", 'tx')
call assert_equal('"sign unplace yy zz', @:)
" cleanup
%bwipe
set nowildmenu
@@ -1105,6 +1112,9 @@ func Test_cmdline_complete_argopt()
call assert_equal('edit', getcompletion('read ++bin ++edi', 'cmdline')[0])
call assert_equal(['fileformat='], getcompletion('edit ++ff', 'cmdline'))
" Test ++ff in the middle of the cmdline
call feedkeys(":edit ++ff zz\<Left>\<Left>\<Left>\<C-A>\<C-B>\"\<CR>", 'xt')
call assert_equal("\"edit ++fileformat= zz", @:)
call assert_equal('dos', getcompletion('write ++ff=d', 'cmdline')[0])
call assert_equal('mac', getcompletion('args ++fileformat=m', 'cmdline')[0])
@@ -2585,6 +2595,16 @@ func Test_wildmenu_pum()
call term_sendkeys(buf, "\<PageUp>")
call VerifyScreenDump(buf, 'Test_wildmenu_pum_50', {})
" pressing <C-E> to end completion should work in middle of the line too
call term_sendkeys(buf, "\<Esc>:set wildchazz\<Left>\<Left>\<Tab>")
call VerifyScreenDump(buf, 'Test_wildmenu_pum_51', {})
call term_sendkeys(buf, "\<C-E>")
call VerifyScreenDump(buf, 'Test_wildmenu_pum_52', {})
" pressing <C-Y> should select the current match and end completion
call term_sendkeys(buf, "\<Esc>:set wildchazz\<Left>\<Left>\<Tab>\<C-Y>")
call VerifyScreenDump(buf, 'Test_wildmenu_pum_53', {})
call term_sendkeys(buf, "\<C-U>\<CR>")
call StopVimInTerminal(buf)
endfunc
@@ -3293,6 +3313,17 @@ func Test_fuzzy_completion_custom_func()
set wildoptions&
endfunc
" Test for fuzzy completion in the middle of a cmdline instead of at the end
func Test_fuzzy_completion_in_middle()
set wildoptions=fuzzy
call feedkeys(":set ildar wrap\<Left>\<Left>\<Left>\<Left>\<Left>\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal("\"set wildchar wildcharm wrap", @:)
call feedkeys(":args ++odng zz\<Left>\<Left>\<Left>\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal("\"args ++encoding= zz", @:)
set wildoptions&
endfunc
" Test for :breakadd argument completion
func Test_cmdline_complete_breakadd()
call feedkeys(":breakadd \<C-A>\<C-B>\"\<CR>", 'tx')

View File

@@ -616,6 +616,9 @@ func Test_set_completion_string_values()
\ {idx, val -> val != ':'}),
\ '')
call assert_equal([], getcompletion('set hl+=8'..hl_display_modes, 'cmdline'))
" Test completion in middle of the line
call feedkeys(":set hl=8b i\<Left>\<Left>\<Tab>\<C-B>\"\<CR>", 'xt')
call assert_equal("\"set hl=8bi i", @:)
"
" Test flag lists

View File

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