Skip to content

Commit 749fa0a

Browse files
committed
patch 8.1.1799: cannot avoid mapping for a popup window
Problem: Cannot avoid mapping for a popup window. Solution: Add the "mapping" property, default TRUE.
1 parent eda35f7 commit 749fa0a

File tree

7 files changed

+69
-5
lines changed

7 files changed

+69
-5
lines changed

runtime/doc/popup.txt

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ popup_dialog({what}, {options}) *popup_dialog()*
246246
\ drag: 1,
247247
\ border: [],
248248
\ padding: [],
249+
\ mapping: 0,
249250
\})
250251
< Use {options} to change the properties. E.g. add a 'filter'
251252
option with value 'popup_filter_yesno'. Example: >
@@ -369,12 +370,20 @@ popup_menu({what}, {options}) *popup_menu()*
369370
\ cursorline: 1,
370371
\ padding: [0,1,0,1],
371372
\ filter: 'popup_filter_menu',
373+
\ mapping: 0,
372374
\ })
373375
< The current line is highlighted with a match using
374376
"PopupSelected", or "PmenuSel" if that is not defined.
375377

376378
Use {options} to change the properties. Should at least set
377379
"callback" to a function that handles the selected item.
380+
Example: >
381+
func ColorSelected(id, result)
382+
" use a:result
383+
endfunc
384+
call popup_menu(['red', 'green', 'blue'], #{
385+
\ callback: 'ColorSelected',
386+
\ })
378387
379388
380389
popup_move({id}, {options}) *popup_move()*
@@ -433,16 +442,17 @@ popup_setoptions({id}, {options}) *popup_setoptions()*
433442
borderhighlight
434443
callback
435444
close
436-
drag
437-
resize
438445
cursorline
446+
drag
439447
filter
440448
firstline
441449
flip
442450
highlight
451+
mapping
443452
mask
444453
moved
445454
padding
455+
resize
446456
scrollbar
447457
scrollbarhighlight
448458
thumbhighlight
@@ -615,6 +625,9 @@ The second argument of |popup_create()| is a dictionary with options:
615625
Default is zero, except for |popup_menu()|.
616626
filter A callback that can filter typed characters, see
617627
|popup-filter|.
628+
mapping Allow for key mapping. When FALSE and the popup is
629+
visible and has a filter callback key mapping is
630+
disabled. Default value is TRUE.
618631
callback A callback that is called when the popup closes, e.g.
619632
when using |popup_filter_menu()|, see |popup-callback|.
620633

@@ -671,8 +684,11 @@ key as a string, e.g.: >
671684
endif
672685
return 0
673686
endfunc
674-
675-
Currently the key is what results after any mapping. This may change...
687+
< *popup-mapping*
688+
Normally the key is what results after any mapping, since the keys pass on as
689+
normal input if the filter does not use it. If the filter consumes all the
690+
keys, set the "mapping" property to zero so that mappings do not get in the
691+
way. This is default for |popup_menu()| and |popup_dialog()|.
676692

677693
Some common key actions:
678694
x close the popup (see note below)
@@ -703,6 +719,11 @@ the second argument of `popup_close()`.
703719
If the popup is force-closed, e.g. because the cursor moved or CTRL-C was
704720
pressed, the number -1 is passed to the callback.
705721

722+
Example: >
723+
func SelectedColor(id, result)
724+
echo 'choice made: ' .. a:result
725+
endfunc
726+
706727
707728
POPUP SCROLLBAR *popup-scrollbar*
708729

src/getchar.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,6 +1574,9 @@ vgetc(void)
15741574
if (mod_mask
15751575
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
15761576
|| im_is_preediting()
1577+
#endif
1578+
#if defined(FEAT_TEXT_PROP)
1579+
|| popup_no_mapping()
15771580
#endif
15781581
)
15791582
{

src/popupwin.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,15 @@ apply_general_options(win_T *wp, dict_T *dict)
800800
set_callback(&wp->w_filter_cb, &callback);
801801
}
802802
}
803+
di = dict_find(dict, (char_u *)"mapping", -1);
804+
if (di != NULL)
805+
{
806+
nr = dict_get_number(dict, (char_u *)"mapping");
807+
if (nr)
808+
wp->w_popup_flags |= POPF_MAPPING;
809+
else
810+
wp->w_popup_flags &= ~POPF_MAPPING;
811+
}
803812

