Skip to content

Commit 1e38198

Browse files
girishjichrisbra
authored andcommitted
patch 9.1.1639: completion: popup may be misplaced
Problem: During commandline completiom, popup window placement can be incorrect when 'noselect' is present in 'wildmode' (Shane-XB-Qian) Solution: Disable "showtail" feature when 'noselect' is present. fixes: vim#17969 closes: vim#18001 Signed-off-by: Girish Palya <[email protected]> Signed-off-by: Christian Brabandt <[email protected]>
1 parent a09b160 commit 1e38198

File tree

7 files changed

+82
-29
lines changed

7 files changed

+82
-29
lines changed

src/cmdexpand.c

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -342,16 +342,15 @@ nextwild(
342342
{
343343
size_t plen = STRLEN(p);
344344
int difflen;
345-
int v;
345+
int v = OK;
346346

347347
difflen = (int)plen - xp->xp_pattern_len;
348348
if (ccline->cmdlen + difflen + 4 > ccline->cmdbufflen)
349349
{
350350
v = realloc_cmdbuff(ccline->cmdlen + difflen + 4);
351351
xp->xp_pattern = ccline->cmdbuff + i;
352352
}
353-
else
354-
v = OK;
353+
355354
if (v == OK)
356355
{
357356
mch_memmove(&ccline->cmdbuff[ccline->cmdpos + difflen],
@@ -395,7 +394,7 @@ cmdline_pum_create(
395394
int showtail)
396395
{
397396
int i;
398-
int columns;
397+
int prefix_len;
399398

400399
// Add all the completion matches
401400
compl_match_array = ALLOC_MULT(pumitem_T, numMatches);
@@ -415,13 +414,11 @@ cmdline_pum_create(
415414

416415
// Compute the popup menu starting column
417416
compl_startcol = ccline == NULL ? 0 : vim_strsize(ccline->cmdbuff) + 1;
418-
columns = vim_strsize(xp->xp_pattern);
417+
prefix_len = vim_strsize(xp->xp_pattern);
419418
if (showtail)
420-
{
421-
columns += vim_strsize(showmatches_gettail(matches[0]));
422-
columns -= vim_strsize(matches[0]);
423-
}
424-
compl_startcol = MAX(0, compl_startcol - columns);
419+
prefix_len += vim_strsize(showmatches_gettail(matches[0]))
420+
- vim_strsize(matches[0]);
421+
compl_startcol = MAX(0, compl_startcol - prefix_len);
425422

426423
// no default selection
427424
compl_selected = -1;
@@ -1279,12 +1276,12 @@ showmatches_oneline(
12791276
* be inserted like a normal character.
12801277
*/
12811278
int
1282-
showmatches(expand_T *xp, int wildmenu UNUSED)
1279+
showmatches(expand_T *xp, int wildmenu, int noselect)
12831280
{
12841281
cmdline_info_T *ccline = get_cmdline_info();
12851282
int numMatches;
12861283
char_u **matches;
1287-
int i, j;
1284+
int i;
12881285
int maxlen;
12891286
int lines;
12901287
int columns;
@@ -1300,12 +1297,13 @@ showmatches(expand_T *xp, int wildmenu UNUSED)
13001297

13011298
if (xp->xp_numfiles == -1)
13021299
{
1300+
int retval;
13031301
set_expand_context(xp);
1304-
i = expand_cmdline(xp, ccline->cmdbuff, ccline->cmdpos,
1305-
&numMatches, &matches);
1302+
retval = expand_cmdline(xp, ccline->cmdbuff, ccline->cmdpos,
1303+
&numMatches, &matches);
1304+
if (retval != EXPAND_OK)
1305+
return retval;
13061306
showtail = expand_showtail(xp);
1307-
if (i != EXPAND_OK)
1308-
return i;
13091307
}
13101308
else
13111309
{
@@ -1316,7 +1314,8 @@ showmatches(expand_T *xp, int wildmenu UNUSED)
13161314

13171315
if (wildmenu && vim_strchr(p_wop, WOP_PUM) != NULL)
13181316
// cmdline completion popup menu (with wildoptions=pum)
1319-
return cmdline_pum_create(ccline, xp, matches, numMatches, showtail);
1317+
return cmdline_pum_create(ccline, xp, matches, numMatches,
1318+
showtail && !noselect);
13201319

13211320
if (!wildmenu)
13221321
{
@@ -1339,17 +1338,18 @@ showmatches(expand_T *xp, int wildmenu UNUSED)
13391338
maxlen = 0;
13401339
for (i = 0; i < numMatches; ++i)
13411340
{
1341+
int len;
13421342
if (!showtail && (xp->xp_context == EXPAND_FILES
13431343
|| xp->xp_context == EXPAND_SHELLCMD
13441344
|| xp->xp_context == EXPAND_BUFFERS))
13451345
{
13461346
home_replace(NULL, matches[i], NameBuff, MAXPATHL, TRUE);
1347-
j = vim_strsize(NameBuff);
1347+
len = vim_strsize(NameBuff);
13481348
}
13491349
else
1350-
j = vim_strsize(SHOW_MATCH(i));
1351-
if (j > maxlen)
1352-
maxlen = j;
1350+
len = vim_strsize(SHOW_MATCH(i));
1351+
if (len > maxlen)
1352+
maxlen = len;
13531353
}
13541354

13551355
if (xp->xp_context == EXPAND_TAGS_LISTFILES)

src/ex_getln.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -946,10 +946,11 @@ cmdline_wildchar_complete(
946946
int res;
947947
int j;
948948
int options = WILD_NO_BEEP;
949+
int noselect = (wim_flags[0] & WIM_NOSELECT) != 0;
949950

950951
if (wim_flags[wim_index] & WIM_BUFLASTUSED)
951952
options |= WILD_BUFLASTUSED;
952-
if (wim_flags[0] & WIM_NOSELECT)
953+
if (noselect)
953954
options |= WILD_KEEP_SOLE_ITEM;
954955
if (xp->xp_numfiles > 0) // typed p_wc at least twice
955956
{
@@ -960,7 +961,8 @@ cmdline_wildchar_complete(
960961
|| (p_wmnu && (wim_flags[wim_index] & WIM_FULL) != 0)))
961962
{
962963
(void)showmatches(xp,
963-
p_wmnu && ((wim_flags[wim_index] & WIM_LIST) == 0));
964+
p_wmnu && ((wim_flags[wim_index] & WIM_LIST) == 0),
965+
noselect);
964966
redrawcmd();
965967
*did_wild_list = TRUE;
966968
}
@@ -1011,7 +1013,7 @@ cmdline_wildchar_complete(
10111013
// "list", or no change and 'wildmode' contains "longest,list",
10121014
// list all matches
10131015
if (res == OK
1014-
&& xp->xp_numfiles > ((wim_flags[wim_index] & WIM_NOSELECT) ? 0 : 1))
1016+
&& xp->xp_numfiles > (noselect ? 0 : 1))
10151017
{
10161018
// a "longest" that didn't do anything is skipped (but not
10171019
// "list:longest")
@@ -1031,7 +1033,7 @@ cmdline_wildchar_complete(
10311033
p_wmnu = p_wmnu_save;
10321034
}
10331035
(void)showmatches(xp, p_wmnu
1034-
&& ((wim_flags[wim_index] & WIM_LIST) == 0));
1036+
&& ((wim_flags[wim_index] & WIM_LIST) == 0), noselect);
10351037
redrawcmd();
10361038
*did_wild_list = TRUE;
10371039
if (wim_flags[wim_index] & WIM_LONGEST)
@@ -2013,7 +2015,8 @@ getcmdline_int(
20132015
{
20142016
if (cmdline_pum_active())
20152017
{
2016-
skip_pum_redraw = skip_pum_redraw && (vim_isprintc(c)
2018+
skip_pum_redraw = skip_pum_redraw && !key_is_wc
2019+
&& (vim_isprintc(c)
20172020
|| c == K_BS || c == Ctrl_H || c == K_DEL
20182021
|| c == K_KDEL || c == Ctrl_W || c == Ctrl_U);
20192022
cmdline_pum_remove(&ccline, skip_pum_redraw);
@@ -2124,7 +2127,8 @@ getcmdline_int(
21242127
{
21252128
// Trigger the popup menu when wildoptions=pum
21262129
showmatches(&xpc, p_wmnu
2127-
&& ((wim_flags[wim_index] & WIM_LIST) == 0));
2130+
&& ((wim_flags[wim_index] & WIM_LIST) == 0),
2131+
wim_flags[0] & WIM_NOSELECT);
21282132
}
21292133
if (nextwild(&xpc, WILD_PREV, 0, firstc != '@') == OK
21302134
&& nextwild(&xpc, WILD_PREV, 0, firstc != '@') == OK)
@@ -2239,7 +2243,8 @@ getcmdline_int(
22392243
goto cmdline_not_changed;
22402244

22412245
case Ctrl_D:
2242-
if (showmatches(&xpc, FALSE) == EXPAND_NOTHING)
2246+
if (showmatches(&xpc, FALSE, wim_flags[0] & WIM_NOSELECT)
2247+
== EXPAND_NOTHING)
22432248
break; // Use ^D as normal char instead
22442249

22452250
redrawcmd();

src/proto/cmdexpand.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ char_u *ExpandOne(expand_T *xp, char_u *str, char_u *orig, int options, int mode
1212
void ExpandInit(expand_T *xp);
1313
void ExpandCleanup(expand_T *xp);
1414
void clear_cmdline_orig(void);
15-
int showmatches(expand_T *xp, int wildmenu);
15+
int showmatches(expand_T *xp, int wildmenu, int noselect);
1616
char_u *addstar(char_u *fname, int len, int context);
1717
void set_expand_context(expand_T *xp);
1818
void set_cmd_context(expand_T *xp, char_u *str, int len, int col, int use_ccline);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
| +0&#ffffff0@74
2+
|~+0#4040ff13&| @73
3+
|~| @73
4+
|~| @73
5+
|~| | +0#0000001#ffd7ff255|a|/|b|/|c|/| @8| +0#4040ff13#ffffff0@56
6+
|~| | +0#0000001#ffd7ff255|a|/|b|/|f|i|l|e|X|n|a|m|e|1| | +0#4040ff13#ffffff0@56
7+
|~| | +0#0000001#ffd7ff255|a|/|b|/|f|i|l|e|X|n|a|m|e|2| | +0#4040ff13#ffffff0@56
8+
|:+0#0000000&|e| |$|T|E|S|T|D|I|R|/> @62
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
| +0&#ffffff0@74
2+
|~+0#4040ff13&| @73
3+
|~| @73
4+
|~| @73
5+
|~| | +0#0000001#e0e0e08|a|/|b|/|c|/| @8| +0#4040ff13#ffffff0@56
6+
|~| | +0#0000001#ffd7ff255|a|/|b|/|f|i|l|e|X|n|a|m|e|1| | +0#4040ff13#ffffff0@56
7+
|~| | +0#0000001#ffd7ff255|a|/|b|/|f|i|l|e|X|n|a|m|e|2| | +0#4040ff13#ffffff0@56
8+
|:+0#0000000&|e| |a|/|b|/|c|/> @65

src/testdir/test_cmdline.vim

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4859,4 +4859,34 @@ func Test_wildtrigger_update_screen()
48594859
cnoremap <buffer> <F8> <C-R>=wildtrigger()[-1]<CR>
48604860
endfunc
48614861

4862+
" Issue #17969: With 'noselect', the popup menu should appear next to the
4863+
" environment variable being expanded. Disable 'showtail' when completing
4864+
" file paths when 'noselect' is present.
4865+
func Test_noselect_expand_env_var()
4866+
CheckScreendump
4867+
4868+
let lines =<< trim [SCRIPT]
4869+
set wildmenu wildoptions=pum wildmode=noselect,full
4870+
let $TESTDIR = 'a/b'
4871+
[SCRIPT]
4872+
call writefile(lines, 'XTest_wildmenu', 'D')
4873+
let buf = RunVimInTerminal('-S XTest_wildmenu', {'rows': 8})
4874+
4875+
call mkdir('a/b/c', 'pR')
4876+
call writefile(['asdf'], 'a/b/fileXname1')
4877+
call writefile(['foo'], 'a/b/fileXname2')
4878+
4879+
call term_sendkeys(buf, ":e $TESTDIR/\<Tab>")
4880+
call VerifyScreenDump(buf, 'Test_expand_env_var_1', {})
4881+
4882+
call term_sendkeys(buf, "\<C-N>")
4883+
call VerifyScreenDump(buf, 'Test_expand_env_var_2', {})
4884+
4885+
call term_sendkeys(buf, "\<C-P>")
4886+
call VerifyScreenDump(buf, 'Test_expand_env_var_1', {})
4887+
" clean up
4888+
call term_sendkeys(buf, "\<Esc>")
4889+
call StopVimInTerminal(buf)
4890+
endfunc
4891+
48624892
" vim: shiftwidth=2 sts=2 expandtab

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,8 @@ static char *(features[]) =
719719

720720
static int included_patches[] =
721721
{ /* Add new patch number below this line */
722+
/**/
723+
1639,
722724
/**/
723725
1638,
724726
/**/

0 commit comments

Comments
 (0)