Merge pull request #32709 from deathbeam/vim-9.1.1166

vim-patch:9.1.{1166,1168}: 'wildmode' noselect
This commit is contained in:
zeertzjq
2025-03-04 06:41:41 +08:00
committed by GitHub
9 changed files with 105 additions and 19 deletions

View File

@@ -329,6 +329,7 @@ OPTIONS
• 'completeopt' flag "fuzzy" enables |fuzzy-matching| during |ins-completion|. • 'completeopt' flag "fuzzy" enables |fuzzy-matching| during |ins-completion|.
• 'completeopt' flag "preinsert" highlights text to be inserted. • 'completeopt' flag "preinsert" highlights text to be inserted.
• 'wildmode' flag "noselect" shows 'wildmenu' without selecting an entry.
• 'messagesopt' configures |:messages| and |hit-enter| prompt. • 'messagesopt' configures |:messages| and |hit-enter| prompt.
• 'tabclose' controls which tab page to focus when closing a tab page. • 'tabclose' controls which tab page to focus when closing a tab page.
• 'eventignorewin' to persistently ignore events in a window. • 'eventignorewin' to persistently ignore events in a window.

View File

@@ -7050,7 +7050,10 @@ A jump table for the options with a short description can be found at |Q_op|.
"lastused" When completing buffer names and more than one buffer "lastused" When completing buffer names and more than one buffer
matches, sort buffers by time last used (other than matches, sort buffers by time last used (other than
the current buffer). the current buffer).
When there is only a single match, it is fully completed in all cases. "noselect" Do not pre-select first menu item and start 'wildmenu'
if it is enabled.
When there is only a single match, it is fully completed in all cases
except when "noselect" is present.
Examples of useful colon-separated values: Examples of useful colon-separated values:
"longest:full" Like "longest", but also start 'wildmenu' if it is "longest:full" Like "longest", but also start 'wildmenu' if it is
@@ -7073,7 +7076,11 @@ A jump table for the options with a short description can be found at |Q_op|.
set wildmode=list,full set wildmode=list,full
< List all matches without completing, then each full match >vim < List all matches without completing, then each full match >vim
set wildmode=longest,list set wildmode=longest,list
< Complete longest common string, then list alternatives. < Complete longest common string, then list alternatives >vim
set wildmode=noselect:full
< Display 'wildmenu' without completing, then each full match >vim
set wildmode=noselect:lastused,full
< Same as above, but sort buffers by time last used.
More info here: |cmdline-completion|. More info here: |cmdline-completion|.
*'wildoptions'* *'wop'* *'wildoptions'* *'wop'*

View File

@@ -7691,7 +7691,10 @@ vim.go.wmnu = vim.go.wildmenu
--- "lastused" When completing buffer names and more than one buffer --- "lastused" When completing buffer names and more than one buffer
--- matches, sort buffers by time last used (other than --- matches, sort buffers by time last used (other than
--- the current buffer). --- the current buffer).
--- When there is only a single match, it is fully completed in all cases. --- "noselect" Do not pre-select first menu item and start 'wildmenu'
--- if it is enabled.
--- When there is only a single match, it is fully completed in all cases
--- except when "noselect" is present.
--- ---
--- Examples of useful colon-separated values: --- Examples of useful colon-separated values:
--- "longest:full" Like "longest", but also start 'wildmenu' if it is --- "longest:full" Like "longest", but also start 'wildmenu' if it is
@@ -7729,7 +7732,17 @@ vim.go.wmnu = vim.go.wildmenu
--- ```vim --- ```vim
--- set wildmode=longest,list --- set wildmode=longest,list
--- ``` --- ```
--- Complete longest common string, then list alternatives. --- Complete longest common string, then list alternatives
---
--- ```vim
--- set wildmode=noselect:full
--- ```
--- Display 'wildmenu' without completing, then each full match
---
--- ```vim
--- set wildmode=noselect:lastused,full
--- ```
--- Same as above, but sort buffers by time last used.
--- More info here: `cmdline-completion`. --- More info here: `cmdline-completion`.
--- ---
--- @type string --- @type string

View File

