diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/map.c | 31 | ||||
-rw-r--r-- | src/popupwin.c | 15 | ||||
-rw-r--r-- | src/proto/map.pro | 1 | ||||
-rw-r--r-- | src/structs.h | 1 | ||||
-rw-r--r-- | src/testdir/test_popupwin.vim | 66 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim.h | 1 |
7 files changed, 104 insertions, 13 deletions
@@ -897,20 +897,10 @@ map_clear_int( } #if defined(FEAT_EVAL) || defined(PROTO) -/* - * Return TRUE if a map exists that has "str" in the rhs for mode "modechars". - * Recognize termcap codes in "str". - * Also checks mappings local to the current buffer. - */ int -map_to_exists(char_u *str, char_u *modechars, int abbr) +mode_str2flags(char_u *modechars) { int mode = 0; - char_u *rhs; - char_u *buf; - int retval; - - rhs = replace_termcodes(str, &buf, FALSE, TRUE, FALSE); if (vim_strchr(modechars, 'n') != NULL) mode |= NORMAL; @@ -929,7 +919,24 @@ map_to_exists(char_u *str, char_u *modechars, int abbr) if (vim_strchr(modechars, 'c') != NULL) mode |= CMDLINE; - retval = map_to_exists_mode(rhs, mode, abbr); + return mode; +} + +/* + * Return TRUE if a map exists that has "str" in the rhs for mode "modechars". + * Recognize termcap codes in "str". + * Also checks mappings local to the current buffer. + */ + int +map_to_exists(char_u *str, char_u *modechars, int abbr) +{ + char_u *rhs; + char_u *buf; + int retval; + + rhs = replace_termcodes(str, &buf, FALSE, TRUE, FALSE); + + retval = map_to_exists_mode(rhs, mode_str2flags(modechars), abbr); vim_free(buf); return retval; diff --git a/src/popupwin.c b/src/popupwin.c index abf40e8c0..226232dd0 100644 --- a/src/popupwin.c +++ b/src/popupwin.c @@ -845,6 +845,15 @@ apply_general_options(win_T *wp, dict_T *dict) wp->w_popup_flags &= ~POPF_MAPPING; } + str = dict_get_string(dict, (char_u *)"filtermode", FALSE); + if (str != NULL) + { + if (STRCMP(str, "a") == 0) + wp->w_filter_mode = MODE_ALL; + else + wp->w_filter_mode = mode_str2flags(str); + } + di = dict_find(dict, (char_u *)"callback", -1); if (di != NULL) { @@ -1851,6 +1860,7 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type) wp->w_border_char[i] = 0; wp->w_want_scrollbar = 1; wp->w_popup_fixed = 0; + wp->w_filter_mode = MODE_ALL; if (d != NULL) // Deal with options. @@ -2768,6 +2778,7 @@ popup_do_filter(int c) int res = FALSE; win_T *wp; int save_KeyTyped = KeyTyped; + int state; if (recursive) return FALSE; @@ -2785,8 +2796,10 @@ popup_do_filter(int c) res = TRUE; } + state = get_real_state(); while (!res && (wp = find_next_popup(FALSE)) != NULL) - if (wp->w_filter_cb.cb_name != NULL) + if (wp->w_filter_cb.cb_name != NULL + && (wp->w_filter_mode & state) != 0) res = invoke_popup_filter(wp, c); recursive = FALSE; diff --git a/src/proto/map.pro b/src/proto/map.pro index 05d66fb87..cf1b31a4c 100644 --- a/src/proto/map.pro +++ b/src/proto/map.pro @@ -4,6 +4,7 @@ mapblock_T *get_buf_maphash_list(int state, int c); int is_maphash_valid(void); int do_map(int maptype, char_u *arg, int mode, int abbrev); void map_clear_int(buf_T *buf, int mode, int local, int abbr); +int mode_str2flags(char_u *modechars); int map_to_exists(char_u *str, char_u *modechars, int abbr); int map_to_exists_mode(char_u *rhs, int mode, int abbr); char_u *set_context_in_map_cmd(expand_T *xp, char_u *cmd, char_u *arg, int forceit, int isabbrev, int isunmap, cmdidx_T cmdidx); diff --git a/src/structs.h b/src/structs.h index 35a22b102..e599550a1 100644 --- a/src/structs.h +++ b/src/structs.h @@ -3054,6 +3054,7 @@ struct window_S // computed callback_T w_close_cb; // popup close callback callback_T w_filter_cb; // popup filter callback + int w_filter_mode; // mode when filter callback is used win_T *w_popup_curwin; // close popup if curwin differs linenr_T w_popup_lnum; // close popup if cursor not on this line diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim index 8fd4da157..36cf306a7 100644 --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -1892,6 +1892,72 @@ func Test_popupwin_garbage_collect() delfunc MyPopupFilter endfunc +func Test_popupwin_filter_mode() + func MyPopupFilter(winid, c) + let s:typed = a:c + if a:c == ':' || a:c == "\r" || a:c == 'v' + " can start cmdline mode, get out, and start/stop Visual mode + return 0 + endif + return 1 + endfunc + + " Normal, Visual and Insert mode + let winid = popup_create('something', #{filter: 'MyPopupFilter', filtermode: 'nvi'}) + redraw + call feedkeys('x', 'xt') + call assert_equal('x', s:typed) + + call feedkeys(":let g:foo = 'foo'\<CR>", 'xt') + call assert_equal(':', s:typed) + call assert_equal('foo', g:foo) + + let @x = 'something' + call feedkeys('v$"xy', 'xt') + call assert_equal('y', s:typed) + call assert_equal('something', @x) " yank command is filtered out + call feedkeys('v', 'xt') " end Visual mode + + call popup_close(winid) + + " only Normal mode + let winid = popup_create('something', #{filter: 'MyPopupFilter', filtermode: 'n'}) + redraw + call feedkeys('x', 'xt') + call assert_equal('x', s:typed) + + call feedkeys(":let g:foo = 'foo'\<CR>", 'xt') + call assert_equal(':', s:typed) + call assert_equal('foo', g:foo) + + let @x = 'something' + call feedkeys('v$"xy', 'xt') + call assert_equal('v', s:typed) + call assert_notequal('something', @x) + + call popup_close(winid) + + " default: all modes + let winid = popup_create('something', #{filter: 'MyPopupFilter'}) + redraw + call feedkeys('x', 'xt') + call assert_equal('x', s:typed) + + let g:foo = 'bar' + call feedkeys(":let g:foo = 'foo'\<CR>", 'xt') + call assert_equal("\r", s:typed) + call assert_equal('bar', g:foo) + + let @x = 'something' + call feedkeys('v$"xy', 'xt') + call assert_equal('y', s:typed) + call assert_equal('something', @x) " yank command is filtered out + call feedkeys('v', 'xt') " end Visual mode + + call popup_close(winid) + delfunc MyPopupFilter +endfunc + func Test_popupwin_with_buffer() call writefile(['some text', 'in a buffer'], 'XsomeFile') let buf = bufadd('XsomeFile') diff --git a/src/version.c b/src/version.c index 5dbdc9fa4..655b68a99 100644 --- a/src/version.c +++ b/src/version.c @@ -762,6 +762,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1969, +/**/ 1968, /**/ 1967, @@ -680,6 +680,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring); #define CONFIRM 0x800 // ":confirm" prompt #define SELECTMODE 0x1000 // Select mode, only for mappings #define TERMINAL 0x2000 // Terminal mode +#define MODE_ALL 0xffff // all mode bits used for mapping #define MAP_ALL_MODES (0x3f | SELECTMODE | TERMINAL) |