@@ -254,6 +254,9 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
254254 CmdlineInfo * const ccline = get_cmdline_info ();
255255 char * p ;
256256 bool from_wildtrigger_func = options & WILD_FUNC_TRIGGER ;
257+ bool wild_navigate = (type == WILD_NEXT || type == WILD_PREV
258+ || type == WILD_PAGEUP || type == WILD_PAGEDOWN
259+ || type == WILD_PUM_WANT );
257260
258261 if (xp -> xp_numfiles == -1 ) {
259262 pre_incsearch_pos = xp -> xp_pre_incsearch_pos ;
@@ -292,15 +295,13 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
292295
293296 // If cmd_silent is set then don't show the dots, because redrawcmd() below
294297 // won't remove them.
295- if (!cmd_silent && !from_wildtrigger_func
298+ if (!cmd_silent && !from_wildtrigger_func && ! wild_navigate
296299 && !(ui_has (kUICmdline ) || ui_has (kUIWildmenu ))) {
297300 msg_puts ("..." ); // show that we are busy
298301 ui_flush ();
299302 }
300303
301- if (type == WILD_NEXT || type == WILD_PREV
302- || type == WILD_PAGEUP || type == WILD_PAGEDOWN
303- || type == WILD_PUM_WANT ) {
304+ if (wild_navigate ) {
304305 // Get next/previous match for a previous expanded pattern.
305306 p = ExpandOne (xp , NULL , NULL , 0 , type );
306307 } else {
@@ -313,7 +314,7 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
313314 tmp = addstar (xp -> xp_pattern , xp -> xp_pattern_len , xp -> xp_context );
314315 }
315316 // Translate string into pattern and expand it.
316- const int use_options = (( options & ~ WILD_KEEP_SOLE_ITEM )
317+ const int use_options = (options
317318 | WILD_HOME_REPLACE
318319 | WILD_ADD_SLASH
319320 | WILD_SILENT
@@ -337,7 +338,13 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
337338 }
338339 }
339340
340- if (p != NULL && !got_int ) {
341+ // Save cmdline before inserting selected item
342+ if (!wild_navigate && ccline -> cmdbuff != NULL ) {
343+ xfree (cmdline_orig );
344+ cmdline_orig = xstrnsave (ccline -> cmdbuff , (size_t )ccline -> cmdlen );
345+ }
346+
347+ if (p != NULL && !got_int && !(options & WILD_NOSELECT )) {
341348 size_t plen = strlen (p );
342349 int difflen = (int )plen - (int )(xp -> xp_pattern_len );
343350 if (ccline -> cmdlen + difflen + 4 > ccline -> cmdbufflen ) {
@@ -364,7 +371,7 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
364371
365372 if (xp -> xp_numfiles <= 0 && p == NULL ) {
366373 beep_flush ();
367- } else if (xp -> xp_numfiles == 1 && !(options & WILD_KEEP_SOLE_ITEM ) ) {
374+ } else if (xp -> xp_numfiles == 1 && !(options & WILD_NOSELECT ) && ! wild_navigate ) {
368375 // free expanded pattern
369376 ExpandOne (xp , NULL , NULL , 0 , WILD_FREE );
370377 }
@@ -374,10 +381,9 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
374381 return OK ;
375382}
376383
377- /// Create and display a cmdline completion popup menu with items from
378- /// "matches".
384+ /// Create completion popup menu with items from "matches".
379385static int cmdline_pum_create (CmdlineInfo * ccline , expand_T * xp , char * * matches , int numMatches ,
380- bool showtail )
386+ bool showtail , bool noselect )
381387{
382388 assert (numMatches >= 0 );
383389 // Add all the completion matches
@@ -395,19 +401,13 @@ static int cmdline_pum_create(CmdlineInfo *ccline, expand_T *xp, char **matches,
395401 }
396402
397403 // Compute the popup menu starting column
398- char * endpos = showtail ? showmatches_gettail (xp -> xp_pattern , true ) : xp -> xp_pattern ;
404+ char * endpos = showtail ? showmatches_gettail (xp -> xp_pattern , noselect ) : xp -> xp_pattern ;
399405 if (ui_has (kUICmdline ) && cmdline_win == NULL ) {
400406 compl_startcol = (int )(endpos - ccline -> cmdbuff );
401407 } else {
402408 compl_startcol = cmd_screencol ((int )(endpos - ccline -> cmdbuff ));
403409 }
404410
405- // no default selection
406- compl_selected = -1 ;
407-
408- pum_clear ();
409- cmdline_pum_display (true);
410-
411411 return EXPAND_OK ;
412412}
413413
@@ -420,8 +420,7 @@ void cmdline_pum_display(bool changed_array)
420420/// Returns true if the cmdline completion popup menu is being displayed.
421421bool cmdline_pum_active (void )
422422{
423- // compl_match_array != NULL should already imply pum_visible() in Nvim.
424- return compl_match_array != NULL ;
423+ return pum_visible () && compl_match_array != NULL ;
425424}
426425
427426/// Remove the cmdline completion popup menu (if present), free the list of items.
@@ -745,11 +744,20 @@ static char *get_next_or_prev_match(int mode, expand_T *xp)
745744 }
746745
747746 // Display matches on screen
748- if (compl_match_array ) {
749- compl_selected = findex ;
750- cmdline_pum_display (false);
751- } else if (p_wmnu ) {
752- redraw_wildmenu (xp , xp -> xp_numfiles , xp -> xp_files , findex , cmd_showtail );
747+ if (p_wmnu ) {
748+ if (compl_match_array ) {
749+ compl_selected = findex ;
750+ cmdline_pum_display (false);
751+ } else if (wop_flags & kOptWopFlagPum ) {
752+ if (cmdline_pum_create (get_cmdline_info (), xp , xp -> xp_files ,
753+ xp -> xp_numfiles , cmd_showtail , false) == EXPAND_OK ) {
754+ compl_selected = findex ;
755+ pum_clear ();
756+ cmdline_pum_display (true);
757+ }
758+ } else {
759+ redraw_wildmenu (xp , xp -> xp_numfiles , xp -> xp_files , findex , cmd_showtail );
760+ }
753761 }
754762
755763 xp -> xp_selected = findex ;
@@ -925,7 +933,7 @@ char *ExpandOne(expand_T *xp, char *str, char *orig, int options, int mode)
925933 cmdline_pum_remove ();
926934 }
927935 }
928- xp -> xp_selected = 0 ;
936+ xp -> xp_selected = ( options & WILD_NOSELECT ) ? -1 : 0 ;
929937
930938 if (mode == WILD_FREE ) { // only release file name
931939 return NULL ;
@@ -1084,49 +1092,49 @@ static void showmatches_oneline(expand_T *xp, char **matches, int numMatches, in
10841092 }
10851093}
10861094
1087- /// Show all matches for completion on the command line .
1088- /// Returns EXPAND_NOTHING when the character that triggered expansion should
1089- /// be inserted like a normal character.
1090- int showmatches (expand_T * xp , bool wildmenu )
1095+ /// Display completion matches .
1096+ /// Returns EXPAND_NOTHING when the character that triggered expansion should be
1097+ /// inserted as a normal character.
1098+ int showmatches (expand_T * xp , bool display_wildmenu , bool display_list , bool noselect )
10911099{
10921100 CmdlineInfo * const ccline = get_cmdline_info ();
10931101 int numMatches ;
10941102 char * * matches ;
1095- int j ;
10961103 int maxlen ;
10971104 int lines ;
10981105 int columns ;
10991106 bool showtail ;
11001107
1101- // Save cmdline before expansion
1102- if (ccline -> cmdbuff != NULL ) {
1103- xfree (cmdline_orig );
1104- cmdline_orig = xstrnsave (ccline -> cmdbuff , (size_t )ccline -> cmdlen );
1105- }
1106-
11071108 if (xp -> xp_numfiles == -1 ) {
11081109 set_expand_context (xp );
11091110 if (xp -> xp_context == EXPAND_LUA ) {
11101111 nlua_expand_pat (xp );
11111112 }
1112- int i = expand_cmdline (xp , ccline -> cmdbuff , ccline -> cmdpos ,
1113- & numMatches , & matches );
1114- showtail = expand_showtail (xp );
1115- if (i != EXPAND_OK ) {
1116- return i ;
1113+ int retval = expand_cmdline (xp , ccline -> cmdbuff , ccline -> cmdpos ,
1114+ & numMatches , & matches );
1115+ if (retval != EXPAND_OK ) {
1116+ return retval ;
11171117 }
1118+ showtail = expand_showtail (xp );
11181119 } else {
11191120 numMatches = xp -> xp_numfiles ;
11201121 matches = xp -> xp_files ;
11211122 showtail = cmd_showtail ;
11221123 }
11231124
1124- if (((!ui_has (kUICmdline ) || cmdline_win != NULL ) && wildmenu && (wop_flags & kOptWopFlagPum ))
1125+ if (((!ui_has (kUICmdline ) || cmdline_win != NULL ) && display_wildmenu && !display_list
1126+ && (wop_flags & kOptWopFlagPum ))
11251127 || ui_has (kUIWildmenu ) || (ui_has (kUICmdline ) && ui_has (kUIPopupmenu ))) {
1126- return cmdline_pum_create (ccline , xp , matches , numMatches , showtail );
1128+ int retval = cmdline_pum_create (ccline , xp , matches , numMatches , showtail , noselect );
1129+ if (retval == EXPAND_OK ) {
1130+ compl_selected = noselect ? -1 : 0 ;
1131+ pum_clear ();
1132+ cmdline_pum_display (true);
1133+ }
1134+ return retval ;
11271135 }
11281136
1129- if (! wildmenu ) {
1137+ if (display_list ) {
11301138 msg_didany = false; // lines_left will be set
11311139 msg_start (); // prepare for paging
11321140 msg_putchar ('\n' );
@@ -1138,22 +1146,24 @@ int showmatches(expand_T *xp, bool wildmenu)
11381146 }
11391147
11401148 if (got_int ) {
1141- got_int = false; // only int. the completion, not the cmd line
1142- } else if (wildmenu ) {
1143- redraw_wildmenu (xp , numMatches , matches , -1 , showtail );
1144- } else {
1149+ got_int = false; // only interrupt the completion, not the cmd line
1150+ } else if (display_wildmenu && !display_list ) {
1151+ redraw_wildmenu (xp , numMatches , matches , noselect ? -1 : 0 ,
1152+ showtail ); // display statusbar menu
1153+ } else if (display_list ) {
11451154 // find the length of the longest file name
11461155 maxlen = 0 ;
11471156 for (int i = 0 ; i < numMatches ; i ++ ) {
1157+ int len ;
11481158 if (!showtail && (xp -> xp_context == EXPAND_FILES
11491159 || xp -> xp_context == EXPAND_SHELLCMD
11501160 || xp -> xp_context == EXPAND_BUFFERS )) {
11511161 home_replace (NULL , matches [i ], NameBuff , MAXPATHL , true);
1152- j = vim_strsize (NameBuff );
1162+ len = vim_strsize (NameBuff );
11531163 } else {
1154- j = vim_strsize (SHOW_MATCH (i ));
1164+ len = vim_strsize (SHOW_MATCH (i ));
11551165 }
1156- maxlen = MAX (maxlen , j );
1166+ maxlen = MAX (maxlen , len );
11571167 }
11581168
11591169 if (xp -> xp_context == EXPAND_TAGS_LISTFILES ) {
@@ -3569,7 +3579,7 @@ int wildmenu_translate_key(CmdlineInfo *cclp, int key, expand_T *xp, bool did_wi
35693579{
35703580 int c = key ;
35713581
3572- if (did_wild_list ) {
3582+ if (cmdline_pum_active () || did_wild_list || wild_menu_showing ) {
35733583 if (c == K_LEFT ) {
35743584 c = Ctrl_P ;
35753585 } else if (c == K_RIGHT ) {
0 commit comments