# HG changeset patch # User Bram Moolenaar # Date 1647438304 -3600 # Node ID 06535d568f74072e574727ab9645e0312c8f25c7 # Parent 00e653cb7b228537bb8cc60a87185cfdc3eeabbf patch 8.2.4579: cannot use page-up and page-down in the cmdline popup menu Commit: https://github.com/vim/vim/commit/5cffa8df7e3c28681b9e5deef6df395784359b6b Author: Yegappan Lakshmanan Date: Wed Mar 16 13:33:53 2022 +0000 patch 8.2.4579: cannot use page-up and page-down in the cmdline popup menu Problem: Cannot use page-up and page-down in the command line completion popup menu. Solution: Check for to page-up and page-down keys. (Yegappan Lakshmanan, closes #9960) diff --git a/src/cmdexpand.c b/src/cmdexpand.c --- a/src/cmdexpand.c +++ b/src/cmdexpand.c @@ -224,7 +224,8 @@ nextwild( i = (int)(xp->xp_pattern - ccline->cmdbuff); xp->xp_pattern_len = ccline->cmdpos - i; - if (type == WILD_NEXT || type == WILD_PREV) + if (type == WILD_NEXT || type == WILD_PREV + || type == WILD_PAGEUP || type == WILD_PAGEDOWN) { // Get next/previous match for a previous expanded pattern. p2 = ExpandOne(xp, NULL, NULL, 0, type); @@ -404,7 +405,7 @@ int cmdline_compl_startcol(void) /* * Get the next or prev cmdline completion match. The index of the match is set - * in 'p_findex' + * in "p_findex" */ static char_u * get_next_or_prev_match( @@ -414,6 +415,7 @@ get_next_or_prev_match( char_u *orig_save) { int findex = *p_findex; + int ht; if (xp->xp_numfiles <= 0) return NULL; @@ -424,11 +426,50 @@ get_next_or_prev_match( findex = xp->xp_numfiles; --findex; } - else // mode == WILD_NEXT + else if (mode == WILD_NEXT) ++findex; - - // When wrapping around, return the original string, set findex to - // -1. + else if (mode == WILD_PAGEUP) + { + if (findex == 0) + // at the first entry, don't select any entries + findex = -1; + else if (findex == -1) + // no entry is selected. select the last entry + findex = xp->xp_numfiles - 1; + else + { + // go up by the pum height + ht = pum_get_height(); + if (ht > 3) + ht -= 2; + findex -= ht; + if (findex < 0) + // few entries left, select the first entry + findex = 0; + } + } + else // mode == WILD_PAGEDOWN + { + if (findex == xp->xp_numfiles - 1) + // at the last entry, don't select any entries + findex = -1; + else if (findex == -1) + // no entry is selected. select the first entry + findex = 0; + else + { + // go down by the pum height + ht = pum_get_height(); + if (ht > 3) + ht -= 2; + findex += ht; + if (findex >= xp->xp_numfiles) + // few entries left, select the last entry + findex = xp->xp_numfiles - 1; + } + } + + // When wrapping around, return the original string, set findex to -1. if (findex < 0) { if (orig_save == NULL) @@ -585,7 +626,7 @@ find_longest_match(expand_T *xp, int opt } /* - * Do wildcard expansion on the string 'str'. + * 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. * Return NULL for failure. @@ -639,7 +680,8 @@ ExpandOne( long_u len; // first handle the case of using an old match - if (mode == WILD_NEXT || mode == WILD_PREV) + if (mode == WILD_NEXT || mode == WILD_PREV + || mode == WILD_PAGEUP || mode == WILD_PAGEDOWN) return get_next_or_prev_match(mode, xp, &findex, orig_save); if (mode == WILD_CANCEL) diff --git a/src/ex_getln.c b/src/ex_getln.c --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -1757,6 +1757,7 @@ getcmdline_int( for (;;) { int trigger_cmdlinechanged = TRUE; + int end_wildmenu; redir_off = TRUE; // Don't redirect the typed command. // Repeated, because a ":redir" inside @@ -1878,10 +1879,21 @@ getcmdline_int( } #endif + // 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). + // If the popup menu is displayed, then PageDown and PageUp keys are + // also used to navigate the menu. + end_wildmenu = (!(c == p_wc && KeyTyped) && c != p_wcm + && c != Ctrl_N && c != Ctrl_P && c != Ctrl_A && c != Ctrl_L); +#ifdef FEAT_WILDMENU + end_wildmenu = end_wildmenu && (!cmdline_pum_active() || + (c != K_PAGEDOWN && c != K_PAGEUP + && c != K_KPAGEDOWN && c != K_KPAGEUP)); +#endif + // free expanded names when finished walking through matches - if (!(c == p_wc && KeyTyped) && c != p_wcm - && c != Ctrl_N && c != Ctrl_P && c != Ctrl_A - && c != Ctrl_L) + if (end_wildmenu) { #ifdef FEAT_WILDMENU if (cmdline_pum_active()) @@ -2306,12 +2318,29 @@ getcmdline_int( case K_KPAGEUP: case K_PAGEDOWN: case K_KPAGEDOWN: - res = cmdline_browse_history(c, firstc, &lookfor, histype, - &hiscnt, &xpc); - if (res == CMDLINE_CHANGED) - goto cmdline_changed; - else if (res == GOTO_NORMAL_MODE) - goto returncmd; +#ifdef FEAT_WILDMENU + if (cmdline_pum_active() + && (c == K_PAGEUP || c == K_PAGEDOWN || + c == K_KPAGEUP || c == K_KPAGEDOWN)) + { + // If the popup menu is displayed, then PageUp and PageDown + // are used to scroll the menu. + if (nextwild(&xpc, + (c == K_PAGEUP) ? WILD_PAGEUP : WILD_PAGEDOWN, + 0, firstc != '@') == FAIL) + break; + goto cmdline_not_changed; + } + else +#endif + { + res = cmdline_browse_history(c, firstc, &lookfor, histype, + &hiscnt, &xpc); + if (res == CMDLINE_CHANGED) + goto cmdline_changed; + else if (res == GOTO_NORMAL_MODE) + goto returncmd; + } goto cmdline_not_changed; #ifdef FEAT_SEARCH_EXTRA diff --git a/src/spellsuggest.c b/src/spellsuggest.c --- a/src/spellsuggest.c +++ b/src/spellsuggest.c @@ -509,7 +509,7 @@ spell_suggest(int count) // make sure we don't include the NUL at the end of the line line = ml_get_curline(); if (badlen > (int)STRLEN(line) - (int)curwin->w_cursor.col) - badlen = STRLEN(line) - curwin->w_cursor.col; + badlen = (int)STRLEN(line) - (int)curwin->w_cursor.col; } // Find the start of the badly spelled word. else if (spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL) == 0 diff --git a/src/testdir/dumps/Test_wildmenu_pum_42.dump b/src/testdir/dumps/Test_wildmenu_pum_42.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_pum_42.dump @@ -0,0 +1,10 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @3| +0#0000001#ffd7ff255|d|e|f|i|n|e| @8| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|j|u|m|p| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|l|i|s|t| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|p|l|a|c|e| @9| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#e0e0e08|u|n|d|e|f|i|n|e| @6| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|u|n|p|l|a|c|e| @7| +0#4040ff13#ffffff0@53 +|:+0#0000000&|s|i|g|n| |u|n|d|e|f|i|n|e> @60 diff --git a/src/testdir/dumps/Test_wildmenu_pum_43.dump b/src/testdir/dumps/Test_wildmenu_pum_43.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_pum_43.dump @@ -0,0 +1,10 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @3| +0#0000001#ffd7ff255|d|e|f|i|n|e| @8| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|j|u|m|p| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|l|i|s|t| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|p|l|a|c|e| @9| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|u|n|d|e|f|i|n|e| @6| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#e0e0e08|u|n|p|l|a|c|e| @7| +0#4040ff13#ffffff0@53 +|:+0#0000000&|s|i|g|n| |u|n|p|l|a|c|e> @61 diff --git a/src/testdir/dumps/Test_wildmenu_pum_44.dump b/src/testdir/dumps/Test_wildmenu_pum_44.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_pum_44.dump @@ -0,0 +1,10 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @3| +0#0000001#ffd7ff255|d|e|f|i|n|e| @8| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|j|u|m|p| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|l|i|s|t| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|p|l|a|c|e| @9| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|u|n|d|e|f|i|n|e| @6| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|u|n|p|l|a|c|e| @7| +0#4040ff13#ffffff0@53 +|:+0#0000000&|s|i|g|n| > @68 diff --git a/src/testdir/dumps/Test_wildmenu_pum_45.dump b/src/testdir/dumps/Test_wildmenu_pum_45.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_pum_45.dump @@ -0,0 +1,10 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @3| +0#0000001#e0e0e08|d|e|f|i|n|e| @8| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|j|u|m|p| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|l|i|s|t| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|p|l|a|c|e| @9| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|u|n|d|e|f|i|n|e| @6| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|u|n|p|l|a|c|e| @7| +0#4040ff13#ffffff0@53 +|:+0#0000000&|s|i|g|n| |d|e|f|i|n|e> @62 diff --git a/src/testdir/dumps/Test_wildmenu_pum_46.dump b/src/testdir/dumps/Test_wildmenu_pum_46.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_pum_46.dump @@ -0,0 +1,10 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @3| +0#0000001#ffd7ff255|d|e|f|i|n|e| @8| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|j|u|m|p| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|l|i|s|t| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|p|l|a|c|e| @9| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|u|n|d|e|f|i|n|e| @6| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#e0e0e08|u|n|p|l|a|c|e| @7| +0#4040ff13#ffffff0@53 +|:+0#0000000&|s|i|g|n| |u|n|p|l|a|c|e> @61 diff --git a/src/testdir/dumps/Test_wildmenu_pum_47.dump b/src/testdir/dumps/Test_wildmenu_pum_47.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_pum_47.dump @@ -0,0 +1,10 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @3| +0#0000001#ffd7ff255|d|e|f|i|n|e| @8| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|j|u|m|p| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|l|i|s|t| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|p|l|a|c|e| @9| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|u|n|d|e|f|i|n|e| @6| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|u|n|p|l|a|c|e| @7| +0#4040ff13#ffffff0@53 +|:+0#0000000&|s|i|g|n| > @68 diff --git a/src/testdir/dumps/Test_wildmenu_pum_48.dump b/src/testdir/dumps/Test_wildmenu_pum_48.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_pum_48.dump @@ -0,0 +1,10 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @3| +0#0000001#ffd7ff255|d|e|f|i|n|e| @8| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|j|u|m|p| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|l|i|s|t| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|p|l|a|c|e| @9| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|u|n|d|e|f|i|n|e| @6| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#e0e0e08|u|n|p|l|a|c|e| @7| +0#4040ff13#ffffff0@53 +|:+0#0000000&|s|i|g|n| |u|n|p|l|a|c|e> @61 diff --git a/src/testdir/dumps/Test_wildmenu_pum_49.dump b/src/testdir/dumps/Test_wildmenu_pum_49.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_pum_49.dump @@ -0,0 +1,10 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @3| +0#0000001#ffd7ff255|d|e|f|i|n|e| @8| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#e0e0e08|j|u|m|p| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|l|i|s|t| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|p|l|a|c|e| @9| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|u|n|d|e|f|i|n|e| @6| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|u|n|p|l|a|c|e| @7| +0#4040ff13#ffffff0@53 +|:+0#0000000&|s|i|g|n| |j|u|m|p> @64 diff --git a/src/testdir/dumps/Test_wildmenu_pum_50.dump b/src/testdir/dumps/Test_wildmenu_pum_50.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_pum_50.dump @@ -0,0 +1,10 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @3| +0#0000001#e0e0e08|d|e|f|i|n|e| @8| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|j|u|m|p| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|l|i|s|t| @10| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|p|l|a|c|e| @9| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|u|n|d|e|f|i|n|e| @6| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|u|n|p|l|a|c|e| @7| +0#4040ff13#ffffff0@53 +|:+0#0000000&|s|i|g|n| |d|e|f|i|n|e> @62 diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -152,6 +152,14 @@ func Test_complete_wildmenu() call assert_equal('"e Xdir1/Xdir2/1', @:) cunmap + " Test for canceling the wild menu by pressing or . + " After this pressing or should not change the selection. + call feedkeys(":sign \\\\\\\"\", 'tx') + call assert_equal('"sign define', @:) + call histadd('cmd', 'TestWildMenu') + call feedkeys(":sign \\\\\\\"\", 'tx') + call assert_equal('"TestWildMenu', @:) + " cleanup %bwipe call delete('Xdir1', 'rf') @@ -2416,6 +2424,28 @@ func Test_wildmenu_pum() call VerifyScreenDump(buf, 'Test_wildmenu_pum_41', {}) call term_sendkeys(buf, "\") + " Pressing should scroll the menu downward + call term_sendkeys(buf, ":sign \\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_42', {}) + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_43', {}) + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_44', {}) + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_45', {}) + call term_sendkeys(buf, "\sign \\\\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_46', {}) + + " Pressing should scroll the menu upward + call term_sendkeys(buf, "\sign \\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_47', {}) + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_48', {}) + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_49', {}) + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_50', {}) + call term_sendkeys(buf, "\\") call StopVimInTerminal(buf) call delete('Xtest') diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4579, +/**/ 4578, /**/ 4577, diff --git a/src/vim.h b/src/vim.h --- a/src/vim.h +++ b/src/vim.h @@ -818,6 +818,8 @@ extern int (*dyn_libintl_wputenv)(const #define WILD_ALL_KEEP 8 #define WILD_CANCEL 9 #define WILD_APPLY 10 +#define WILD_PAGEUP 11 +#define WILD_PAGEDOWN 12 #define WILD_LIST_NOTFOUND 0x01 #define WILD_HOME_REPLACE 0x02