commit 7d569abb206753d5d01b223ab94927ebd9724576
parent 1670fbee0f57af9aa9c43f448d92870cf0407285
Author: zeertzjq <zeertzjq@outlook.com>
Date: Fri, 25 Apr 2025 14:37:42 +0800
fix(pum): handle RightDrag on parent grid properly (#33626)
Diffstat:
2 files changed, 286 insertions(+), 321 deletions(-)
diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c
@@ -78,6 +78,7 @@ static int pum_col; // left column of pum, right column if 'righ
static int pum_win_row_offset; // The row offset needed to convert to window relative coordinates
static int pum_win_col_offset; // The column offset needed to convert to window relative coordinates
static int pum_left_col; // left column of pum, before padding or scrollbar
+static int pum_right_col; // right column of pum, after padding or scrollbar
static bool pum_above; // pum is drawn above cursor line
static bool pum_is_visible = false;
@@ -613,6 +614,7 @@ void pum_redraw(void)
grid_assign_handle(&pum_grid);
pum_left_col = pum_col - col_off;
+ pum_right_col = pum_left_col + grid_width;
bool moved = ui_comp_put_grid(&pum_grid, pum_row, pum_left_col,
pum_height, grid_width, false, true);
bool invalid_grid = moved || pum_invalid;
@@ -1392,15 +1394,16 @@ static void pum_select_mouse_pos(void)
if (mouse_grid == pum_grid.handle) {
pum_selected = mouse_row;
return;
- } else if (mouse_grid != pum_anchor_grid || mouse_col < pum_grid.comp_col
- || mouse_col >= pum_grid.comp_col + pum_grid.comp_width) {
+ } else if (mouse_grid != pum_anchor_grid
+ || mouse_col < pum_left_col - pum_win_col_offset
+ || mouse_col >= pum_right_col - pum_win_col_offset) {
pum_selected = -1;
return;
}
- int idx = mouse_row - pum_grid.comp_row;
+ int idx = mouse_row - (pum_row - pum_win_row_offset);
- if (idx < 0 || idx >= pum_grid.comp_height) {
+ if (idx < 0 || idx >= pum_height) {
pum_selected = -1;
} else if (*pum_array[idx].pum_text != NUL) {
pum_selected = idx;
diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua
@@ -692,7 +692,7 @@ describe('ui/ext_popupmenu', function()
end)
end)
- it('<PageUP>, <PageDown> works without ui_pum_set_height', function()
+ it('<PageUp>, <PageDown> works without ui_pum_set_height', function()
source_complete_month()
local month_expected = {
{ 'January', '', '', '' },
@@ -6687,9 +6687,26 @@ describe('builtin popupmenu', function()
menu PopUp.baz :let g:menustr = 'baz'<CR>
]])
+ --- @param state string|test.function.ui.screen.Expect
+ --- @param str string
+ --- @param repl string
+ --- @return string|test.function.ui.screen.Expect
+ local function screen_replace(state, str, repl)
+ if type(state) == 'string' then
+ local new_state = state:gsub(vim.pesc(str), vim.pesc(repl))
+ return new_state
+ end
+ local new_state = vim.deepcopy(state)
+ local grid = assert(new_state.grid)
+ grid = grid:gsub(vim.pesc(str), vim.pesc(repl))
+ new_state.grid = grid
+ return new_state
+ end
+
+ local no_sel_screen ---@type string|test.function.ui.screen.Expect
if multigrid then
api.nvim_input_mouse('right', 'press', '', 2, 0, 4)
- screen:expect({
+ no_sel_screen = {
grid = [[
## grid 1
[2:--------------------------------]|*5
@@ -6705,80 +6722,27 @@ describe('builtin popupmenu', function()
{n: baz }|
]],
float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250, 2, 1, 3 } },
- })
+ }
else
feed('<RightMouse><4,0>')
- screen:expect([[
+ no_sel_screen = [[
^popup menu test |
{1:~ }{n: foo }{1: }|
{1:~ }{n: bar }{1: }|
{1:~ }{n: baz }{1: }|
{1:~ }|
|
- ]])
+ ]]
end
+ screen:expect(no_sel_screen)
feed('<Down>')
- if multigrid then
- screen:expect({
- grid = [[
- ## grid 1
- [2:--------------------------------]|*5
- [3:--------------------------------]|
- ## grid 2
- ^popup menu test |
- {1:~ }|*4
- ## grid 3
- |
- ## grid 4
- {s: foo }|
- {n: bar }|
- {n: baz }|
- ]],
- float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250, 2, 1, 3 } },
- })
- else
- screen:expect([[
- ^popup menu test |
- {1:~ }{s: foo }{1: }|
- {1:~ }{n: bar }{1: }|
- {1:~ }{n: baz }{1: }|
- {1:~ }|
- |
- ]])
- end
+ screen:expect(screen_replace(no_sel_screen, '{n: foo }', '{s: foo }'))
feed('<Down>')
- if multigrid then
- screen:expect({
- grid = [[
- ## grid 1
- [2:--------------------------------]|*5
- [3:--------------------------------]|
- ## grid 2
- ^popup menu test |
- {1:~ }|*4
- ## grid 3
- |
- ## grid 4
- {n: foo }|
- {s: bar }|
- {n: baz }|
- ]],
- float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250, 2, 1, 3 } },
- })
- else
- screen:expect([[
- ^popup menu test |
- {1:~ }{n: foo }{1: }|
- {1:~ }{s: bar }{1: }|
- {1:~ }{n: baz }{1: }|
- {1:~ }|
- |
- ]])
- end
+ screen:expect(screen_replace(no_sel_screen, '{n: bar }', '{s: bar }'))
feed('<CR>')
+ local no_menu_screen ---@type string
if multigrid then
- screen:expect({
- grid = [[
+ no_menu_screen = [[
## grid 1
[2:--------------------------------]|*5
[3:--------------------------------]|
@@ -6787,15 +6751,15 @@ describe('builtin popupmenu', function()
{1:~ }|*4
## grid 3
:let g:menustr = 'bar' |
- ]],
- })
+ ]]
else
- screen:expect([[
+ no_menu_screen = [[
^popup menu test |
{1:~ }|*4
:let g:menustr = 'bar' |
- ]])
+ ]]
end
+ screen:expect(no_menu_screen)
eq('bar', api.nvim_get_var('menustr'))
if multigrid then
@@ -6888,31 +6852,16 @@ describe('builtin popupmenu', function()
end
if multigrid then
api.nvim_input_mouse('left', 'press', '', 4, 2, 2)
- screen:expect({
- grid = [[
- ## grid 1
- [2:--------------------------------]|*5
- [3:--------------------------------]|
- ## grid 2
- ^popup menu test |
- {1:~ }|*4
- ## grid 3
- :let g:menustr = 'baz' |
- ]],
- })
else
feed('<LeftMouse><21,5>')
- screen:expect([[
- ^popup menu test |
- {1:~ }|*4
- :let g:menustr = 'baz' |
- ]])
end
+ no_menu_screen = no_menu_screen:gsub([['bar']], [['baz']])
+ screen:expect(no_menu_screen)
eq('baz', api.nvim_get_var('menustr'))
if multigrid then
api.nvim_input_mouse('right', 'press', '', 2, 0, 4)
- screen:expect({
+ no_sel_screen = {
grid = [[
## grid 1
[2:--------------------------------]|*5
@@ -6928,76 +6877,38 @@ describe('builtin popupmenu', function()
{n: baz }|
]],
float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250, 2, 1, 3 } },
- })
+ }
else
feed('<RightMouse><4,0>')
- screen:expect([[
+ no_sel_screen = [[
^popup menu test |
{1:~ }{n: foo }{1: }|
{1:~ }{n: bar }{1: }|
{1:~ }{n: baz }{1: }|
{1:~ }|
:let g:menustr = 'baz' |
- ]])
+ ]]
end
+ screen:expect(no_sel_screen)
if multigrid then
api.nvim_input_mouse('right', 'drag', '', 2, 3, 6)
- screen:expect({
- grid = [[
- ## grid 1
- [2:--------------------------------]|*5
- [3:--------------------------------]|
- ## grid 2
- ^popup menu test |
- {1:~ }|*4
- ## grid 3
- :let g:menustr = 'baz' |
- ## grid 4
- {n: foo }|
- {n: bar }|
- {s: baz }|
- ]],
- float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250, 2, 1, 3 } },
- })
else
feed('<RightDrag><6,3>')
- screen:expect([[
- ^popup menu test |
- {1:~ }{n: foo }{1: }|
- {1:~ }{n: bar }{1: }|
- {1:~ }{s: baz }{1: }|
- {1:~ }|
- :let g:menustr = 'baz' |
- ]])
end
+ screen:expect(screen_replace(no_sel_screen, '{n: baz }', '{s: baz }'))
if multigrid then
api.nvim_input_mouse('right', 'release', '', 2, 1, 6)
- screen:expect({
- grid = [[
- ## grid 1
- [2:--------------------------------]|*5
- [3:--------------------------------]|
- ## grid 2
- ^popup menu test |
- {1:~ }|*4
- ## grid 3
- :let g:menustr = 'foo' |
- ]],
- })
else
feed('<RightRelease><6,1>')
- screen:expect([[
- ^popup menu test |
- {1:~ }|*4
- :let g:menustr = 'foo' |
- ]])
end
+ no_menu_screen = no_menu_screen:gsub([['baz']], [['foo']])
+ screen:expect(no_menu_screen)
eq('foo', api.nvim_get_var('menustr'))
eq(false, screen.options.mousemoveevent)
if multigrid then
api.nvim_input_mouse('right', 'press', '', 2, 0, 4)
- screen:expect({
+ no_sel_screen = {
grid = [[
## grid 1
[2:--------------------------------]|*5
@@ -7013,134 +6924,48 @@ describe('builtin popupmenu', function()
{n: baz }|
]],
float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250, 2, 1, 3 } },
- })
+ }
else
feed('<RightMouse><4,0>')
- screen:expect([[
+ no_sel_screen = [[
^popup menu test |
{1:~ }{n: foo }{1: }|
{1:~ }{n: bar }{1: }|
{1:~ }{n: baz }{1: }|
{1:~ }|
:let g:menustr = 'foo' |
- ]])
+ ]]
end
+ screen:expect(no_sel_screen)
eq(true, screen.options.mousemoveevent)
if multigrid then
api.nvim_input_mouse('wheel', 'up', '', 2, 0, 4)
- screen:expect({
- grid = [[
- ## grid 1
- [2:--------------------------------]|*5
- [3:--------------------------------]|
- ## grid 2
- ^popup menu test |
- {1:~ }|*4
- ## grid 3
- :let g:menustr = 'foo' |
- ## grid 4
- {s: foo }|
- {n: bar }|
- {n: baz }|
- ]],
- float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250, 2, 1, 3 } },
- })
else
feed('<ScrollWheelUp><4,0>')
- screen:expect([[
- ^popup menu test |
- {1:~ }{s: foo }{1: }|
- {1:~ }{n: bar }{1: }|
- {1:~ }{n: baz }{1: }|
- {1:~ }|
- :let g:menustr = 'foo' |
- ]])
end
+ screen:expect(screen_replace(no_sel_screen, '{n: foo }', '{s: foo }'))
eq(true, screen.options.mousemoveevent)
if multigrid then
api.nvim_input_mouse('move', '', '', 4, 2, 3)
- screen:expect({
- grid = [[
- ## grid 1
- [2:--------------------------------]|*5
- [3:--------------------------------]|
- ## grid 2
- ^popup menu test |
- {1:~ }|*4
- ## grid 3
- :let g:menustr = 'foo' |
- ## grid 4
- {n: foo }|
- {n: bar }|
- {s: baz }|
- ]],
- float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250, 2, 1, 3 } },
- })
else
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' |
- ]])
end
+ screen:expect(screen_replace(no_sel_screen, '{n: baz }', '{s: baz }'))
eq(true, screen.options.mousemoveevent)
if multigrid then
api.nvim_input_mouse('wheel', 'down', '', 4, 2, 3)
- screen:expect({
- grid = [[
- ## grid 1
- [2:--------------------------------]|*5
- [3:--------------------------------]|
- ## grid 2
- ^popup menu test |
- {1:~ }|*4
- ## grid 3
- :let g:menustr = 'foo' |
- ## grid 4
- {n: foo }|
- {s: bar }|
- {n: baz }|
- ]],
- float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250, 2, 1, 3 } },
- })
else
feed('<ScrollWheelDown><6,3>')
- screen:expect([[
- ^popup menu test |
- {1:~ }{n: foo }{1: }|
- {1:~ }{s: bar }{1: }|
- {1:~ }{n: baz }{1: }|
- {1:~ }|
- :let g:menustr = 'foo' |
- ]])
end
+ screen:expect(screen_replace(no_sel_screen, '{n: bar }', '{s: bar }'))
eq(true, screen.options.mousemoveevent)
if multigrid then
api.nvim_input_mouse('left', 'press', '', 4, 1, 3)
- screen:expect({
- grid = [[
- ## grid 1
- [2:--------------------------------]|*5
- [3:--------------------------------]|
- ## grid 2
- ^popup menu test |
- {1:~ }|*4
- ## grid 3
- :let g:menustr = 'bar' |
- ]],
- })
else
feed('<LeftMouse><6,2>')
- screen:expect([[
- ^popup menu test |
- {1:~ }|*4
- :let g:menustr = 'bar' |
- ]])
end
+ no_menu_screen = no_menu_screen:gsub([['foo']], [['bar']])
+ screen:expect(no_menu_screen)
eq(false, screen.options.mousemoveevent)
eq('bar', api.nvim_get_var('menustr'))
@@ -7289,7 +7114,7 @@ describe('builtin popupmenu', function()
command('setlocal winbar=WINBAR')
if multigrid then
api.nvim_input_mouse('right', 'press', '', 6, 1, 14)
- screen:expect({
+ no_sel_screen = {
grid = [[
## grid 1
[2:--------------------------------]|*2
@@ -7313,23 +7138,28 @@ describe('builtin popupmenu', function()
^popup menu test |
]],
float_pos = { [4] = { -1, 'SW', 6, 1, 12, false, 250, 2, 1, 28 } },
- })
+ }
else
feed('<RightMouse><30,4>')
- screen:expect([[
+ no_sel_screen = [[
popup menu test |
{1:~ }{n: foo}|
{3:[No Name] [+] }{n: bar}|
popup menu test│{2:WINBAR }{n: baz}|
{1:~ }│^popup menu test |
:let g:menustr = 'foo' |
- ]])
+ ]]
end
- local no_menu_screen ---@type string|test.function.ui.screen.Expect
+ screen:expect(no_sel_screen)
+ if multigrid then
+ api.nvim_input_mouse('right', 'drag', '', 6, 0, 15)
+ else
+ feed('<RightDrag><31,3>')
+ end
+ screen:expect(screen_replace(no_sel_screen, '{n: baz}', '{s: baz}'))
if multigrid then
api.nvim_input_mouse('left', 'press', '', 4, 1, 2)
- no_menu_screen = {
- grid = [[
+ screen:expect([[
## grid 1
[2:--------------------------------]|*2
{3:[No Name] [+] }|
@@ -7346,124 +7176,212 @@ describe('builtin popupmenu', function()
## grid 6
{2:WINBAR }|
^popup menu test |
- ]],
- }
+ ]])
else
feed('<LeftMouse><31,2>')
- no_menu_screen = {
- grid = [[
+ screen:expect([[
popup menu test |
{1:~ }|
{3:[No Name] [+] }|
popup menu test│{2:WINBAR }|
{1:~ }│^popup menu test |
:let g:menustr = 'bar' |
- ]],
- }
+ ]])
end
- screen:expect(no_menu_screen)
eq('bar', api.nvim_get_var('menustr'))
- local no_sel_screen ---@type string|test.function.ui.screen.Expect
+ command([[let g:menustr = '']])
+ screen:try_resize(32, 9)
+ command('wincmd t | 4vsplit | wincmd l | topleft 1split')
+ if multigrid then
+ no_menu_screen = [[
+ ## grid 1
+ [8:--------------------------------]|
+ {4:[No Name] [+] }|
+ [7:----]│[2:---------------------------]|*2
+ {3:<+] [No Name] [+] }|
+ [5:---------------]│[6:----------------]|*3
+ [3:--------------------------------]|
+ ## grid 2
+ popup menu test |
+ {1:~ }|
+ ## grid 3
+ |
+ ## grid 5
+ popup menu test|
+ {1:~ }|*2
+ ## grid 6
+ {2:WINBAR }|
+ popup menu test |
+ {1:~ }|
+ ## grid 7
+ popu|
+ p me|
+ ## grid 8
+ ^popup menu test |
+ ]]
+ else
+ no_menu_screen = [[
+ ^popup menu test |
+ {4:[No Name] [+] }|
+ popu│popup menu test |
+ p me│{1:~ }|
+ {3:<+] [No Name] [+] }|
+ popup menu test│{2:WINBAR }|
+ {1:~ }│popup menu test |
+ {1:~ }│{1:~ }|
+ |
+ ]]
+ end
+ screen:expect(no_menu_screen)
+
if multigrid then
no_sel_screen = {
grid = [[
## grid 1
- [2:--------------------------------]|*2
- {3:[No Name] [+] }|
- [5:---------------]│[6:----------------]|*2
+ [8:--------------------------------]|
+ {4:[No Name] [+] }|
+ [7:----]│[2:---------------------------]|*2
+ {3:<+] [No Name] [+] }|
+ [5:---------------]│[6:----------------]|*3
[3:--------------------------------]|
## grid 2
- popup menu test |
- {1:~ }|
+ popup menu test |
+ {1:~ }|
## grid 3
- :let g:menustr = 'bar' |
+ |
## grid 4
{n: foo }|
{n: bar }|
{n: baz }|
## grid 5
popup menu test|
- {1:~ }|
+ {1:~ }|*2
## grid 6
{2:WINBAR }|
- ^popup menu test |
+ popup menu test |
+ {1:~ }|
+ ## grid 7
+ popu|
+ p me|
+ ## grid 8
+ ^popup menu test |
]],
- float_pos = { [4] = { -1, 'NW', 1, 1, 19, false, 250, 2, 1, 19 } },
+ float_pos = { [4] = { -1, 'NW', 1, 1, 14, false, 250, 2, 1, 14 } },
}
else
no_sel_screen = {
grid = [[
- popup menu test |
- {1:~ }{n: foo }{1: }|
- {3:[No Name] [+] }{n: bar }{3: }|
+ ^popup menu test |
+ {4:[No Name] [+] }|
+ popu│popup menu test |
+ p me│{1:~ }{n: foo }{1: }|
+ {3:<+] [No Name] [+] }{n: bar }{3: }|
popup menu test│{2:WIN}{n: baz }{2: }|
- {1:~ }│^popup menu test |
- :let g:menustr = 'bar' |
+ {1:~ }│popup menu test |
+ {1:~ }│{1:~ }|
+ |
]],
}
end
- local sel_screens = {} ---@type (string|test.function.ui.screen.Expect)[]
- for i, s in ipairs({ 'foo', 'bar', 'baz' }) do
- local sel_screen = vim.deepcopy(no_sel_screen)
- local grid = assert(sel_screen.grid)
- grid = grid:gsub(vim.pesc(('{n: %s }'):format(s)), ('{s: %s }'):format(s))
- sel_screen.grid = grid
- sel_screens[i] = sel_screen
+
+ local pos = {
+ { 0, 2, 20 },
+ { 0, 3, 19 },
+ { 0, 3, 18 },
+ { 0, 4, 23 },
+ { 0, 4, 24 },
+ { 0, 5, 19 },
+ { 0, 5, 18 },
+ }
+ if multigrid then
+ for i = 1, 7 do
+ local _, row, col = unpack(pos[i])
+ pos[i] = { 1, row - 2, col - 5 }
+ end
end
- command([[let g:menustr = '']])
- local g = multigrid and 1 or 0
+ api.nvim_input_mouse('right', 'press', '', unpack(pos[1]))
+ screen:expect(no_sel_screen)
+ api.nvim_input_mouse('right', 'drag', '', unpack(pos[2]))
+ screen:expect(screen_replace(no_sel_screen, '{n: foo }', '{s: foo }'))
+ api.nvim_input_mouse('right', 'drag', '', unpack(pos[3]))
+ screen:expect(no_sel_screen)
+ api.nvim_input_mouse('right', 'drag', '', unpack(pos[4]))
+ screen:expect(screen_replace(no_sel_screen, '{n: bar }', '{s: bar }'))
+ api.nvim_input_mouse('right', 'drag', '', unpack(pos[5]))
+ screen:expect(no_sel_screen)
+ api.nvim_input_mouse('right', 'drag', '', unpack(pos[6]))
+ screen:expect(screen_replace(no_sel_screen, '{n: baz }', '{s: baz }'))
+ api.nvim_input_mouse('right', 'release', '', unpack(pos[7]))
+ screen:expect(no_sel_screen)
+ api.nvim_input_mouse('left', 'press', '', unpack(pos[7]))
+ screen:expect(no_menu_screen)
+ eq('', api.nvim_get_var('menustr'))
+
+ if multigrid then
+ for i = 2, 6, 2 do
+ local _, row, col = unpack(pos[i])
+ pos[i] = { 4, row - 1, col - 14 }
+ end
+ end
- api.nvim_input_mouse('right', 'press', '', g, 0, 20)
+ api.nvim_input_mouse('right', 'press', '', unpack(pos[1]))
screen:expect(no_sel_screen)
- api.nvim_input_mouse('move', '', '', g, 1, 19)
- screen:expect(sel_screens[1])
- api.nvim_input_mouse('move', '', '', g, 1, 18)
+ api.nvim_input_mouse('move', '', '', unpack(pos[2]))
+ screen:expect(screen_replace(no_sel_screen, '{n: foo }', '{s: foo }'))
+ api.nvim_input_mouse('move', '', '', unpack(pos[3]))
screen:expect(no_sel_screen)
- api.nvim_input_mouse('move', '', '', g, 2, 23)
- screen:expect(sel_screens[2])
- api.nvim_input_mouse('move', '', '', g, 2, 24)
+ api.nvim_input_mouse('move', '', '', unpack(pos[4]))
+ screen:expect(screen_replace(no_sel_screen, '{n: bar }', '{s: bar }'))
+ api.nvim_input_mouse('move', '', '', unpack(pos[5]))
screen:expect(no_sel_screen)
- api.nvim_input_mouse('move', '', '', g, 3, 19)
- screen:expect(sel_screens[3])
- api.nvim_input_mouse('left', 'press', '', g, 3, 18)
+ api.nvim_input_mouse('move', '', '', unpack(pos[6]))
+ screen:expect(screen_replace(no_sel_screen, '{n: baz }', '{s: baz }'))
+ api.nvim_input_mouse('left', 'press', '', unpack(pos[7]))
screen:expect(no_menu_screen)
eq('', api.nvim_get_var('menustr'))
- command('wincmd t | set rightleft')
+ command('set rightleft | wincmd p | set rightleft | wincmd p')
if multigrid then
- no_menu_screen = {
- grid = [[
+ no_menu_screen = [[
## grid 1
- [2:--------------------------------]|*2
+ [8:--------------------------------]|
{4:[No Name] [+] }|
- [5:---------------]│[6:----------------]|*2
+ [7:----]│[2:---------------------------]|*2
+ {3:<+] [No Name] [+] }|
+ [5:---------------]│[6:----------------]|*3
[3:--------------------------------]|
## grid 2
- tset unem pupo^p|
- {1: ~}|
+ tset unem pupop|
+ {1: ~}|
## grid 3
- :let g:menustr = 'bar' |
+ |
## grid 5
popup menu test|
- {1:~ }|
+ {1:~ }|*2
## grid 6
{2:WINBAR }|
popup menu test |
- ]],
- }
+ {1:~ }|
+ ## grid 7
+ popu|
+ p me|
+ ## grid 8
+ tset unem pupo^p|
+ ]]
else
- no_menu_screen = {
- grid = [[
+ no_menu_screen = [[
tset unem pupo^p|
- {1: ~}|
{4:[No Name] [+] }|
+ popu│ tset unem pupop|
+ p me│{1: ~}|
+ {3:<+] [No Name] [+] }|
popup menu test│{2:WINBAR }|
{1:~ }│popup menu test |
- :let g:menustr = 'bar' |
- ]],
- }
+ {1:~ }│{1:~ }|
+ |
+ ]]
end
screen:expect(no_menu_screen)
@@ -7471,64 +7389,108 @@ describe('builtin popupmenu', function()
no_sel_screen = {
grid = [[
## grid 1
- [2:--------------------------------]|*2
+ [8:--------------------------------]|
{4:[No Name] [+] }|
- [5:---------------]│[6:----------------]|*2
+ [7:----]│[2:---------------------------]|*2
+ {3:<+] [No Name] [+] }|
+ [5:---------------]│[6:----------------]|*3
[3:--------------------------------]|
## grid 2
- tset unem pupo^p|
- {1: ~}|
+ tset unem pupop|
+ {1: ~}|
## grid 3
- :let g:menustr = 'bar' |
+ |
## grid 4
{n: oof }|
{n: rab }|
{n: zab }|
## grid 5
popup menu test|
- {1:~ }|
+ {1:~ }|*2
## grid 6
{2:WINBAR }|
popup menu test |
+ {1:~ }|
+ ## grid 7
+ popu|
+ p me|
+ ## grid 8
+ tset unem pupo^p|
]],
- float_pos = { [4] = { -1, 'NW', 1, 1, 17, false, 250, 2, 1, 17 } },
+ float_pos = { [4] = { -1, 'NW', 1, 1, 12, false, 250, 2, 1, 12 } },
}
else
no_sel_screen = {
grid = [[
tset unem pupo^p|
- {1: }{n: oof }{1: ~}|
- {4:[No Name] [+] }{n: rab }{4: }|
+ {4:[No Name] [+] }|
+ popu│ tset unem pupop|
+ p me│{1: }{n: oof }{1: ~}|
+ {3:<+] [No Name] [+}{n: rab }{3: }|
popup menu test│{2:W}{n: zab }{2: }|
{1:~ }│popup menu test |
- :let g:menustr = 'bar' |
+ {1:~ }│{1:~ }|
+ |
]],
}
end
- for i, s in ipairs({ 'oof', 'rab', 'zab' }) do
- local sel_screen = vim.deepcopy(no_sel_screen)
- local grid = assert(sel_screen.grid)
- grid = grid:gsub(vim.pesc(('{n: %s }'):format(s)), ('{s: %s }'):format(s))
- sel_screen.grid = grid
- sel_screens[i] = sel_screen
+
+ pos = {
+ { 0, 2, 20 },
+ { 0, 3, 21 },
+ { 0, 3, 22 },
+ { 0, 4, 17 },
+ { 0, 4, 16 },
+ { 0, 5, 21 },
+ { 0, 5, 22 },
+ }
+ if multigrid then
+ for i = 1, 7 do
+ local _, row, col = unpack(pos[i])
+ pos[i] = { 1, row - 2, col - 5 }
+ end
end
- api.nvim_input_mouse('right', 'press', '', g, 0, 20)
+ api.nvim_input_mouse('right', 'press', '', unpack(pos[1]))
screen:expect(no_sel_screen)
- api.nvim_input_mouse('move', '', '', g, 1, 21)
- screen:expect(sel_screens[1])
- api.nvim_input_mouse('move', '', '', g, 1, 22)
+ api.nvim_input_mouse('move', '', '', unpack(pos[2]))
+ screen:expect(screen_replace(no_sel_screen, '{n: oof }', '{s: oof }'))
+ api.nvim_input_mouse('move', '', '', unpack(pos[3]))
screen:expect(no_sel_screen)
- api.nvim_input_mouse('move', '', '', g, 2, 17)
- screen:expect(sel_screens[2])
- api.nvim_input_mouse('move', '', '', g, 2, 16)
+ api.nvim_input_mouse('move', '', '', unpack(pos[4]))
+ screen:expect(screen_replace(no_sel_screen, '{n: rab }', '{s: rab }'))
+ api.nvim_input_mouse('move', '', '', unpack(pos[5]))
screen:expect(no_sel_screen)
- api.nvim_input_mouse('move', '', '', g, 3, 21)
- screen:expect(sel_screens[3])
- api.nvim_input_mouse('left', 'press', '', g, 3, 22)
+ api.nvim_input_mouse('move', '', '', unpack(pos[6]))
+ screen:expect(screen_replace(no_sel_screen, '{n: zab }', '{s: zab }'))
+ api.nvim_input_mouse('left', 'press', '', unpack(pos[7]))
screen:expect(no_menu_screen)
eq('', api.nvim_get_var('menustr'))
+ if multigrid then
+ for i = 2, 6, 2 do
+ local _, row, col = unpack(pos[i])
+ pos[i] = { 4, row - 1, col - 12 }
+ end
+ end
+
+ api.nvim_input_mouse('right', 'press', '', unpack(pos[1]))
+ screen:expect(no_sel_screen)
+ api.nvim_input_mouse('right', 'drag', '', unpack(pos[2]))
+ screen:expect(screen_replace(no_sel_screen, '{n: oof }', '{s: oof }'))
+ api.nvim_input_mouse('right', 'drag', '', unpack(pos[3]))
+ screen:expect(no_sel_screen)
+ api.nvim_input_mouse('right', 'drag', '', unpack(pos[4]))
+ screen:expect(screen_replace(no_sel_screen, '{n: rab }', '{s: rab }'))
+ api.nvim_input_mouse('right', 'drag', '', unpack(pos[5]))
+ screen:expect(no_sel_screen)
+ api.nvim_input_mouse('right', 'drag', '', unpack(pos[6]))
+ screen:expect(screen_replace(no_sel_screen, '{n: zab }', '{s: zab }'))
+ api.nvim_input_mouse('right', 'release', '', unpack(pos[7]))
+ screen:expect(no_sel_screen)
+ api.nvim_input_mouse('left', 'press', '', unpack(pos[7]))
+ eq('', api.nvim_get_var('menustr'))
+
command('set norightleft')
end)