Skip to content

Commit 209ec90

Browse files
ychinchrisbra
authored andcommitted
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 <[email protected]> Co-authored-by: Yee Cheng Chin <[email protected]>
1 parent 396058a commit 209ec90

File tree

12 files changed

+88
-13
lines changed

12 files changed

+88
-13
lines changed

runtime/doc/index.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,12 +1119,12 @@ commands in wildmenu mode (see 'wildmenu')
11191119
<Left> select the previous match / move up to parent
11201120
<Right> select the next match / move down to submenu
11211121
<CR> move into submenu when doing menu completion
1122+
CTRL-E stop completion and go back to original text
1123+
CTRL-Y accept selected match and stop completion
11221124
other stop completion and insert the typed character
11231125

11241126
commands in wildmenu mode with 'wildoptions' set to "pum"
11251127

1126-
CTRL-E stop completion and go back to original text
1127-
CTRL-Y accept selected match and stop completion
11281128
<PageUp> select a match several entries back
11291129
<PageDown> select a match several entries forward
11301130

runtime/doc/options.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9323,6 +9323,10 @@ A jump table for the options with a short description can be found at |Q_op|.
93239323
CTRL-N - go to the next entry
93249324
<CR> - in menu completion, when the cursor is just after a
93259325
dot: move into a submenu.
9326+
CTRL-E - end completion, go back to what was there before
9327+
selecting a match.
9328+
CTRL-Y - accept the currently selected match and stop
9329+
completion.
93269330

93279331
When not using the popup menu for command line completion, the
93289332
following keys have special meanings:
@@ -9341,10 +9345,6 @@ A jump table for the options with a short description can be found at |Q_op|.
93419345
parent directory or parent menu.
93429346
<Right> - in filename/menu name completion: move into a
93439347
subdirectory or submenu.
9344-
CTRL-E - end completion, go back to what was there before
9345-
selecting a match.
9346-
CTRL-Y - accept the currently selected match and stop
9347-
completion.
93489348

93499349
This makes the menus accessible from the console |console-menus|.
93509350

