mirror of
https://github.com/neovim/neovim.git
synced 2026-01-30 00:52:52 +10:00
Merge pull request #33565 from zeertzjq/vim-9.1.1329
vim-patch:9.1.{1329,1331,1338}
This commit is contained in:
@@ -400,6 +400,16 @@ CmdlineLeave Before leaving the command-line (including
|
||||
Note: `abort` can only be changed from false
|
||||
to true: cannot execute an already aborted
|
||||
cmdline by changing it to false.
|
||||
*CmdlineLeavePre*
|
||||
CmdlineLeavePre Just before leaving the command line, and
|
||||
before |CmdlineLeave|. Useful for capturing
|
||||
completion info with |cmdcomplete_info()|, as
|
||||
this information is cleared before
|
||||
|CmdlineLeave| is triggered. Triggered for
|
||||
non-interactive use of ":" in a mapping, but
|
||||
not when using |<Cmd>|. Also triggered when
|
||||
abandoning the command line by typing CTRL-C
|
||||
or <Esc>. <afile> is set to |cmdline-char|.
|
||||
*CmdwinEnter*
|
||||
CmdwinEnter After entering the command-line window.
|
||||
Useful for setting options specifically for
|
||||
|
||||
23
runtime/doc/builtin.txt
generated
23
runtime/doc/builtin.txt
generated
@@ -1061,6 +1061,29 @@ clearmatches([{win}]) *clearmatches()*
|
||||
Parameters: ~
|
||||
• {win} (`integer?`)
|
||||
|
||||
cmdcomplete_info() *cmdcomplete_info()*
|
||||
Returns a |Dictionary| with information about cmdline
|
||||
completion. See |cmdline-completion|.
|
||||
The items are:
|
||||
cmdline_orig The original command-line string before
|
||||
completion began.
|
||||
pum_visible |TRUE| if popup menu is visible.
|
||||
See |pumvisible()|.
|
||||
matches List of all completion candidates. Each item
|
||||
is a string.
|
||||
selected Selected item index. First index is zero.
|
||||
Index is -1 if no item is selected (showing
|
||||
typed text only, or the last completion after
|
||||
no item is selected when using the <Up> or
|
||||
<Down> keys)
|
||||
|
||||
Returns an empty |Dictionary| if no completion was attempted,
|
||||
if there was only one candidate and it was fully completed, or
|
||||
if an error occurred.
|
||||
|
||||
Return: ~
|
||||
(`table<string,any>`)
|
||||
|
||||
col({expr} [, {winid}]) *col()*
|
||||
The result is a Number, which is the byte index of the column
|
||||
position given with {expr}.
|
||||
|
||||
@@ -122,7 +122,7 @@ EDITOR
|
||||
|
||||
EVENTS
|
||||
|
||||
• todo
|
||||
• |CmdlineLeavePre| triggered before preparing to leave the command line.
|
||||
|
||||
HIGHLIGHTS
|
||||
|
||||
@@ -180,7 +180,7 @@ UI
|
||||
|
||||
VIMSCRIPT
|
||||
|
||||
• todo
|
||||
• |cmdcomplete_info()| gets current cmdline completion info.
|
||||
|
||||
==============================================================================
|
||||
CHANGED FEATURES *news-changed*
|
||||
|
||||
@@ -921,6 +921,7 @@ Command line: *command-line-functions*
|
||||
getcmdwintype() return the current command-line window type
|
||||
getcompletion() list of command-line completion matches
|
||||
fullcommand() get full command name
|
||||
cmdcomplete_info() get command-line completion information
|
||||
|
||||
Quickfix and location lists: *quickfix-functions*
|
||||
getqflist() list of quickfix errors
|
||||
|
||||
22
runtime/lua/vim/_meta/vimfn.lua
generated
22
runtime/lua/vim/_meta/vimfn.lua
generated
@@ -919,6 +919,28 @@ function vim.fn.cindent(lnum) end
|
||||
--- @param win? integer
|
||||
function vim.fn.clearmatches(win) end
|
||||
|
||||
--- Returns a |Dictionary| with information about cmdline
|
||||
--- completion. See |cmdline-completion|.
|
||||
--- The items are:
|
||||
--- cmdline_orig The original command-line string before
|
||||
--- completion began.
|
||||
--- pum_visible |TRUE| if popup menu is visible.
|
||||
--- See |pumvisible()|.
|
||||
--- matches List of all completion candidates. Each item
|
||||
--- is a string.
|
||||
--- selected Selected item index. First index is zero.
|
||||
--- Index is -1 if no item is selected (showing
|
||||
--- typed text only, or the last completion after
|
||||
--- no item is selected when using the <Up> or
|
||||
--- <Down> keys)
|
||||
---
|
||||
--- Returns an empty |Dictionary| if no completion was attempted,
|
||||
--- if there was only one candidate and it was fully completed, or
|
||||
--- if an error occurred.
|
||||
---
|
||||
--- @return table<string,any>
|
||||
function vim.fn.cmdcomplete_info() end
|
||||
|
||||
--- The result is a Number, which is the byte index of the column
|
||||
--- position given with {expr}.
|
||||
--- For accepted positions see |getpos()|.
|
||||
|
||||
@@ -29,6 +29,7 @@ return {
|
||||
CmdlineChanged = false, -- command line was modified
|
||||
CmdlineEnter = false, -- after entering cmdline mode
|
||||
CmdlineLeave = false, -- before leaving cmdline mode
|
||||
CmdlineLeavePre = false, -- just before leaving the command line
|
||||
CmdwinEnter = false, -- after entering the cmdline window
|
||||
CmdwinLeave = false, -- before leaving the cmdline window
|
||||
ColorScheme = false, -- after loading a colorscheme
|
||||
|
||||
@@ -1726,6 +1726,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|
||||
// Don't try expanding the following events.
|
||||
if (event == EVENT_CMDLINECHANGED
|
||||
|| event == EVENT_CMDLINEENTER
|
||||
|| event == EVENT_CMDLINELEAVEPRE
|
||||
|| event == EVENT_CMDLINELEAVE
|
||||
|| event == EVENT_CMDUNDEFINED
|
||||
|| event == EVENT_CURSORMOVEDC
|
||||
|
||||
@@ -91,6 +91,8 @@ static int compl_match_arraysize;
|
||||
/// First column in cmdline of the matched item for completion.
|
||||
static int compl_startcol;
|
||||
static int compl_selected;
|
||||
/// cmdline before expansion
|
||||
static char *cmdline_orig = NULL;
|
||||
|
||||
#define SHOW_MATCH(m) (showtail ? showmatches_gettail(matches[m], false) : matches[m])
|
||||
|
||||
@@ -401,6 +403,7 @@ void cmdline_pum_remove(void)
|
||||
{
|
||||
pum_undisplay(true);
|
||||
XFREE_CLEAR(compl_match_array);
|
||||
compl_match_arraysize = 0;
|
||||
}
|
||||
|
||||
void cmdline_pum_cleanup(CmdlineInfo *cclp)
|
||||
@@ -979,6 +982,11 @@ void ExpandCleanup(expand_T *xp)
|
||||
XFREE_CLEAR(xp->xp_orig);
|
||||
}
|
||||
|
||||
void clear_cmdline_orig(void)
|
||||
{
|
||||
XFREE_CLEAR(cmdline_orig);
|
||||
}
|
||||
|
||||
/// Display one line of completion matches. Multiple matches are displayed in
|
||||
/// each line (used by wildmode=list and CTRL-D)
|
||||
///
|
||||
@@ -1059,6 +1067,12 @@ int showmatches(expand_T *xp, bool wildmenu)
|
||||
int columns;
|
||||
bool showtail;
|
||||
|
||||
// Save cmdline before expansion
|
||||
if (ccline->cmdbuff != NULL) {
|
||||
xfree(cmdline_orig);
|
||||
cmdline_orig = xstrnsave(ccline->cmdbuff, (size_t)ccline->cmdlen);
|
||||
}
|
||||
|
||||
if (xp->xp_numfiles == -1) {
|
||||
set_expand_context(xp);
|
||||
if (xp->xp_context == EXPAND_LUA) {
|
||||
@@ -3653,3 +3667,30 @@ theend:
|
||||
xfree(pat);
|
||||
ExpandCleanup(&xpc);
|
||||
}
|
||||
|
||||
/// "cmdcomplete_info()" function
|
||||
void f_cmdcomplete_info(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
CmdlineInfo *ccline = get_cmdline_info();
|
||||
|
||||
tv_dict_alloc_ret(rettv);
|
||||
if (ccline == NULL || ccline->xpc == NULL || ccline->xpc->xp_files == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
dict_T *retdict = rettv->vval.v_dict;
|
||||
int ret = tv_dict_add_str(retdict, S_LEN("cmdline_orig"), cmdline_orig);
|
||||
if (ret == OK) {
|
||||
ret = tv_dict_add_nr(retdict, S_LEN("pum_visible"), pum_visible());
|
||||
}
|
||||
if (ret == OK) {
|
||||
ret = tv_dict_add_nr(retdict, S_LEN("selected"), ccline->xpc->xp_selected);
|
||||
}
|
||||
if (ret == OK) {
|
||||
list_T *li = tv_list_alloc(ccline->xpc->xp_numfiles);
|
||||
ret = tv_dict_add_list(retdict, S_LEN("matches"), li);
|
||||
for (int idx = 0; ret == OK && idx < ccline->xpc->xp_numfiles; idx++) {
|
||||
tv_list_append_string(li, ccline->xpc->xp_files[idx], -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1254,6 +1254,33 @@ M.funcs = {
|
||||
returns = false,
|
||||
signature = 'clearmatches([{win}])',
|
||||
},
|
||||
cmdcomplete_info = {
|
||||
args = 0,
|
||||
desc = [=[
|
||||
Returns a |Dictionary| with information about cmdline
|
||||
completion. See |cmdline-completion|.
|
||||
The items are:
|
||||
cmdline_orig The original command-line string before
|
||||
completion began.
|
||||
pum_visible |TRUE| if popup menu is visible.
|
||||
See |pumvisible()|.
|
||||
matches List of all completion candidates. Each item
|
||||
is a string.
|
||||
selected Selected item index. First index is zero.
|
||||
Index is -1 if no item is selected (showing
|
||||
typed text only, or the last completion after
|
||||
no item is selected when using the <Up> or
|
||||
<Down> keys)
|
||||
|
||||
Returns an empty |Dictionary| if no completion was attempted,
|
||||
if there was only one candidate and it was fully completed, or
|
||||
if an error occurred.
|
||||
]=],
|
||||
name = 'cmdcomplete_info',
|
||||
params = {},
|
||||
returns = 'table<string,any>',
|
||||
signature = 'cmdcomplete_info()',
|
||||
},
|
||||
col = {
|
||||
args = { 1, 2 },
|
||||
base = 1,
|
||||
|
||||
@@ -745,6 +745,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
|
||||
|
||||
ExpandInit(&s->xpc);
|
||||
ccline.xpc = &s->xpc;
|
||||
clear_cmdline_orig();
|
||||
|
||||
cmdmsg_rl = (curwin->w_p_rl && *curwin->w_p_rlc == 's'
|
||||
&& (s->firstc == '/' || s->firstc == '?'));
|
||||
@@ -901,6 +902,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
|
||||
|
||||
ExpandCleanup(&s->xpc);
|
||||
ccline.xpc = NULL;
|
||||
clear_cmdline_orig();
|
||||
|
||||
finish_incsearch_highlighting(s->gotesc, &s->is_state, false);
|
||||
|
||||
@@ -1301,6 +1303,12 @@ static int command_line_execute(VimState *state, int key)
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger CmdlineLeavePre autocommand
|
||||
if (s->c == '\n' || s->c == '\r' || s->c == K_KENTER
|
||||
|| s->c == ESC || s->c == Ctrl_C) {
|
||||
trigger_cmd_autocmd(get_cmdline_type(), EVENT_CMDLINELEAVEPRE);
|
||||
}
|
||||
|
||||
// The wildmenu is cleared if the pressed key is not used for
|
||||
// navigating the wild menu (i.e. the key is not 'wildchar' or
|
||||
// 'wildcharm' or Ctrl-N or Ctrl-P or Ctrl-A or Ctrl-L).
|
||||
|
||||
@@ -1921,6 +1921,53 @@ func Test_QuitPre()
|
||||
bwipe Xbar
|
||||
endfunc
|
||||
|
||||
func Test_Cmdline_Trigger()
|
||||
autocmd CmdlineLeavePre : let g:log = "CmdlineLeavePre"
|
||||
new
|
||||
let g:log = ''
|
||||
nnoremap <F1> <Cmd>echo "hello"<CR>
|
||||
call feedkeys("\<F1>", 'x')
|
||||
call assert_equal('', g:log)
|
||||
nunmap <F1>
|
||||
let g:log = ''
|
||||
nnoremap <F1> :echo "hello"<CR>
|
||||
call feedkeys("\<F1>", 'x')
|
||||
call assert_equal('CmdlineLeavePre', g:log)
|
||||
nunmap <F1>
|
||||
let g:log = ''
|
||||
split
|
||||
call assert_equal('', g:log)
|
||||
call feedkeys(":echo hello", "tx")
|
||||
call assert_equal('CmdlineLeavePre', g:log)
|
||||
let g:log = ''
|
||||
close
|
||||
call assert_equal('', g:log)
|
||||
call feedkeys(":echo hello", "tx")
|
||||
call assert_equal('CmdlineLeavePre', g:log)
|
||||
let g:log = ''
|
||||
tabnew
|
||||
call assert_equal('', g:log)
|
||||
call feedkeys(":echo hello", "tx")
|
||||
call assert_equal('CmdlineLeavePre', g:log)
|
||||
let g:log = ''
|
||||
split
|
||||
call assert_equal('', g:log)
|
||||
call feedkeys(":echo hello", "tx")
|
||||
call assert_equal('CmdlineLeavePre', g:log)
|
||||
let g:log = ''
|
||||
tabclose
|
||||
call assert_equal('', g:log)
|
||||
call feedkeys(":echo hello", "tx")
|
||||
call assert_equal('CmdlineLeavePre', g:log)
|
||||
let g:count = 0
|
||||
autocmd CmdlineLeavePre * let g:count += 1
|
||||
call feedkeys(":let c = input('? ')\<cr>B\<cr>", "tx")
|
||||
call assert_equal(2, g:count)
|
||||
unlet! g:count
|
||||
unlet! g:log
|
||||
bw!
|
||||
endfunc
|
||||
|
||||
func Test_Cmdline()
|
||||
au! CmdlineChanged : let g:text = getcmdline()
|
||||
let g:text = 0
|
||||
@@ -1994,13 +2041,17 @@ func Test_Cmdline()
|
||||
|
||||
au! CmdlineEnter : let g:entered = expand('<afile>')
|
||||
au! CmdlineLeave : let g:left = expand('<afile>')
|
||||
au! CmdlineLeavePre : let g:leftpre = expand('<afile>')
|
||||
let g:entered = 0
|
||||
let g:left = 0
|
||||
let g:leftpre = 0
|
||||
call feedkeys(":echo 'hello'\<CR>", 'xt')
|
||||
call assert_equal(':', g:entered)
|
||||
call assert_equal(':', g:left)
|
||||
call assert_equal(':', g:leftpre)
|
||||
au! CmdlineEnter
|
||||
au! CmdlineLeave
|
||||
au! CmdlineLeavePre
|
||||
|
||||
let save_shellslash = &shellslash
|
||||
" Nvim doesn't allow setting value of a hidden option to non-default value
|
||||
@@ -2009,18 +2060,38 @@ func Test_Cmdline()
|
||||
endif
|
||||
au! CmdlineEnter / let g:entered = expand('<afile>')
|
||||
au! CmdlineLeave / let g:left = expand('<afile>')
|
||||
au! CmdlineLeavePre / let g:leftpre = expand('<afile>')
|
||||
let g:entered = 0
|
||||
let g:left = 0
|
||||
let g:leftpre = 0
|
||||
new
|
||||
call setline(1, 'hello')
|
||||
call feedkeys("/hello\<CR>", 'xt')
|
||||
call assert_equal('/', g:entered)
|
||||
call assert_equal('/', g:left)
|
||||
call assert_equal('/', g:leftpre)
|
||||
bwipe!
|
||||
au! CmdlineEnter
|
||||
au! CmdlineLeave
|
||||
au! CmdlineLeavePre
|
||||
let &shellslash = save_shellslash
|
||||
|
||||
let g:left = "cancelled"
|
||||
let g:leftpre = "cancelled"
|
||||
au! CmdlineLeave : let g:left = "triggered"
|
||||
au! CmdlineLeavePre : let g:leftpre = "triggered"
|
||||
call feedkeys(":echo 'hello'\<esc>", 'xt')
|
||||
call assert_equal('triggered', g:left)
|
||||
call assert_equal('triggered', g:leftpre)
|
||||
let g:left = "cancelled"
|
||||
let g:leftpre = "cancelled"
|
||||
au! CmdlineLeave : let g:left = "triggered"
|
||||
call feedkeys(":echo 'hello'\<c-c>", 'xt')
|
||||
call assert_equal('triggered', g:left)
|
||||
call assert_equal('triggered', g:leftpre)
|
||||
au! CmdlineLeave
|
||||
au! CmdlineLeavePre
|
||||
|
||||
au! CursorMovedC : let g:pos += [getcmdpos()]
|
||||
let g:pos = []
|
||||
call feedkeys(":foo bar baz\<C-W>\<C-W>\<C-W>\<Esc>", 'xt')
|
||||
|
||||
@@ -4287,4 +4287,50 @@ func Test_cd_bslash_completion_windows()
|
||||
let &shellslash = save_shellslash
|
||||
endfunc
|
||||
|
||||
" Test cmdcomplete_info() with CmdlineLeavePre autocmd
|
||||
func Test_cmdcomplete_info()
|
||||
augroup test_CmdlineLeavePre
|
||||
autocmd!
|
||||
" Calling expand() should not interfere with cmdcomplete_info().
|
||||
autocmd CmdlineLeavePre * call expand('test_cmdline.*')
|
||||
autocmd CmdlineLeavePre * let g:cmdcomplete_info = string(cmdcomplete_info())
|
||||
augroup END
|
||||
new
|
||||
call assert_equal({}, cmdcomplete_info())
|
||||
call feedkeys(":h echom\<cr>", "tx") " No expansion
|
||||
call assert_equal('{}', g:cmdcomplete_info)
|
||||
call feedkeys(":h echoms\<tab>\<cr>", "tx")
|
||||
call assert_equal('{''cmdline_orig'': '''', ''pum_visible'': 0, ''matches'': [], ''selected'': 0}', g:cmdcomplete_info)
|
||||
call feedkeys(":h echom\<tab>\<cr>", "tx")
|
||||
call assert_equal(
|
||||
\ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 0, ''matches'': ['':echom'', '':echomsg''], ''selected'': 0}',
|
||||
\ g:cmdcomplete_info)
|
||||
call feedkeys(":h echom\<tab>\<tab>\<cr>", "tx")
|
||||
call assert_equal(
|
||||
\ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 0, ''matches'': ['':echom'', '':echomsg''], ''selected'': 1}',
|
||||
\ g:cmdcomplete_info)
|
||||
call feedkeys(":h echom\<tab>\<tab>\<tab>\<cr>", "tx")
|
||||
call assert_equal(
|
||||
\ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 0, ''matches'': ['':echom'', '':echomsg''], ''selected'': -1}',
|
||||
\ g:cmdcomplete_info)
|
||||
|
||||
set wildoptions=pum
|
||||
call feedkeys(":h echoms\<tab>\<cr>", "tx")
|
||||
call assert_equal('{''cmdline_orig'': '''', ''pum_visible'': 0, ''matches'': [], ''selected'': 0}', g:cmdcomplete_info)
|
||||
call feedkeys(":h echom\<tab>\<cr>", "tx")
|
||||
call assert_equal(
|
||||
\ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 1, ''matches'': ['':echom'', '':echomsg''], ''selected'': 0}',
|
||||
\ g:cmdcomplete_info)
|
||||
call feedkeys(":h echom\<tab>\<tab>\<cr>", "tx")
|
||||
call assert_equal(
|
||||
\ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 1, ''matches'': ['':echom'', '':echomsg''], ''selected'': 1}',
|
||||
\ g:cmdcomplete_info)
|
||||
call feedkeys(":h echom\<tab>\<tab>\<tab>\<cr>", "tx")
|
||||
call assert_equal(
|
||||
\ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 1, ''matches'': ['':echom'', '':echomsg''], ''selected'': -1}',
|
||||
\ g:cmdcomplete_info)
|
||||
bw!
|
||||
set wildoptions&
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
Reference in New Issue
Block a user