Merge pull request #19481 from zeertzjq/vim-8.2.4674

Add 'mousemoveevent' as a UI option
This commit is contained in:
zeertzjq 2022-09-04 21:44:31 +08:00 committed by GitHub
commit 5ac6654334
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 245 additions and 18 deletions

View File

@ -1067,9 +1067,11 @@ nvim_input_mouse({button}, {action}, {modifier}, {grid}, {row}, {col})
|api-fast| |api-fast|
Parameters: ~ Parameters: ~
{button} Mouse button: one of "left", "right", "middle", "wheel". {button} Mouse button: one of "left", "right", "middle", "wheel",
"move".
{action} For ordinary buttons, one of "press", "drag", "release". {action} For ordinary buttons, one of "press", "drag", "release".
For the wheel, one of "up", "down", "left", "right". For the wheel, one of "up", "down", "left", "right".
Ignored for "move".
{modifier} String of modifiers each represented by a single char. The {modifier} String of modifiers each represented by a single char. The
same specifiers are used as for a key press, except that same specifiers are used as for a key press, except that
the "-" separator is optional, so "C-A-", "c-a" and "CA" the "-" separator is optional, so "C-A-", "c-a" and "CA"

View File

@ -4231,6 +4231,15 @@ A jump table for the options with a short description can be found at |Q_op|.
The 'mousemodel' option is set by the |:behave| command. The 'mousemodel' option is set by the |:behave| command.
*'mousemoveevent'* *'mousemev'*
'mousemoveevent' 'mousemev' boolean (default off)
global
When on, mouse move events are delivered to the input queue and are
available for mapping. The default, off, avoids the mouse movement
overhead except when needed.
Warning: Setting this option can make pending mappings to be aborted
when the mouse is moved.
*'mousescroll'* *'mousescroll'*
'mousescroll' string (default "ver:3,hor:6") 'mousescroll' string (default "ver:3,hor:6")
global global

View File

@ -207,6 +207,7 @@ the editor.
'guifontwide' 'guifontwide'
'linespace' 'linespace'
'mousefocus' 'mousefocus'
'mousemoveevent'
'pumblend' 'pumblend'
'showtabline' 'showtabline'
'termguicolors' 'termguicolors'

View File

