changeset 28109:06535d568f74 v8.2.4579

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 <yegappan@yahoo.com> 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)
author Bram Moolenaar <Bram@vim.org>
date Wed, 16 Mar 2022 14:45:04 +0100
parents 00e653cb7b22
children 4bcb871d7ccc
files src/cmdexpand.c src/ex_getln.c src/spellsuggest.c src/testdir/dumps/Test_wildmenu_pum_42.dump src/testdir/dumps/Test_wildmenu_pum_43.dump src/testdir/dumps/Test_wildmenu_pum_44.dump src/testdir/dumps/Test_wildmenu_pum_45.dump src/testdir/dumps/Test_wildmenu_pum_46.dump src/testdir/dumps/Test_wildmenu_pum_47.dump src/testdir/dumps/Test_wildmenu_pum_48.dump src/testdir/dumps/Test_wildmenu_pum_49.dump src/testdir/dumps/Test_wildmenu_pum_50.dump src/testdir/test_cmdline.vim src/version.c src/vim.h
diffstat 15 files changed, 213 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- 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)
--- 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
--- 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
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
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
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
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
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
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
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
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
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
--- 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 <F2>
 
+  " Test for canceling the wild menu by pressing <PageDown> or <PageUp>.
+  " After this pressing <Left> or <Right> should not change the selection.
+  call feedkeys(":sign \<Tab>\<PageDown>\<Left>\<Right>\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"sign define', @:)
+  call histadd('cmd', 'TestWildMenu')
+  call feedkeys(":sign \<Tab>\<PageUp>\<Left>\<Right>\<C-A>\<C-B>\"\<CR>", '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, "\<Esc>")
 
+  " Pressing <PageDown> should scroll the menu downward
+  call term_sendkeys(buf, ":sign \<Tab>\<PageDown>")
+  call VerifyScreenDump(buf, 'Test_wildmenu_pum_42', {})
+  call term_sendkeys(buf, "\<PageDown>")
+  call VerifyScreenDump(buf, 'Test_wildmenu_pum_43', {})
+  call term_sendkeys(buf, "\<PageDown>")
+  call VerifyScreenDump(buf, 'Test_wildmenu_pum_44', {})
+  call term_sendkeys(buf, "\<PageDown>")
+  call VerifyScreenDump(buf, 'Test_wildmenu_pum_45', {})
+  call term_sendkeys(buf, "\<C-U>sign \<Tab>\<Down>\<Down>\<PageDown>")
+  call VerifyScreenDump(buf, 'Test_wildmenu_pum_46', {})
+
+  " Pressing <PageUp> should scroll the menu upward
+  call term_sendkeys(buf, "\<C-U>sign \<Tab>\<PageUp>")
+  call VerifyScreenDump(buf, 'Test_wildmenu_pum_47', {})
+  call term_sendkeys(buf, "\<PageUp>")
+  call VerifyScreenDump(buf, 'Test_wildmenu_pum_48', {})
+  call term_sendkeys(buf, "\<PageUp>")
+  call VerifyScreenDump(buf, 'Test_wildmenu_pum_49', {})
+  call term_sendkeys(buf, "\<PageUp>")
+  call VerifyScreenDump(buf, 'Test_wildmenu_pum_50', {})
+
   call term_sendkeys(buf, "\<C-U>\<CR>")
   call StopVimInTerminal(buf)
   call delete('Xtest')
--- 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,
--- 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