804813
di = dict_find(dict, (char_u *)"callback", -1);
805814
if (di != NULL)
@@ -1413,7 +1422,7 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
14131422
if (rettv != NULL)
14141423
rettv->vval.v_number = wp->w_id;
14151424
wp->w_popup_pos = POPPOS_TOPLEFT;
1416-
wp->w_popup_flags = POPF_IS_POPUP;
1425+
wp->w_popup_flags = POPF_IS_POPUP | POPF_MAPPING;
14171426

14181427
if (buf != NULL)
14191428
{
@@ -1561,6 +1570,7 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
15611570
wp->w_popup_pos = POPPOS_CENTER;
15621571
wp->w_zindex = POPUPWIN_DIALOG_ZINDEX;
15631572
wp->w_popup_flags |= POPF_DRAG;
1573+
wp->w_popup_flags &= ~POPF_MAPPING;
15641574
for (i = 0; i < 4; ++i)
15651575
{
15661576
wp->w_popup_border[i] = 1;
@@ -2501,6 +2511,25 @@ popup_do_filter(int c)
25012511
return res;
25022512
}
25032513

2514+
/*
2515+
* Return TRUE if there is a popup visible with a filter callback and the
2516+
* "mapping" property off.
2517+
*/
2518+
int
2519+
popup_no_mapping(void)
2520+
{
2521+
int round;
2522+
win_T *wp;
2523+
2524+
for (round = 1; round <= 2; ++round)
2525+
for (wp = round == 1 ? first_popupwin : curtab->tp_first_popupwin;
2526+
wp != NULL; wp = wp->w_next)
2527+
if (wp->w_filter_cb.cb_name != NULL
2528+
&& (wp->w_popup_flags & (POPF_HIDDEN | POPF_MAPPING)) == 0)
2529+
return TRUE;
2530+
return FALSE;
2531+
}
2532+
25042533
/*
25052534
* Called when the cursor moved: check if any popup needs to be closed if the
25062535
* cursor moved far enough.

src/proto/popupwin.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ int error_if_popup_window(void);
3838
void popup_reset_handled(void);
3939
win_T *find_next_popup(int lowest);
4040
int popup_do_filter(int c);
41+
int popup_no_mapping(void);
4142
void popup_check_cursor_pos(void);
4243
void may_update_popup_mask(int type);
4344
void update_popups(void (*win_update)(win_T *wp));

src/testdir/test_popupwin.vim

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,7 @@ func Test_popup_invalid_arguments()
657657
call assert_fails('call popup_create("text", #{mask: ["asdf"]})', 'E475:')
658658
call popup_clear()
659659
call assert_fails('call popup_create("text", #{mask: test_null_list()})', 'E475:')
660+
call assert_fails('call popup_create("text", #{mapping: []})', 'E745:')
660661
call popup_clear()
661662
endfunc
662663

@@ -1203,6 +1204,8 @@ func Test_popup_menu()
12031204
let s:cb_winid = a:id
12041205
let s:cb_res = a:res
12051206
endfunc
1207+
" mapping won't be used in popup
1208+
map j k
12061209
12071210
let winid = ShowMenu(" ", 1)
12081211
let winid = ShowMenu("j \<CR>", 2)
@@ -1215,6 +1218,7 @@ func Test_popup_menu()
12151218
let winid = ShowMenu("\<C-C>", -1)
12161219

12171220
delfunc QuitCallback
1221+
unmap j
12181222
endfunc
12191223

12201224
func Test_popup_menu_screenshot()
@@ -2194,6 +2198,9 @@ func Test_previewpopup()
21942198
call term_sendkeys(buf, "/another\<CR>\<C-W>}")
21952199
call VerifyScreenDump(buf, 'Test_popupwin_previewpopup_4', {})
21962200

2201+
call term_sendkeys(buf, ":cd ..\<CR>:\<CR>")
2202+
call VerifyScreenDump(buf, 'Test_popupwin_previewpopup_5', {})
2203+
21972204
call StopVimInTerminal(buf)
21982205
call delete('Xtags')
21992206
call delete('Xtagfile')

src/version.c

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

774774
static int included_patches[] =
775775
{ /* Add new patch number below this line */
776+
/**/
777+
1799,
776778
/**/
777779
1798,
778780
/**/

src/vim.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
621621
#define POPF_ON_CMDLINE 0x10 // popup overlaps command line
622622
#define POPF_DRAG 0x20 // popup can be moved by dragging
623623
#define POPF_RESIZE 0x40 // popup can be resized by dragging
624+
#define POPF_MAPPING 0x80 // mapping keys
624625

625626
#ifdef FEAT_TEXT_PROP
626627
# define WIN_IS_POPUP(wp) ((wp)->w_popup_flags != 0)

0 commit comments

Comments
 (0)