@ -336,9 +336,9 @@ Integer nvim_input(String keys)
/// mouse input in a GUI. The deprecated pseudokey form /// mouse input in a GUI. The deprecated pseudokey form
/// ("<LeftMouse><col,row>") of |nvim_input()| has the same limitation. /// ("<LeftMouse><col,row>") of |nvim_input()| has the same limitation.
/// ///
/// @param button Mouse button: one of "left", "right", "middle", "wheel". /// @param button Mouse button: one of "left", "right", "middle", "wheel", "move".
/// @param action For ordinary buttons, one of "press", "drag", "release". /// @param action For ordinary buttons, one of "press", "drag", "release".
/// For the wheel, one of "up", "down", "left", "right". /// For the wheel, one of "up", "down", "left", "right". Ignored for "move".
/// @param modifier String of modifiers each represented by a single char. /// @param modifier String of modifiers each represented by a single char.
/// The same specifiers are used as for a key press, except /// The same specifiers are used as for a key press, except
/// that the "-" separator is optional, so "C-A-", "c-a" /// that the "-" separator is optional, so "C-A-", "c-a"
@ -365,6 +365,8 @@ void nvim_input_mouse(String button, String action, String modifier, Integer gri
code = KE_RIGHTMOUSE; code = KE_RIGHTMOUSE;
} else if (strequal(button.data, "wheel")) { } else if (strequal(button.data, "wheel")) {
code = KE_MOUSEDOWN; code = KE_MOUSEDOWN;
} else if (strequal(button.data, "move")) {
code = KE_MOUSEMOVE;
} else { } else {
goto error; goto error;
} }
@ -381,7 +383,7 @@ void nvim_input_mouse(String button, String action, String modifier, Integer gri
} else { } else {
goto error; goto error;
} }
} else { } else if (code != KE_MOUSEMOVE) {
if (strequal(action.data, "press")) { if (strequal(action.data, "press")) {
// pass // pass
} else if (strequal(action.data, "drag")) { } else if (strequal(action.data, "drag")) {

View File

@ -616,6 +616,7 @@ EXTERN int p_ma; ///< 'modifiable'
EXTERN int p_mod; ///< 'modified' EXTERN int p_mod; ///< 'modified'
EXTERN char *p_mouse; // 'mouse' EXTERN char *p_mouse; // 'mouse'
EXTERN char *p_mousem; // 'mousemodel' EXTERN char *p_mousem; // 'mousemodel'
EXTERN int p_mousemev; ///< 'mousemoveevent'
EXTERN int p_mousef; // 'mousefocus' EXTERN int p_mousef; // 'mousefocus'
EXTERN char *p_mousescroll; // 'mousescroll' EXTERN char *p_mousescroll; // 'mousescroll'
EXTERN long p_mousescroll_vert INIT(= MOUSESCROLL_VERT_DFLT); EXTERN long p_mousescroll_vert INIT(= MOUSESCROLL_VERT_DFLT);

View File

@ -1621,6 +1621,14 @@ return {
varname='p_mousem', varname='p_mousem',
defaults={if_true="popup_setpos"} defaults={if_true="popup_setpos"}
}, },
{
full_name='mousemoveevent', abbreviation='mousemev',
short_desc=N_("deliver mouse move events to input queue"),
type='bool', scope={'global'},
redraw={'ui_option'},
varname='p_mousemev',
defaults={if_true=false}
},
{ {
full_name='mousescroll', full_name='mousescroll',
short_desc=N_("amount to scroll by when scrolling with a mouse"), short_desc=N_("amount to scroll by when scrolling with a mouse"),

View File

@ -293,7 +293,8 @@ static uint8_t check_multiclick(int code, int grid, int row, int col)
|| code == KE_MOUSEDOWN || code == KE_MOUSEDOWN
|| code == KE_MOUSEUP || code == KE_MOUSEUP
|| code == KE_MOUSELEFT || code == KE_MOUSELEFT
|| code == KE_MOUSERIGHT) { || code == KE_MOUSERIGHT
|| code == KE_MOUSEMOVE) {
return 0; return 0;
} }
uint64_t mouse_time = os_hrtime(); // time of current mouse click (ns) uint64_t mouse_time = os_hrtime(); // time of current mouse click (ns)
@ -347,7 +348,8 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, unsigned int bu
if (type != KS_EXTRA if (type != KS_EXTRA
|| !((mouse_code >= KE_LEFTMOUSE && mouse_code <= KE_RIGHTRELEASE) || !((mouse_code >= KE_LEFTMOUSE && mouse_code <= KE_RIGHTRELEASE)
|| (mouse_code >= KE_MOUSEDOWN && mouse_code <= KE_MOUSERIGHT))) { || (mouse_code >= KE_MOUSEDOWN && mouse_code <= KE_MOUSERIGHT)
|| mouse_code == KE_MOUSEMOVE)) {
return bufsize; return bufsize;
} }

View File

@ -1042,6 +1042,10 @@ void pum_show_popupmenu(vimmenu_T *menu)
pum_scrollbar = 0; pum_scrollbar = 0;
pum_height = pum_size; pum_height = pum_size;
pum_position_at_mouse(20); pum_position_at_mouse(20);
if (!p_mousemev) {
// Pretend 'mousemoveevent' is set.
ui_call_option_set(STATIC_CSTR_AS_STRING("mousemoveevent"), BOOLEAN_OBJ(true));
}
pum_selected = -1; pum_selected = -1;
pum_first = 0; pum_first = 0;
@ -1102,6 +1106,9 @@ void pum_show_popupmenu(vimmenu_T *menu)
xfree(array); xfree(array);
pum_undisplay(true); pum_undisplay(true);
if (!p_mousemev) {
ui_call_option_set(STATIC_CSTR_AS_STRING("mousemoveevent"), BOOLEAN_OBJ(false));
}
} }
void pum_make_popup(const char *path_name, int use_mouse_pos) void pum_make_popup(const char *path_name, int use_mouse_pos)

View File

