From e3eb6967bcce6a7f82639aa9d2e925080804026d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 21 Aug 2022 21:31:25 +0800 Subject: vim-patch:8.2.4325: 'wildmenu' only shows few matches (#19876) Problem: 'wildmenu' only shows few matches. Solution: Add the "pum" option: use a popup menu to show the matches. (Yegappan Lakshmanan et al., closes vim/vim#9707) https://github.com/vim/vim/commit/3908ef5017a6b4425727013588f72cc7343199b9 Omit p_wmnu check in cmdline_pum_active() as it can cause problems. Omit vim_strchr() flags as that isn't really better than bitmasks. Omit key translations and document it in vim_diff.txt. --- src/nvim/cmdexpand.c | 8 +- src/nvim/eval/funcs.c | 2 +- src/nvim/ex_getln.c | 4 + src/nvim/testdir/test_cmdline.vim | 173 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 185 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index 56fc39c83d..e82e98ba4e 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -258,7 +258,7 @@ void cmdline_pum_display(bool changed_array) bool cmdline_pum_active(void) { - // return p_wmnu && pum_visible() && compl_match_array != NULL; + // compl_match_array != NULL should already imply pum_visible() in Nvim. return compl_match_array != NULL; } @@ -269,6 +269,12 @@ void cmdline_pum_remove(void) XFREE_CLEAR(compl_match_array); } +void cmdline_pum_cleanup(CmdlineInfo *cclp) +{ + cmdline_pum_remove(); + wildmenu_cleanup(cclp); +} + /// Do wildcard expansion on the string 'str'. /// Chars that should not be expanded must be preceded with a backslash. /// Return a pointer to allocated memory containing the new string. diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index e15244b515..9c3c859771 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -9633,7 +9633,7 @@ static void f_visualmode(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "wildmenumode()" function static void f_wildmenumode(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - if (wild_menu_showing || ((State & MODE_CMDLINE) && pum_visible())) { + if (wild_menu_showing || ((State & MODE_CMDLINE) && cmdline_pum_active())) { rettv->vval.v_number = 1; } } diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 5a5491c79e..a0bcccb5be 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -1801,6 +1801,10 @@ static int command_line_handle_key(CommandLineState *s) if (nextwild(&s->xpc, WILD_ALL, 0, s->firstc != '@') == FAIL) { break; } + if (cmdline_pum_active()) { + cmdline_pum_cleanup(&ccline); + s->xpc.xp_context = EXPAND_NOTHING; + } return command_line_changed(s); case Ctrl_L: diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index b9f027afb2..e10fd64560 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -1857,6 +1857,179 @@ func Test_recalling_cmdline() cunmap (save-cmdline) endfunc +" Test for using a popup menu for the command line completion matches +" (wildoptions=pum) +func Test_wildmenu_pum() + CheckRunVimInTerminal + + let commands =<< trim [CODE] + set wildmenu + set wildoptions=pum + set shm+=I + set noruler + set noshowcmd + [CODE] + call writefile(commands, 'Xtest') + + let buf = RunVimInTerminal('-S Xtest', #{rows: 10}) + + call term_sendkeys(buf, ":sign \") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_01', {}) + + call term_sendkeys(buf, "\\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_02', {}) + + call term_sendkeys(buf, "\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_03', {}) + + call term_sendkeys(buf, "\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_04', {}) + + call term_sendkeys(buf, "\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_05', {}) + + " pressing should end completion and go back to the original match + call term_sendkeys(buf, "\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_06', {}) + + " pressing should select the current match and end completion + call term_sendkeys(buf, "\\\\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_07', {}) + + " With 'wildmode' set to 'longest,full', completing a match should display + " the longest match, the wildmenu should not be displayed. + call term_sendkeys(buf, ":\set wildmode=longest,full\") + call TermWait(buf) + call term_sendkeys(buf, ":sign u\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_08', {}) + + " pressing should display the wildmenu + call term_sendkeys(buf, "\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_09', {}) + + " pressing second time should select the next entry in the menu + call term_sendkeys(buf, "\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_10', {}) + + call term_sendkeys(buf, ":\set wildmode=full\") + " " showing popup menu in different columns in the cmdline + call term_sendkeys(buf, ":sign define \") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_11', {}) + + call term_sendkeys(buf, " \") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_12', {}) + + call term_sendkeys(buf, " \") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_13', {}) + + " Directory name completion + call mkdir('Xdir/XdirA/XdirB', 'p') + call writefile([], 'Xdir/XfileA') + call writefile([], 'Xdir/XdirA/XfileB') + call writefile([], 'Xdir/XdirA/XdirB/XfileC') + + call term_sendkeys(buf, "\e Xdi\\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_14', {}) + + " Pressing on a directory name should go into that directory + call term_sendkeys(buf, "\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_15', {}) + + " Pressing on a directory name should go to the parent directory + call term_sendkeys(buf, "\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_16', {}) + + " Pressing when the popup menu is displayed should list all the + " matches and remove the popup menu + call term_sendkeys(buf, "\sign \\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_17', {}) + + " Pressing when the popup menu is displayed should remove the popup + " menu + call term_sendkeys(buf, "\sign \\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_18', {}) + + " Pressing should open the popup menu with the last entry selected + call term_sendkeys(buf, "\\:sign \\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_19', {}) + + " Pressing should close the popup menu and cancel the cmd line + call term_sendkeys(buf, "\\:sign \\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_20', {}) + + " Typing a character when the popup is open, should close the popup + call term_sendkeys(buf, ":sign \x") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_21', {}) + + " When the popup is open, entering the cmdline window should close the popup + call term_sendkeys(buf, "\sign \\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_22', {}) + call term_sendkeys(buf, ":q\") + + " After the last popup menu item, should show the original string + call term_sendkeys(buf, ":sign u\\\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_23', {}) + + " Use the popup menu for the command name + call term_sendkeys(buf, "\bu\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_24', {}) + + " Pressing the left arrow should remove the popup menu + call term_sendkeys(buf, "\\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_25', {}) + + " Pressing should remove the popup menu and erase the last character + call term_sendkeys(buf, "\\sign \\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_26', {}) + + " Pressing should remove the popup menu and erase the previous word + call term_sendkeys(buf, "\\sign \\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_27', {}) + + " Pressing should remove the popup menu and erase the entire line + call term_sendkeys(buf, "\\sign \\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_28', {}) + + " Using to cancel the popup menu and then pressing should recall + " the cmdline from history + call term_sendkeys(buf, "sign xyz\:sign \\\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_29', {}) + + call term_sendkeys(buf, "\\") + call StopVimInTerminal(buf) + call delete('Xtest') + call delete('Xdir', 'rf') +endfunc + " this was going over the end of IObuff func Test_report_error_with_composing() let caught = 'no' -- cgit