summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-08-03 16:18:07 +0200
committerBram Moolenaar <Bram@vim.org>2019-08-03 16:18:07 +0200
commit749fa0af85232be1d44b77a09161f71cdbace62c (patch)
tree1aae6e9a655399ecadba0db9e399323077e0d705
parenteda35f7127c6ac51573eda808687f6369c31ee2d (diff)
patch 8.1.1799: cannot avoid mapping for a popup windowv8.1.1799
Problem: Cannot avoid mapping for a popup window. Solution: Add the "mapping" property, default TRUE.
-rw-r--r--runtime/doc/popup.txt29
-rw-r--r--src/getchar.c3
-rw-r--r--src/popupwin.c31
-rw-r--r--src/proto/popupwin.pro1
-rw-r--r--src/testdir/test_popupwin.vim7
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h1
7 files changed, 69 insertions, 5 deletions
diff --git a/runtime/doc/popup.txt b/runtime/doc/popup.txt
index b58ade69d2..bac34331f8 100644
--- a/runtime/doc/popup.txt
+++ b/runtime/doc/popup.txt
@@ -246,6 +246,7 @@ popup_dialog({what}, {options}) *popup_dialog()*
\ drag: 1,
\ border: [],
\ padding: [],
+ \ mapping: 0,
\})
< Use {options} to change the properties. E.g. add a 'filter'
option with value 'popup_filter_yesno'. Example: >
@@ -369,12 +370,20 @@ popup_menu({what}, {options}) *popup_menu()*
\ cursorline: 1,
\ padding: [0,1,0,1],
\ filter: 'popup_filter_menu',
+ \ mapping: 0,
\ })
< The current line is highlighted with a match using
"PopupSelected", or "PmenuSel" if that is not defined.
Use {options} to change the properties. Should at least set
"callback" to a function that handles the selected item.
+ Example: >
+ func ColorSelected(id, result)
+ " use a:result
+ endfunc
+ call popup_menu(['red', 'green', 'blue'], #{
+ \ callback: 'ColorSelected',
+ \ })
popup_move({id}, {options}) *popup_move()*
@@ -433,16 +442,17 @@ popup_setoptions({id}, {options}) *popup_setoptions()*
borderhighlight
callback
close
- drag
- resize
cursorline
+ drag
filter
firstline
flip
highlight
+ mapping
mask
moved
padding
+ resize
scrollbar
scrollbarhighlight
thumbhighlight
@@ -615,6 +625,9 @@ The second argument of |popup_create()| is a dictionary with options:
Default is zero, except for |popup_menu()|.
filter A callback that can filter typed characters, see
|popup-filter|.
+ mapping Allow for key mapping. When FALSE and the popup is
+ visible and has a filter callback key mapping is
+ disabled. Default value is TRUE.
callback A callback that is called when the popup closes, e.g.
when using |popup_filter_menu()|, see |popup-callback|.
@@ -671,8 +684,11 @@ key as a string, e.g.: >
endif
return 0
endfunc
-
-Currently the key is what results after any mapping. This may change...
+< *popup-mapping*
+Normally the key is what results after any mapping, since the keys pass on as
+normal input if the filter does not use it. If the filter consumes all the
+keys, set the "mapping" property to zero so that mappings do not get in the
+way. This is default for |popup_menu()| and |popup_dialog()|.
Some common key actions:
x close the popup (see note below)
@@ -703,6 +719,11 @@ the second argument of `popup_close()`.
If the popup is force-closed, e.g. because the cursor moved or CTRL-C was
pressed, the number -1 is passed to the callback.
+Example: >
+ func SelectedColor(id, result)
+ echo 'choice made: ' .. a:result
+ endfunc
+
POPUP SCROLLBAR *popup-scrollbar*
diff --git a/src/getchar.c b/src/getchar.c
index fe1cc7e2ef..4a3587c3f2 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -1575,6 +1575,9 @@ vgetc(void)
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|| im_is_preediting()
#endif
+#if defined(FEAT_TEXT_PROP)
+ || popup_no_mapping()
+#endif
)
{
// no mapping after modifier has been read
diff --git a/src/popupwin.c b/src/popupwin.c
index 4ca6d9fdf1..28ad48cfc8 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -800,6 +800,15 @@ apply_general_options(win_T *wp, dict_T *dict)
set_callback(&wp->w_filter_cb, &callback);
}
}
+ di = dict_find(dict, (char_u *)"mapping", -1);
+ if (di != NULL)
+ {
+ nr = dict_get_number(dict, (char_u *)"mapping");
+ if (nr)
+ wp->w_popup_flags |= POPF_MAPPING;
+ else
+ wp->w_popup_flags &= ~POPF_MAPPING;
+ }
di = dict_find(dict, (char_u *)"callback", -1);
if (di != NULL)
@@ -1413,7 +1422,7 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
if (rettv != NULL)
rettv->vval.v_number = wp->w_id;
wp->w_popup_pos = POPPOS_TOPLEFT;
- wp->w_popup_flags = POPF_IS_POPUP;
+ wp->w_popup_flags = POPF_IS_POPUP | POPF_MAPPING;
if (buf != NULL)
{
@@ -1561,6 +1570,7 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
wp->w_popup_pos = POPPOS_CENTER;
wp->w_zindex = POPUPWIN_DIALOG_ZINDEX;
wp->w_popup_flags |= POPF_DRAG;
+ wp->w_popup_flags &= ~POPF_MAPPING;
for (i = 0; i < 4; ++i)
{
wp->w_popup_border[i] = 1;
@@ -2502,6 +2512,25 @@ popup_do_filter(int c)
}
/*
+ * Return TRUE if there is a popup visible with a filter callback and the
+ * "mapping" property off.
+ */
+ int
+popup_no_mapping(void)
+{
+ int round;
+ win_T *wp;
+
+ for (round = 1; round <= 2; ++round)
+ for (wp = round == 1 ? first_popupwin : curtab->tp_first_popupwin;
+ wp != NULL; wp = wp->w_next)
+ if (wp->w_filter_cb.cb_name != NULL
+ && (wp->w_popup_flags & (POPF_HIDDEN | POPF_MAPPING)) == 0)
+ return TRUE;
+ return FALSE;
+}
+
+/*
* Called when the cursor moved: check if any popup needs to be closed if the
* cursor moved far enough.
*/
diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro
index b964fc0dd0..f1d0d2b523 100644
--- a/src/proto/popupwin.pro
+++ b/src/proto/popupwin.pro
@@ -38,6 +38,7 @@ int error_if_popup_window(void);
void popup_reset_handled(void);
win_T *find_next_popup(int lowest);
int popup_do_filter(int c);
+int popup_no_mapping(void);
void popup_check_cursor_pos(void);
void may_update_popup_mask(int type);
void update_popups(void (*win_update)(win_T *wp));
diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim
index d4b98aee7b..e5d16314bc 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -657,6 +657,7 @@ func Test_popup_invalid_arguments()
call assert_fails('call popup_create("text", #{mask: ["asdf"]})', 'E475:')
call popup_clear()
call assert_fails('call popup_create("text", #{mask: test_null_list()})', 'E475:')
+ call assert_fails('call popup_create("text", #{mapping: []})', 'E745:')
call popup_clear()
endfunc
@@ -1203,6 +1204,8 @@ func Test_popup_menu()
let s:cb_winid = a:id
let s:cb_res = a:res
endfunc
+ " mapping won't be used in popup
+ map j k
let winid = ShowMenu(" ", 1)
let winid = ShowMenu("j \<CR>", 2)
@@ -1215,6 +1218,7 @@ func Test_popup_menu()
let winid = ShowMenu("\<C-C>", -1)
delfunc QuitCallback
+ unmap j
endfunc
func Test_popup_menu_screenshot()
@@ -2194,6 +2198,9 @@ func Test_previewpopup()
call term_sendkeys(buf, "/another\<CR>\<C-W>}")
call VerifyScreenDump(buf, 'Test_popupwin_previewpopup_4', {})
+ call term_sendkeys(buf, ":cd ..\<CR>:\<CR>")
+ call VerifyScreenDump(buf, 'Test_popupwin_previewpopup_5', {})
+
call StopVimInTerminal(buf)
call delete('Xtags')
call delete('Xtagfile')
diff --git a/src/version.c b/src/version.c
index ec67fe4060..b2c4416ae3 100644
--- a/src/version.c
+++ b/src/version.c
@@ -774,6 +774,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1799,
+/**/
1798,
/**/
1797,
diff --git a/src/vim.h b/src/vim.h
index 02b4c03bc6..70fcf3a12c 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -621,6 +621,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
#define POPF_ON_CMDLINE 0x10 // popup overlaps command line
#define POPF_DRAG 0x20 // popup can be moved by dragging
#define POPF_RESIZE 0x40 // popup can be resized by dragging
+#define POPF_MAPPING 0x80 // mapping keys
#ifdef FEAT_TEXT_PROP
# define WIN_IS_POPUP(wp) ((wp)->w_popup_flags != 0)