src/cmdexpand.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ nextwild(
260260
{
261261
if (cmdline_fuzzy_completion_supported(xp))
262262
// If fuzzy matching, don't modify the search string
263-
p1 = vim_strsave(xp->xp_pattern);
263+
p1 = vim_strnsave(xp->xp_pattern, xp->xp_pattern_len);
264264
else
265265
p1 = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
266266

src/ex_docmd.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5590,7 +5590,8 @@ expand_argopt(
55905590

55915591
// Special handling of "ff" which acts as a short form of
55925592
// "fileformat", as "ff" is not a substring of it.
5593-
if (STRCMP(xp->xp_pattern, "ff") == 0)
5593+
if (xp->xp_pattern_len == 2
5594+
&& STRNCMP(xp->xp_pattern, "ff", xp->xp_pattern_len) == 0)
55945595
{
55955596
*matches = ALLOC_MULT(char_u *, 1);
55965597
if (*matches == NULL)

src/ex_getln.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,7 +1599,7 @@ getcmdline_int(
15991599
cmdline_info_T save_ccline;
16001600
int did_save_ccline = FALSE;
16011601
int cmdline_type;
1602-
int wild_type;
1602+
int wild_type = 0;
16031603

16041604
// one recursion level deeper
16051605
++depth;
@@ -1878,7 +1878,7 @@ getcmdline_int(
18781878
c = wildmenu_translate_key(&ccline, c, &xpc, did_wild_list);
18791879

18801880
int key_is_wc = (c == p_wc && KeyTyped) || c == p_wcm;
1881-
if (cmdline_pum_active() && !key_is_wc)
1881+
if ((cmdline_pum_active() || did_wild_list) && !key_is_wc)
18821882
{
18831883
// Ctrl-Y: Accept the current selection and close the popup menu.
18841884
// Ctrl-E: cancel the cmdline popup menu and return the original
@@ -1889,7 +1889,6 @@ getcmdline_int(
18891889
if (nextwild(&xpc, wild_type, WILD_NO_BEEP,
18901890
firstc != '@') == FAIL)
18911891
break;
1892-
c = Ctrl_E;
18931892
}
18941893
}
18951894

@@ -2016,6 +2015,14 @@ getcmdline_int(
20162015

20172016
do_abbr = TRUE; // default: check for abbreviation
20182017

2018+
// If already used to cancel/accept wildmenu, don't process the key
2019+
// further.
2020+
if (wild_type == WILD_CANCEL || wild_type == WILD_APPLY)
2021+
{
2022+
wild_type = 0;
2023+
goto cmdline_not_changed;
2024+
}
2025+
20192026
/*
20202027
* Big switch for a typed command line character.
20212028
*/

src/optionstr.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2582,12 +2582,13 @@ expand_set_highlight(optexpand_T *args, int *numMatches, char_u ***matches)
25822582
if (*matches == NULL)
25832583
return FAIL;
25842584

2585-
size_t pattern_len = STRLEN(xp->xp_pattern);
2585+
int pattern_len = xp->xp_pattern_len;
25862586

25872587
for (i = 0; i < num_hl_modes; i++)
25882588
{
25892589
// Don't allow duplicates as these are unique flags
2590-
if (vim_strchr(xp->xp_pattern + 1, p_hl_mode_values[i]) != NULL)
2590+
char_u *dup = vim_strchr(xp->xp_pattern + 1, p_hl_mode_values[i]);
2591+
if (dup != NULL && (int)(dup - xp->xp_pattern) < pattern_len)
25912592
continue;
25922593

25932594
// ':' only works by itself, not with other flags.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
| +0&#ffffff0@74
2+
|~+0#4040ff13&| @73
3+
|~| @73
4+
|~| @73
5+
|~| @73
6+
|~| @73
7+
|~| @73
8+
|~| @2| +0#0000001#e0e0e08|w|i|l|d|c|h|a|r| @6| +0#4040ff13#ffffff0@54
9+
|~| @2| +0#0000001#ffd7ff255|w|i|l|d|c|h|a|r|m| @5| +0#4040ff13#ffffff0@54
10+
|:+0#0000000&|s|e|t| |w|i|l|d|c|h|a|r>z@1| @59
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
| +0&#ffffff0@74
2+
|~+0#4040ff13&| @73
3+
|~| @73
4+
|~| @73
5+
|~| @73
6+
|~| @73
7+
|~| @73
8+
|~| @73
9+
|~| @73
10+
|:+0#0000000&|s|e|t| |w|i|l|d|c|h|a>z@1| @60
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
| +0&#ffffff0@74
2+
|~+0#4040ff13&| @73
3+
|~| @73
4+
|~| @73
5+
|~| @73
6+
|~| @73
7+
|~| @73
8+
|~| @73
9+
|~| @73
10+
|:+0#0000000&|s|e|t| |w|i|l|d|c|h|a|r>z@1| @59

src/testdir/test_cmdline.vim

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,13 @@ func Test_complete_wildmenu()
158158
call feedkeys(":sign \<Tab>\<PageUp>\<Left>\<Right>\<C-A>\<C-B>\"\<CR>", 'tx')
159159
call assert_equal('"TestWildMenu', @:)
160160

161+
" Test for Ctrl-E/Ctrl-Y being able to cancel / accept a match
162+
call feedkeys(":sign un zz\<Left>\<Left>\<Left>\<Tab>\<C-E> yy\<C-B>\"\<CR>", 'tx')
163+
call assert_equal('"sign un yy zz', @:)
164+
165+
call feedkeys(":sign un zz\<Left>\<Left>\<Left>\<Tab>\<Tab>\<C-Y> yy\<C-B>\"\<CR>", 'tx')
166+
call assert_equal('"sign unplace yy zz', @:)
167+
161168
" cleanup
162169
%bwipe
163170
set nowildmenu
@@ -1105,6 +1112,9 @@ func Test_cmdline_complete_argopt()
11051112
call assert_equal('edit', getcompletion('read ++bin ++edi', 'cmdline')[0])
11061113

11071114
call assert_equal(['fileformat='], getcompletion('edit ++ff', 'cmdline'))
1115+
" Test ++ff in the middle of the cmdline
1116+
call feedkeys(":edit ++ff zz\<Left>\<Left>\<Left>\<C-A>\<C-B>\"\<CR>", 'xt')
1117+
call assert_equal("\"edit ++fileformat= zz", @:)
11081118

11091119
call assert_equal('dos', getcompletion('write ++ff=d', 'cmdline')[0])
11101120
call assert_equal('mac', getcompletion('args ++fileformat=m', 'cmdline')[0])
@@ -2585,6 +2595,16 @@ func Test_wildmenu_pum()
25852595
call term_sendkeys(buf, "\<PageUp>")
25862596
call VerifyScreenDump(buf, 'Test_wildmenu_pum_50', {})
25872597

2598+
" pressing <C-E> to end completion should work in middle of the line too
2599+
call term_sendkeys(buf, "\<Esc>:set wildchazz\<Left>\<Left>\<Tab>")
2600+
call VerifyScreenDump(buf, 'Test_wildmenu_pum_51', {})
2601+
call term_sendkeys(buf, "\<C-E>")
2602+
call VerifyScreenDump(buf, 'Test_wildmenu_pum_52', {})
2603+
2604+
" pressing <C-Y> should select the current match and end completion
2605+
call term_sendkeys(buf, "\<Esc>:set wildchazz\<Left>\<Left>\<Tab>\<C-Y>")
2606+
call VerifyScreenDump(buf, 'Test_wildmenu_pum_53', {})
2607+
25882608
call term_sendkeys(buf, "\<C-U>\<CR>")
25892609
call StopVimInTerminal(buf)
25902610
endfunc
@@ -3293,6 +3313,17 @@ func Test_fuzzy_completion_custom_func()
32933313
set wildoptions&
32943314
endfunc
32953315

3316+
" Test for fuzzy completion in the middle of a cmdline instead of at the end
3317+
func Test_fuzzy_completion_in_middle()
3318+
set wildoptions=fuzzy
3319+
call feedkeys(":set ildar wrap\<Left>\<Left>\<Left>\<Left>\<Left>\<C-A>\<C-B>\"\<CR>", 'tx')
3320+
call assert_equal("\"set wildchar wildcharm wrap", @:)
3321+
3322+
call feedkeys(":args ++odng zz\<Left>\<Left>\<Left>\<C-A>\<C-B>\"\<CR>", 'tx')
3323+
call assert_equal("\"args ++encoding= zz", @:)
3324+
set wildoptions&
3325+
endfunc
3326+
32963327
" Test for :breakadd argument completion
32973328
func Test_cmdline_complete_breakadd()
32983329
call feedkeys(":breakadd \<C-A>\<C-B>\"\<CR>", 'tx')

0 commit comments

Comments
 (0)