@@ -288,7 +288,7 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
p1 = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context); p1 = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
} }
// Translate string into pattern and expand it. // Translate string into pattern and expand it.
const int use_options = (options const int use_options = ((options & ~WILD_KEEP_SOLE_ITEM)
| WILD_HOME_REPLACE | WILD_HOME_REPLACE
| WILD_ADD_SLASH | WILD_ADD_SLASH
| WILD_SILENT | WILD_SILENT
@@ -339,7 +339,7 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
if (xp->xp_numfiles <= 0 && p2 == NULL) { if (xp->xp_numfiles <= 0 && p2 == NULL) {
beep_flush(); beep_flush();
} else if (xp->xp_numfiles == 1) { } else if (xp->xp_numfiles == 1 && !(options & WILD_KEEP_SOLE_ITEM)) {
// free expanded pattern // free expanded pattern
ExpandOne(xp, NULL, NULL, 0, WILD_FREE); ExpandOne(xp, NULL, NULL, 0, WILD_FREE);
} }

View File

@@ -40,6 +40,7 @@ enum {
WILD_NOERROR = 0x800, ///< sets EW_NOERROR WILD_NOERROR = 0x800, ///< sets EW_NOERROR
WILD_BUFLASTUSED = 0x1000, WILD_BUFLASTUSED = 0x1000,
BUF_DIFF_FILTER = 0x2000, BUF_DIFF_FILTER = 0x2000,
WILD_KEEP_SOLE_ITEM = 0x4000,
}; };
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS

View File

@@ -1082,6 +1082,9 @@ static int command_line_wildchar_complete(CommandLineState *s)
if (wim_flags[s->wim_index] & kOptWimFlagLastused) { if (wim_flags[s->wim_index] & kOptWimFlagLastused) {
options |= WILD_BUFLASTUSED; options |= WILD_BUFLASTUSED;
} }
if (wim_flags[0] & kOptWimFlagNoselect) {
options |= WILD_KEEP_SOLE_ITEM;
}
if (s->xpc.xp_numfiles > 0) { // typed p_wc at least twice if (s->xpc.xp_numfiles > 0) { // typed p_wc at least twice
// if 'wildmode' contains "list" may still need to list // if 'wildmode' contains "list" may still need to list
if (s->xpc.xp_numfiles > 1 if (s->xpc.xp_numfiles > 1
@@ -1124,19 +1127,20 @@ static int command_line_wildchar_complete(CommandLineState *s)
// when more than one match, and 'wildmode' first contains // when more than one match, and 'wildmode' first contains
// "list", or no change and 'wildmode' contains "longest,list", // "list", or no change and 'wildmode' contains "longest,list",
// list all matches // list all matches
if (res == OK && s->xpc.xp_numfiles > 1) { if (res == OK
&& s->xpc.xp_numfiles > ((wim_flags[s->wim_index] & kOptWimFlagNoselect) ? 0 : 1)) {
// a "longest" that didn't do anything is skipped (but not // a "longest" that didn't do anything is skipped (but not
// "list:longest") // "list:longest")
if (wim_flags[0] == kOptWimFlagLongest && ccline.cmdpos == j) { if (wim_flags[0] == kOptWimFlagLongest && ccline.cmdpos == j) {
s->wim_index = 1; s->wim_index = 1;
} }
if ((wim_flags[s->wim_index] & kOptWimFlagList) if ((wim_flags[s->wim_index] & kOptWimFlagList)
|| (p_wmnu && (wim_flags[s->wim_index] & kOptWimFlagFull) != 0)) { || (p_wmnu && (wim_flags[s->wim_index] & (kOptWimFlagFull|kOptWimFlagNoselect)))) {
if (!(wim_flags[0] & kOptWimFlagLongest)) { if (!(wim_flags[0] & kOptWimFlagLongest)) {
int p_wmnu_save = p_wmnu; int p_wmnu_save = p_wmnu;
p_wmnu = 0; p_wmnu = 0;
// remove match // remove match
nextwild(&s->xpc, WILD_PREV, 0, s->firstc != '@'); nextwild(&s->xpc, WILD_PREV, options, s->firstc != '@');
p_wmnu = p_wmnu_save; p_wmnu = p_wmnu_save;
} }
@@ -1146,7 +1150,8 @@ static int command_line_wildchar_complete(CommandLineState *s)
if (wim_flags[s->wim_index] & kOptWimFlagLongest) { if (wim_flags[s->wim_index] & kOptWimFlagLongest) {
nextwild(&s->xpc, WILD_LONGEST, options, s->firstc != '@'); nextwild(&s->xpc, WILD_LONGEST, options, s->firstc != '@');
} else if (wim_flags[s->wim_index] & kOptWimFlagFull) { } else if ((wim_flags[s->wim_index] & kOptWimFlagFull)
&& !(wim_flags[s->wim_index] & kOptWimFlagNoselect)) {
nextwild(&s->xpc, WILD_NEXT, options, s->firstc != '@'); nextwild(&s->xpc, WILD_NEXT, options, s->firstc != '@');
} }
} else { } else {
@@ -2875,6 +2880,8 @@ int check_opt_wim(void)
new_wim_flags[idx] |= kOptWimFlagList; new_wim_flags[idx] |= kOptWimFlagList;
} else if (i == 8 && strncmp(p, "lastused", 8) == 0) { } else if (i == 8 && strncmp(p, "lastused", 8) == 0) {
new_wim_flags[idx] |= kOptWimFlagLastused; new_wim_flags[idx] |= kOptWimFlagLastused;
} else if (i == 8 && strncmp(p, "noselect", 8) == 0) {
new_wim_flags[idx] |= kOptWimFlagNoselect;
} else { } else {
return FAIL; return FAIL;
} }

View File

@@ -10020,7 +10020,7 @@ local options = {
cb = 'did_set_wildmode', cb = 'did_set_wildmode',
defaults = 'full', defaults = 'full',
-- Keep this in sync with check_opt_wim(). -- Keep this in sync with check_opt_wim().
values = { 'full', 'longest', 'list', 'lastused' }, values = { 'full', 'longest', 'list', 'lastused', 'noselect' },
flags = true, flags = true,
deny_duplicates = false, deny_duplicates = false,
desc = [=[ desc = [=[
@@ -10042,7 +10042,10 @@ local options = {
"lastused" When completing buffer names and more than one buffer "lastused" When completing buffer names and more than one buffer
matches, sort buffers by time last used (other than matches, sort buffers by time last used (other than
the current buffer). the current buffer).
When there is only a single match, it is fully completed in all cases. "noselect" Do not pre-select first menu item and start 'wildmenu'
if it is enabled.
When there is only a single match, it is fully completed in all cases
except when "noselect" is present.
Examples of useful colon-separated values: Examples of useful colon-separated values:
"longest:full" Like "longest", but also start 'wildmenu' if it is "longest:full" Like "longest", but also start 'wildmenu' if it is
@@ -10065,7 +10068,11 @@ local options = {
set wildmode=list,full set wildmode=list,full
< List all matches without completing, then each full match >vim < List all matches without completing, then each full match >vim
set wildmode=longest,list set wildmode=longest,list
< Complete longest common string, then list alternatives. < Complete longest common string, then list alternatives >vim
set wildmode=noselect:full
< Display 'wildmenu' without completing, then each full match >vim
set wildmode=noselect:lastused,full
< Same as above, but sort buffers by time last used.
More info here: |cmdline-completion|. More info here: |cmdline-completion|.
]=], ]=],
full_name = 'wildmode', full_name = 'wildmode',

View File

@@ -352,6 +352,7 @@ let test_values = {
\ 'bs'], \ 'bs'],
\ ['xxx']], \ ['xxx']],
\ 'wildmode': [['', 'full', 'longest', 'list', 'lastused', 'list:full', \ 'wildmode': [['', 'full', 'longest', 'list', 'lastused', 'list:full',
\ 'noselect', 'noselect,full', 'noselect:lastused,full',
\ 'full,longest', 'full,full,full,full'], \ 'full,longest', 'full,full,full,full'],
\ ['xxx', 'a4', 'full,full,full,full,full']], \ ['xxx', 'a4', 'full,full,full,full,full']],
\ 'wildoptions': [['', 'tagfile', 'pum', 'fuzzy'], ['xxx']], \ 'wildoptions': [['', 'tagfile', 'pum', 'fuzzy'], ['xxx']],

View File

@@ -2168,22 +2168,58 @@ func Wildmode_tests()
call assert_equal('AAA AAAA AAAAA', g:Sline) call assert_equal('AAA AAAA AAAAA', g:Sline)
call assert_equal('"b A', @:) call assert_equal('"b A', @:)
" When 'wildmenu' is not set, 'noselect' completes first item
set wildmode=noselect
call feedkeys(":MyCmd o\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"MyCmd oneA', @:)
" When 'noselect' is present, do not complete first <tab>.
set wildmenu
set wildmode=noselect
call feedkeys(":MyCmd o\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"MyCmd o', @:)
call feedkeys(":MyCmd o\t\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"MyCmd o', @:)
call feedkeys(":MyCmd o\t\t\<C-Y>\<C-B>\"\<CR>", 'xt')
call assert_equal('"MyCmd o', @:)
" When 'full' is present, complete after first <tab>.
set wildmode=noselect,full
call feedkeys(":MyCmd o\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"MyCmd o', @:)
call feedkeys(":MyCmd o\t\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"MyCmd oneA', @:)
call feedkeys(":MyCmd o\t\t\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"MyCmd oneB', @:)
call feedkeys(":MyCmd o\t\t\t\<C-Y>\<C-B>\"\<CR>", 'xt')
call assert_equal('"MyCmd oneB', @:)
" 'noselect' has no effect when 'longest' is present.
set wildmode=noselect:longest
call feedkeys(":MyCmd o\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"MyCmd one', @:)
" Complete 'noselect' value in 'wildmode' option
set wildmode&
call feedkeys(":set wildmode=n\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"set wildmode=noselect', @:)
call feedkeys(":set wildmode=\t\t\t\t\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"set wildmode=noselect', @:)
" when using longest completion match, matches shorter than the argument " when using longest completion match, matches shorter than the argument
" should be ignored (happens with :help) " should be ignored (happens with :help)
set wildmode=longest,full set wildmode=longest,full
set wildmenu
call feedkeys(":help a*\t\<C-B>\"\<CR>", 'xt') call feedkeys(":help a*\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"help a', @:) call assert_equal('"help a', @:)
" non existing file " non existing file
call feedkeys(":e a1b2y3z4\t\<C-B>\"\<CR>", 'xt') call feedkeys(":e a1b2y3z4\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"e a1b2y3z4', @:) call assert_equal('"e a1b2y3z4', @:)
set wildmenu&
" Test for longest file name completion with 'fileignorecase' " Test for longest file name completion with 'fileignorecase'
" On MS-Windows, file names are case insensitive. " On MS-Windows, file names are case insensitive.
if has('unix') if has('unix')
call writefile([], 'XTESTfoo') call writefile([], 'XTESTfoo', 'D')
call writefile([], 'Xtestbar') call writefile([], 'Xtestbar', 'D')
set nofileignorecase set nofileignorecase
call feedkeys(":e XT\<Tab>\<C-B>\"\<CR>", 'xt') call feedkeys(":e XT\<Tab>\<C-B>\"\<CR>", 'xt')
call assert_equal('"e XTESTfoo', @:) call assert_equal('"e XTESTfoo', @:)
@@ -2195,10 +2231,23 @@ func Wildmode_tests()
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', @:)
set fileignorecase& set fileignorecase&
call delete('XTESTfoo')
call delete('Xtestbar')
endif endif
" If 'noselect' is present, single item menu should not insert item
func! T(a, c, p)
return "oneA"
endfunc
command! -nargs=1 -complete=custom,T MyCmd
set wildmode=noselect,full
call feedkeys(":MyCmd o\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"MyCmd o', @:)
call feedkeys(":MyCmd o\t\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"MyCmd oneA', @:)
" 'nowildmenu' should make 'noselect' ineffective
set nowildmenu
call feedkeys(":MyCmd o\t\<C-B>\"\<CR>", 'xt')
call assert_equal('"MyCmd oneA', @:)
%argdelete %argdelete
delcommand MyCmd delcommand MyCmd
delfunc T delfunc T