@ -406,8 +406,8 @@ static void forward_mouse_event(TermInput *input, TermKeyKey *key)
} }
} }
if (button == 0 || (ev != TERMKEY_MOUSE_PRESS && ev != TERMKEY_MOUSE_DRAG if ((button == 0 && ev != TERMKEY_MOUSE_RELEASE)
&& ev != TERMKEY_MOUSE_RELEASE)) { || (ev != TERMKEY_MOUSE_PRESS && ev != TERMKEY_MOUSE_DRAG && ev != TERMKEY_MOUSE_RELEASE)) {
return; return;
} }
@ -453,7 +453,8 @@ static void forward_mouse_event(TermInput *input, TermKeyKey *key)
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Drag"); len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Drag");
break; break;
case TERMKEY_MOUSE_RELEASE: case TERMKEY_MOUSE_RELEASE:
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Release"); len += (size_t)snprintf(buf + len, sizeof(buf) - len, button ? "Release" : "MouseMove");
last_pressed_button = 0;
break; break;
case TERMKEY_MOUSE_UNKNOWN: case TERMKEY_MOUSE_UNKNOWN:
abort(); abort();

View File

@ -103,6 +103,7 @@ struct TUIData {
bool immediate_wrap_after_last_column; bool immediate_wrap_after_last_column;
bool bce; bool bce;
bool mouse_enabled; bool mouse_enabled;
bool mouse_move_enabled;
bool busy, is_invisible, want_invisible; bool busy, is_invisible, want_invisible;
bool cork, overflow; bool cork, overflow;
bool cursor_color_changed; bool cursor_color_changed;
@ -117,6 +118,7 @@ struct TUIData {
ModeShape showing_mode; ModeShape showing_mode;
struct { struct {
int enable_mouse, disable_mouse; int enable_mouse, disable_mouse;
int enable_mouse_move, disable_mouse_move;
int enable_bracketed_paste, disable_bracketed_paste; int enable_bracketed_paste, disable_bracketed_paste;
int enable_lr_margin, disable_lr_margin; int enable_lr_margin, disable_lr_margin;
int enter_strikethrough_mode; int enter_strikethrough_mode;
@ -236,6 +238,8 @@ static void terminfo_start(UI *ui)
data->showing_mode = SHAPE_IDX_N; data->showing_mode = SHAPE_IDX_N;
data->unibi_ext.enable_mouse = -1; data->unibi_ext.enable_mouse = -1;
data->unibi_ext.disable_mouse = -1; data->unibi_ext.disable_mouse = -1;
data->unibi_ext.enable_mouse_move = -1;
data->unibi_ext.disable_mouse_move = -1;
data->unibi_ext.set_cursor_color = -1; data->unibi_ext.set_cursor_color = -1;
data->unibi_ext.reset_cursor_color = -1; data->unibi_ext.reset_cursor_color = -1;
data->unibi_ext.enable_bracketed_paste = -1; data->unibi_ext.enable_bracketed_paste = -1;
@ -1138,6 +1142,9 @@ static void tui_mouse_on(UI *ui)
TUIData *data = ui->data; TUIData *data = ui->data;
if (!data->mouse_enabled) { if (!data->mouse_enabled) {
unibi_out_ext(ui, data->unibi_ext.enable_mouse); unibi_out_ext(ui, data->unibi_ext.enable_mouse);
if (data->mouse_move_enabled) {
unibi_out_ext(ui, data->unibi_ext.enable_mouse_move);
}
data->mouse_enabled = true; data->mouse_enabled = true;
} }
} }
@ -1146,6 +1153,9 @@ static void tui_mouse_off(UI *ui)
{ {
TUIData *data = ui->data; TUIData *data = ui->data;
if (data->mouse_enabled) { if (data->mouse_enabled) {
if (data->mouse_move_enabled) {
unibi_out_ext(ui, data->unibi_ext.disable_mouse_move);
}
unibi_out_ext(ui, data->unibi_ext.disable_mouse); unibi_out_ext(ui, data->unibi_ext.disable_mouse);
data->mouse_enabled = false; data->mouse_enabled = false;
} }
@ -1457,9 +1467,18 @@ static void tui_screenshot(UI *ui, String path)
static void tui_option_set(UI *ui, String name, Object value) static void tui_option_set(UI *ui, String name, Object value)
{ {
TUIData *data = ui->data; TUIData *data = ui->data;
if (strequal(name.data, "termguicolors")) { if (strequal(name.data, "mousemoveevent")) {
if (data->mouse_move_enabled != value.data.boolean) {
if (data->mouse_enabled) {
tui_mouse_off(ui);
data->mouse_move_enabled = value.data.boolean;
tui_mouse_on(ui);
} else {
data->mouse_move_enabled = value.data.boolean;
}
}
} else if (strequal(name.data, "termguicolors")) {
ui->rgb = value.data.boolean; ui->rgb = value.data.boolean;
data->print_attr_id = -1; data->print_attr_id = -1;
invalidate(ui, 0, data->grid.height, 0, data->grid.width); invalidate(ui, 0, data->grid.height, 0, data->grid.width);
} else if (strequal(name.data, "ttimeout")) { } else if (strequal(name.data, "ttimeout")) {
@ -2135,6 +2154,10 @@ static void augment_terminfo(TUIData *data, const char *term, long vte_version,
"\x1b[?1002h\x1b[?1006h"); "\x1b[?1002h\x1b[?1006h");
data->unibi_ext.disable_mouse = (int)unibi_add_ext_str(ut, "ext.disable_mouse", data->unibi_ext.disable_mouse = (int)unibi_add_ext_str(ut, "ext.disable_mouse",
"\x1b[?1002l\x1b[?1006l"); "\x1b[?1002l\x1b[?1006l");
data->unibi_ext.enable_mouse_move = (int)unibi_add_ext_str(ut, "ext.enable_mouse_move",
"\x1b[?1003h");
data->unibi_ext.disable_mouse_move = (int)unibi_add_ext_str(ut, "ext.disable_mouse_move",
"\x1b[?1003l");
// Extended underline. // Extended underline.
// terminfo will have Smulx for this (but no support for colors yet). // terminfo will have Smulx for this (but no support for colors yet).

View File

@ -21,6 +21,7 @@ local nvim_set = helpers.nvim_set
local ok = helpers.ok local ok = helpers.ok
local read_file = helpers.read_file local read_file = helpers.read_file
local funcs = helpers.funcs local funcs = helpers.funcs
local meths = helpers.meths
if helpers.pending_win32(pending) then return end if helpers.pending_win32(pending) then return end
@ -666,6 +667,57 @@ describe('TUI', function()
]], attrs) ]], attrs)
end) end)
it('mouse events work with right-click menu', function()
child_session:request('nvim_command', [[
call setline(1, 'popup menu test')
set mouse=a mousemodel=popup
aunmenu PopUp
menu PopUp.foo :let g:menustr = 'foo'<CR>
menu PopUp.bar :let g:menustr = 'bar'<CR>
menu PopUp.baz :let g:menustr = 'baz'<CR>
highlight Pmenu ctermbg=NONE ctermfg=NONE cterm=underline,reverse
highlight PmenuSel ctermbg=NONE ctermfg=NONE cterm=underline,reverse,bold
]])
local attrs = screen:get_default_attr_ids()
attrs[11] = {underline = true, reverse = true}
attrs[12] = {underline = true, reverse = true, bold = true}
meths.input_mouse('right', 'press', '', 0, 0, 4)
screen:expect([[
{1:p}opup menu test |
{4:~ }{11: foo }{4: }|
{4:~ }{11: bar }{4: }|
{4:~ }{11: baz }{4: }|
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
]], attrs)
meths.input_mouse('right', 'release', '', 0, 0, 4)
screen:expect_unchanged()
meths.input_mouse('move', '', '', 0, 3, 6)
screen:expect([[
{1:p}opup menu test |
{4:~ }{11: foo }{4: }|
{4:~ }{11: bar }{4: }|
{4:~ }{12: baz }{4: }|
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
]], attrs)
meths.input_mouse('left', 'press', '', 0, 2, 6)
screen:expect([[
{1:p}opup menu test |
{4:~ }|
{4:~ }|
{4:~ }|
{5:[No Name] [+] }|
:let g:menustr = 'bar' |
{3:-- TERMINAL --} |
]], attrs)
meths.input_mouse('left', 'release', '', 0, 2, 6)
screen:expect_unchanged()
end)
it('paste: Insert mode', function() it('paste: Insert mode', function()
-- "bracketed paste" -- "bracketed paste"
feed_data('i""\027i\027[200~') feed_data('i""\027i\027[200~')

View File

@ -1585,7 +1585,20 @@ describe('ui/mouse/input', function()
eq(0, meths.get_var('mouse_up2')) eq(0, meths.get_var('mouse_up2'))
end) end)
it('feeding <MouseMove> does not use uninitialized memory #19480', function() it('<MouseMove> is not translated into multiclicks and can be mapped', function()
meths.set_var('mouse_move', 0)
meths.set_var('mouse_move2', 0)
command('nnoremap <MouseMove> <Cmd>let g:mouse_move += 1<CR>')
command('nnoremap <2-MouseMove> <Cmd>let g:mouse_move2 += 1<CR>')
feed('<MouseMove><0,0>')
feed('<MouseMove><0,0>')
meths.input_mouse('move', '', '', 0, 0, 0)
meths.input_mouse('move', '', '', 0, 0, 0)
eq(4, meths.get_var('mouse_move'))
eq(0, meths.get_var('mouse_move2'))
end)
it('feeding <MouseMove> in Normal mode does not use uninitialized memory #19480', function()
feed('<MouseMove>') feed('<MouseMove>')
helpers.poke_eventloop() helpers.poke_eventloop()
helpers.assert_alive() helpers.assert_alive()

View File

@ -19,6 +19,7 @@ describe('UI receives option updates', function()
linespace=0, linespace=0,
pumblend=0, pumblend=0,
mousefocus=false, mousefocus=false,
mousemoveevent=false,
showtabline=1, showtabline=1,
termguicolors=false, termguicolors=false,
ttimeout=true, ttimeout=true,
@ -131,6 +132,12 @@ describe('UI receives option updates', function()
eq(expected, screen.options) eq(expected, screen.options)
end) end)
command("set mousemoveevent")
expected.mousemoveevent = true
screen:expect(function()
eq(expected, screen.options)
end)
command("set nottimeout") command("set nottimeout")
expected.ttimeout = false expected.ttimeout = false
screen:expect(function() screen:expect(function()

View File

@ -2755,7 +2755,7 @@ describe('builtin popupmenu', function()
menu PopUp.bar :let g:menustr = 'bar'<CR> menu PopUp.bar :let g:menustr = 'bar'<CR>
menu PopUp.baz :let g:menustr = 'baz'<CR> menu PopUp.baz :let g:menustr = 'baz'<CR>
]]) ]])
meths.input_mouse('right', 'press', '', 0, 0, 4) feed('<RightMouse><4,0>')
screen:expect([[ screen:expect([[
^popup menu test | ^popup menu test |
{1:~ }{n: foo }{1: }| {1:~ }{n: foo }{1: }|
@ -2792,7 +2792,7 @@ describe('builtin popupmenu', function()
:let g:menustr = 'bar' | :let g:menustr = 'bar' |
]]) ]])
eq('bar', meths.get_var('menustr')) eq('bar', meths.get_var('menustr'))
meths.input_mouse('right', 'press', '', 0, 1, 20) feed('<RightMouse><20,1>')
screen:expect([[ screen:expect([[
^popup menu test | ^popup menu test |
{1:~ }| {1:~ }|
@ -2801,7 +2801,7 @@ describe('builtin popupmenu', function()
{1:~ }{n: baz }{1: }| {1:~ }{n: baz }{1: }|
:let g:menustr = 'bar' | :let g:menustr = 'bar' |
]]) ]])
meths.input_mouse('left', 'press', '', 0, 4, 22) feed('<LeftMouse><22,4>')
screen:expect([[ screen:expect([[
^popup menu test | ^popup menu test |
{1:~ }| {1:~ }|
@ -2811,7 +2811,7 @@ describe('builtin popupmenu', function()
:let g:menustr = 'baz' | :let g:menustr = 'baz' |
]]) ]])
eq('baz', meths.get_var('menustr')) eq('baz', meths.get_var('menustr'))
meths.input_mouse('right', 'press', '', 0, 0, 4) feed('<RightMouse><4,0>')
screen:expect([[ screen:expect([[
^popup menu test | ^popup menu test |
{1:~ }{n: foo }{1: }| {1:~ }{n: foo }{1: }|
@ -2820,7 +2820,7 @@ describe('builtin popupmenu', function()
{1:~ }| {1:~ }|
:let g:menustr = 'baz' | :let g:menustr = 'baz' |
]]) ]])
meths.input_mouse('right', 'drag', '', 0, 3, 6) feed('<RightDrag><6,3>')
screen:expect([[ screen:expect([[
^popup menu test | ^popup menu test |
{1:~ }{n: foo }{1: }| {1:~ }{n: foo }{1: }|
@ -2829,7 +2829,7 @@ describe('builtin popupmenu', function()
{1:~ }| {1:~ }|
:let g:menustr = 'baz' | :let g:menustr = 'baz' |
]]) ]])
meths.input_mouse('right', 'release', '', 0, 1, 6) feed('<RightRelease><6,1>')
screen:expect([[ screen:expect([[
^popup menu test | ^popup menu test |
{1:~ }| {1:~ }|
@ -2839,6 +2839,38 @@ describe('builtin popupmenu', function()
:let g:menustr = 'foo' | :let g:menustr = 'foo' |
]]) ]])
eq('foo', meths.get_var('menustr')) eq('foo', meths.get_var('menustr'))
eq(false, screen.options.mousemoveevent)
feed('<RightMouse><4,0>')
screen:expect([[
^popup menu test |
{1:~ }{n: foo }{1: }|
{1:~ }{n: bar }{1: }|
{1:~ }{n: baz }{1: }|
{1:~ }|
:let g:menustr = 'foo' |
]])
eq(true, screen.options.mousemoveevent)
feed('<MouseMove><6,3>')
screen:expect([[
^popup menu test |
{1:~ }{n: foo }{1: }|
{1:~ }{n: bar }{1: }|
{1:~ }{s: baz }{1: }|
{1:~ }|
:let g:menustr = 'foo' |
]])
eq(true, screen.options.mousemoveevent)
feed('<LeftMouse><6,2>')
screen:expect([[
^popup menu test |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
:let g:menustr = 'bar' |
]])
eq(false, screen.options.mousemoveevent)
eq('bar', meths.get_var('menustr'))
end) end)
end) end)
@ -3047,5 +3079,72 @@ describe('builtin popupmenu with ui/ext_multigrid', function()
:let g:menustr = 'foo' | :let g:menustr = 'foo' |
]]}) ]]})
eq('foo', meths.get_var('menustr')) eq('foo', meths.get_var('menustr'))
eq(false, screen.options.mousemoveevent)
meths.input_mouse('right', 'press', '', 2, 0, 4)
screen:expect({grid=[[
## grid 1
[2:--------------------------------]|
[2:--------------------------------]|
[2:--------------------------------]|
[2:--------------------------------]|
[2:--------------------------------]|
[3:--------------------------------]|
## grid 2
^popup menu test |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
## grid 3
:let g:menustr = 'foo' |
## grid 4
{n: foo }|
{n: bar }|
{n: baz }|
]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 100}}})
eq(true, screen.options.mousemoveevent)
meths.input_mouse('move', '', '', 2, 3, 6)
screen:expect({grid=[[
## grid 1
[2:--------------------------------]|
[2:--------------------------------]|
[2:--------------------------------]|
[2:--------------------------------]|
[2:--------------------------------]|
[3:--------------------------------]|
## grid 2
^popup menu test |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
## grid 3
:let g:menustr = 'foo' |
## grid 4
{n: foo }|
{n: bar }|
{s: baz }|
]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 100}}})
eq(true, screen.options.mousemoveevent)
meths.input_mouse('left', 'press', '', 2, 2, 6)
screen:expect({grid=[[
## grid 1
[2:--------------------------------]|
[2:--------------------------------]|
[2:--------------------------------]|
[2:--------------------------------]|
[2:--------------------------------]|
[3:--------------------------------]|
## grid 2
^popup menu test |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
## grid 3
:let g:menustr = 'bar' |
]]})
eq(false, screen.options.mousemoveevent)
eq('bar', meths.get_var('menustr'))
end) end)
end) end)