mirror of
https://github.com/neovim/neovim.git
synced 2024-12-24 21:25:04 -07:00
091eb4c8c7
Problem: Wrong cursor position when clicking after end of line with 'virtualedit', conceal and virtual text. Solution: Always fill linebuf_vcol[] for the columns to clear.
2005 lines
68 KiB
Lua
2005 lines
68 KiB
Lua
local helpers = require('test.functional.helpers')(after_each)
|
|
local Screen = require('test.functional.ui.screen')
|
|
local clear, feed, api = helpers.clear, helpers.feed, helpers.api
|
|
local insert, feed_command = helpers.insert, helpers.feed_command
|
|
local eq, fn = helpers.eq, helpers.fn
|
|
local poke_eventloop = helpers.poke_eventloop
|
|
local command = helpers.command
|
|
local exec = helpers.exec
|
|
|
|
describe('ui/mouse/input', function()
|
|
local screen
|
|
|
|
before_each(function()
|
|
clear()
|
|
api.nvim_set_option_value('mouse', 'a', {})
|
|
api.nvim_set_option_value('list', true, {})
|
|
-- NB: this is weird, but mostly irrelevant to the test
|
|
-- So I didn't bother to change it
|
|
command('set listchars=eol:$')
|
|
command('setl listchars=nbsp:x')
|
|
screen = Screen.new(25, 5)
|
|
screen:attach()
|
|
screen:set_default_attr_ids({
|
|
[0] = { bold = true, foreground = Screen.colors.Blue },
|
|
[1] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Black },
|
|
[2] = { bold = true },
|
|
[3] = {
|
|
foreground = Screen.colors.Blue,
|
|
background = Screen.colors.LightGrey,
|
|
bold = true,
|
|
},
|
|
[4] = { reverse = true },
|
|
[5] = { bold = true, reverse = true },
|
|
[6] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red },
|
|
[7] = { bold = true, foreground = Screen.colors.SeaGreen4 },
|
|
[8] = { foreground = Screen.colors.Brown },
|
|
[9] = { background = Screen.colors.DarkGrey, foreground = Screen.colors.LightGrey },
|
|
})
|
|
command('set mousemodel=extend')
|
|
feed('itesting<cr>mouse<cr>support and selection<esc>')
|
|
screen:expect([[
|
|
testing |
|
|
mouse |
|
|
support and selectio^n |
|
|
{0:~ }|
|
|
|
|
|
]])
|
|
end)
|
|
|
|
it('single left click moves cursor', function()
|
|
feed('<LeftMouse><2,1>')
|
|
screen:expect {
|
|
grid = [[
|
|
testing |
|
|
mo^use |
|
|
support and selection |
|
|
{0:~ }|
|
|
|
|
|
]],
|
|
mouse_enabled = true,
|
|
}
|
|
feed('<LeftMouse><0,0>')
|
|
screen:expect([[
|
|
^testing |
|
|
mouse |
|
|
support and selection |
|
|
{0:~ }|
|
|
|
|
|
]])
|
|
end)
|
|
|
|
it("in external ui works with unset 'mouse'", function()
|
|
api.nvim_set_option_value('mouse', '', {})
|
|
feed('<LeftMouse><2,1>')
|
|
screen:expect {
|
|
grid = [[
|
|
testing |
|
|
mo^use |
|
|
support and selection |
|
|
{0:~ }|
|
|
|
|
|
]],
|
|
mouse_enabled = false,
|
|
}
|
|
feed('<LeftMouse><0,0>')
|
|
screen:expect([[
|
|
^testing |
|
|
mouse |
|
|
support and selection |
|
|
{0:~ }|
|
|
|
|
|
]])
|
|
end)
|
|
|
|
it('double left click enters visual mode', function()
|
|
feed('<LeftMouse><0,0>')
|
|
feed('<LeftRelease><0,0>')
|
|
feed('<LeftMouse><0,0>')
|
|
feed('<LeftRelease><0,0>')
|
|
screen:expect([[
|
|
{1:testin}^g |
|
|
mouse |
|
|
support and selection |
|
|
{0:~ }|
|
|
{2:-- VISUAL --} |
|
|
]])
|
|
end)
|
|
|
|
it('triple left click enters visual line mode', function()
|
|
feed('<LeftMouse><0,0>')
|
|
feed('<LeftRelease><0,0>')
|
|
feed('<LeftMouse><0,0>')
|
|
feed('<LeftRelease><0,0>')
|
|
feed('<LeftMouse><0,0>')
|
|
feed('<LeftRelease><0,0>')
|
|
screen:expect([[
|
|
^t{1:esting} |
|
|
mouse |
|
|
support and selection |
|
|
{0:~ }|
|
|
{2:-- VISUAL LINE --} |
|
|
]])
|
|
end)
|
|
|
|
it('quadruple left click enters visual block mode', function()
|
|
feed('<LeftMouse><0,0>')
|
|
feed('<LeftRelease><0,0>')
|
|
feed('<LeftMouse><0,0>')
|
|
feed('<LeftRelease><0,0>')
|
|
feed('<LeftMouse><0,0>')
|
|
feed('<LeftRelease><0,0>')
|
|
feed('<LeftMouse><0,0>')
|
|
feed('<LeftRelease><0,0>')
|
|
screen:expect([[
|
|
^testing |
|
|
mouse |
|
|
support and selection |
|
|
{0:~ }|
|
|
{2:-- VISUAL BLOCK --} |
|
|
]])
|
|
end)
|
|
|
|
describe('tab drag', function()
|
|
before_each(function()
|
|
screen:set_default_attr_ids({
|
|
[0] = { bold = true, foreground = Screen.colors.Blue },
|
|
tab = { background = Screen.colors.LightGrey, underline = true },
|
|
sel = { bold = true },
|
|
fill = { reverse = true },
|
|
})
|
|
end)
|
|
|
|
it('in tabline on filler space moves tab to the end', function()
|
|
feed_command('%delete')
|
|
insert('this is foo')
|
|
feed_command('silent file foo | tabnew | file bar')
|
|
insert('this is bar')
|
|
screen:expect([[
|
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
|
this is ba^r{0:$} |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
feed('<LeftMouse><4,0>')
|
|
screen:expect([[
|
|
{sel: + foo }{tab: + bar }{fill: }{tab:X}|
|
|
this is fo^o |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
feed('<LeftDrag><14,0>')
|
|
screen:expect([[
|
|
{tab: + bar }{sel: + foo }{fill: }{tab:X}|
|
|
this is fo^o |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
end)
|
|
|
|
it('in tabline to the left moves tab left', function()
|
|
feed_command('%delete')
|
|
insert('this is foo')
|
|
feed_command('silent file foo | tabnew | file bar')
|
|
insert('this is bar')
|
|
screen:expect([[
|
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
|
this is ba^r{0:$} |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
feed('<LeftMouse><11,0>')
|
|
-- Prevent the case where screen:expect() with "unchanged" returns too early,
|
|
-- causing the click position to be overwritten by the next drag.
|
|
poke_eventloop()
|
|
screen:expect {
|
|
grid = [[
|
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
|
this is ba^r{0:$} |
|
|
{0:~ }|*2
|
|
|
|
|
]],
|
|
unchanged = true,
|
|
}
|
|
feed('<LeftDrag><6,0>')
|
|
screen:expect([[
|
|
{sel: + bar }{tab: + foo }{fill: }{tab:X}|
|
|
this is ba^r{0:$} |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
end)
|
|
|
|
it('in tabline to the right moves tab right', function()
|
|
feed_command('%delete')
|
|
insert('this is foo')
|
|
feed_command('silent file foo | tabnew | file bar')
|
|
insert('this is bar')
|
|
screen:expect([[
|
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
|
this is ba^r{0:$} |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
feed('<LeftMouse><4,0>')
|
|
screen:expect([[
|
|
{sel: + foo }{tab: + bar }{fill: }{tab:X}|
|
|
this is fo^o |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
feed('<LeftDrag><7,0>')
|
|
screen:expect([[
|
|
{tab: + bar }{sel: + foo }{fill: }{tab:X}|
|
|
this is fo^o |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
end)
|
|
|
|
it('out of tabline under filler space moves tab to the end', function()
|
|
feed_command('%delete')
|
|
insert('this is foo')
|
|
feed_command('silent file foo | tabnew | file bar')
|
|
insert('this is bar')
|
|
screen:expect([[
|
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
|
this is ba^r{0:$} |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
feed('<LeftMouse><4,0>')
|
|
screen:expect([[
|
|
{sel: + foo }{tab: + bar }{fill: }{tab:X}|
|
|
this is fo^o |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
feed('<LeftDrag><4,1>')
|
|
screen:expect {
|
|
grid = [[
|
|
{sel: + foo }{tab: + bar }{fill: }{tab:X}|
|
|
this is fo^o |
|
|
{0:~ }|*2
|
|
|
|
|
]],
|
|
unchanged = true,
|
|
}
|
|
feed('<LeftDrag><14,1>')
|
|
screen:expect([[
|
|
{tab: + bar }{sel: + foo }{fill: }{tab:X}|
|
|
this is fo^o |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
end)
|
|
|
|
it('out of tabline to the left moves tab left', function()
|
|
feed_command('%delete')
|
|
insert('this is foo')
|
|
feed_command('silent file foo | tabnew | file bar')
|
|
insert('this is bar')
|
|
screen:expect([[
|
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
|
this is ba^r{0:$} |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
feed('<LeftMouse><11,0>')
|
|
-- Prevent the case where screen:expect() with "unchanged" returns too early,
|
|
-- causing the click position to be overwritten by the next drag.
|
|
poke_eventloop()
|
|
screen:expect {
|
|
grid = [[
|
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
|
this is ba^r{0:$} |
|
|
{0:~ }|*2
|
|
|
|
|
]],
|
|
unchanged = true,
|
|
}
|
|
feed('<LeftDrag><11,1>')
|
|
screen:expect {
|
|
grid = [[
|
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
|
this is ba^r{0:$} |
|
|
{0:~ }|*2
|
|
|
|
|
]],
|
|
unchanged = true,
|
|
}
|
|
feed('<LeftDrag><6,1>')
|
|
screen:expect([[
|
|
{sel: + bar }{tab: + foo }{fill: }{tab:X}|
|
|
this is ba^r{0:$} |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
end)
|
|
|
|
it('out of tabline to the right moves tab right', function()
|
|
feed_command('%delete')
|
|
insert('this is foo')
|
|
feed_command('silent file foo | tabnew | file bar')
|
|
insert('this is bar')
|
|
screen:expect([[
|
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
|
this is ba^r{0:$} |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
feed('<LeftMouse><4,0>')
|
|
screen:expect([[
|
|
{sel: + foo }{tab: + bar }{fill: }{tab:X}|
|
|
this is fo^o |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
feed('<LeftDrag><4,1>')
|
|
screen:expect {
|
|
grid = [[
|
|
{sel: + foo }{tab: + bar }{fill: }{tab:X}|
|
|
this is fo^o |
|
|
{0:~ }|*2
|
|
|
|
|
]],
|
|
unchanged = true,
|
|
}
|
|
feed('<LeftDrag><7,1>')
|
|
screen:expect([[
|
|
{tab: + bar }{sel: + foo }{fill: }{tab:X}|
|
|
this is fo^o |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
end)
|
|
end)
|
|
|
|
describe('tabline', function()
|
|
before_each(function()
|
|
screen:set_default_attr_ids({
|
|
[0] = { bold = true, foreground = Screen.colors.Blue },
|
|
tab = { background = Screen.colors.LightGrey, underline = true },
|
|
sel = { bold = true },
|
|
fill = { reverse = true },
|
|
})
|
|
end)
|
|
|
|
it('left click in default tabline (position 4) switches to tab', function()
|
|
feed_command('%delete')
|
|
insert('this is foo')
|
|
feed_command('silent file foo | tabnew | file bar')
|
|
insert('this is bar')
|
|
screen:expect([[
|
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
|
this is ba^r{0:$} |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
feed('<LeftMouse><4,0>')
|
|
screen:expect([[
|
|
{sel: + foo }{tab: + bar }{fill: }{tab:X}|
|
|
this is fo^o |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
end)
|
|
|
|
it('left click in default tabline (position 24) closes tab', function()
|
|
api.nvim_set_option_value('hidden', true, {})
|
|
feed_command('%delete')
|
|
insert('this is foo')
|
|
feed_command('silent file foo | tabnew | file bar')
|
|
insert('this is bar')
|
|
screen:expect([[
|
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
|
this is ba^r{0:$} |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
feed('<LeftMouse><24,0>')
|
|
screen:expect([[
|
|
this is fo^o |
|
|
{0:~ }|*3
|
|
|
|
|
]])
|
|
end)
|
|
|
|
it('double click in default tabline (position 4) opens new tab', function()
|
|
api.nvim_set_option_value('hidden', true, {})
|
|
feed_command('%delete')
|
|
insert('this is foo')
|
|
feed_command('silent file foo | tabnew | file bar')
|
|
insert('this is bar')
|
|
screen:expect([[
|
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
|
this is ba^r{0:$} |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
feed('<2-LeftMouse><4,0>')
|
|
screen:expect([[
|
|
{sel: Name] }{tab: + foo + bar }{fill: }{tab:X}|
|
|
{0:^$} |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
end)
|
|
|
|
describe('%@ label', function()
|
|
before_each(function()
|
|
feed_command([[
|
|
function Test(...)
|
|
let g:reply = a:000
|
|
return copy(a:000) " Check for memory leaks: return should be freed
|
|
endfunction
|
|
]])
|
|
feed_command([[
|
|
function Test2(...)
|
|
return call('Test', a:000 + [2])
|
|
endfunction
|
|
]])
|
|
api.nvim_set_option_value('tabline', '%@Test@test%X-%5@Test2@test2', {})
|
|
api.nvim_set_option_value('showtabline', 2, {})
|
|
screen:expect([[
|
|
{fill:test-test2 }|
|
|
testing |
|
|
mouse |
|
|
support and selectio^n |
|
|
|
|
|
]])
|
|
api.nvim_set_var('reply', {})
|
|
end)
|
|
|
|
local check_reply = function(expected)
|
|
eq(expected, api.nvim_get_var('reply'))
|
|
api.nvim_set_var('reply', {})
|
|
end
|
|
|
|
local test_click = function(name, click_str, click_num, mouse_button, modifiers)
|
|
local function doit(do_click)
|
|
eq(1, fn.has('tablineat'))
|
|
do_click(0, 3)
|
|
check_reply({ 0, click_num, mouse_button, modifiers })
|
|
do_click(0, 4)
|
|
check_reply({})
|
|
do_click(0, 6)
|
|
check_reply({ 5, click_num, mouse_button, modifiers, 2 })
|
|
do_click(0, 13)
|
|
check_reply({ 5, click_num, mouse_button, modifiers, 2 })
|
|
end
|
|
|
|
it(name .. ' works (pseudokey)', function()
|
|
doit(function(row, col)
|
|
feed(click_str .. '<' .. col .. ',' .. row .. '>')
|
|
end)
|
|
end)
|
|
|
|
it(name .. ' works (nvim_input_mouse)', function()
|
|
doit(function(row, col)
|
|
local buttons = { l = 'left', m = 'middle', r = 'right' }
|
|
local modstr = (click_num > 1) and tostring(click_num) or ''
|
|
for char in string.gmatch(modifiers, '%w') do
|
|
modstr = modstr .. char .. '-' -- - not needed but should be accepted
|
|
end
|
|
api.nvim_input_mouse(buttons[mouse_button], 'press', modstr, 0, row, col)
|
|
end)
|
|
end)
|
|
end
|
|
|
|
test_click('single left click', '<LeftMouse>', 1, 'l', ' ')
|
|
test_click('shifted single left click', '<S-LeftMouse>', 1, 'l', 's ')
|
|
test_click('shifted single left click with alt modifier', '<S-A-LeftMouse>', 1, 'l', 's a ')
|
|
test_click(
|
|
'shifted single left click with alt and ctrl modifiers',
|
|
'<S-C-A-LeftMouse>',
|
|
1,
|
|
'l',
|
|
'sca '
|
|
)
|
|
-- <C-RightMouse> does not work
|
|
test_click('shifted single right click with alt modifier', '<S-A-RightMouse>', 1, 'r', 's a ')
|
|
-- Modifiers do not work with MiddleMouse
|
|
test_click(
|
|
'shifted single middle click with alt and ctrl modifiers',
|
|
'<MiddleMouse>',
|
|
1,
|
|
'm',
|
|
' '
|
|
)
|
|
-- Modifiers do not work with N-*Mouse
|
|
test_click('double left click', '<2-LeftMouse>', 2, 'l', ' ')
|
|
test_click('triple left click', '<3-LeftMouse>', 3, 'l', ' ')
|
|
test_click('quadruple left click', '<4-LeftMouse>', 4, 'l', ' ')
|
|
test_click('double right click', '<2-RightMouse>', 2, 'r', ' ')
|
|
test_click('triple right click', '<3-RightMouse>', 3, 'r', ' ')
|
|
test_click('quadruple right click', '<4-RightMouse>', 4, 'r', ' ')
|
|
test_click('double middle click', '<2-MiddleMouse>', 2, 'm', ' ')
|
|
test_click('triple middle click', '<3-MiddleMouse>', 3, 'm', ' ')
|
|
test_click('quadruple middle click', '<4-MiddleMouse>', 4, 'm', ' ')
|
|
end)
|
|
end)
|
|
|
|
it('left drag changes visual selection', function()
|
|
-- drag events must be preceded by a click
|
|
feed('<LeftMouse><2,1>')
|
|
screen:expect([[
|
|
testing |
|
|
mo^use |
|
|
support and selection |
|
|
{0:~ }|
|
|
|
|
|
]])
|
|
feed('<LeftDrag><4,1>')
|
|
screen:expect([[
|
|
testing |
|
|
mo{1:us}^e |
|
|
support and selection |
|
|
{0:~ }|
|
|
{2:-- VISUAL --} |
|
|
]])
|
|
feed('<LeftDrag><2,2>')
|
|
screen:expect([[
|
|
testing |
|
|
mo{1:use} |
|
|
{1:su}^pport and selection |
|
|
{0:~ }|
|
|
{2:-- VISUAL --} |
|
|
]])
|
|
feed('<LeftDrag><0,0>')
|
|
screen:expect([[
|
|
^t{1:esting} |
|
|
{1:mou}se |
|
|
support and selection |
|
|
{0:~ }|
|
|
{2:-- VISUAL --} |
|
|
]])
|
|
end)
|
|
|
|
it('left drag changes visual selection after tab click', function()
|
|
screen:set_default_attr_ids({
|
|
[0] = { bold = true, foreground = Screen.colors.Blue },
|
|
tab = { background = Screen.colors.LightGrey, underline = true },
|
|
sel = { bold = true },
|
|
fill = { reverse = true },
|
|
vis = { background = Screen.colors.LightGrey, foreground = Screen.colors.Black },
|
|
})
|
|
feed_command('silent file foo | tabnew | file bar')
|
|
insert('this is bar')
|
|
feed_command('tabprevious') -- go to first tab
|
|
screen:expect([[
|
|
{sel: + foo }{tab: + bar }{fill: }{tab:X}|
|
|
testing |
|
|
mouse |
|
|
support and selectio^n |
|
|
:tabprevious |
|
|
]])
|
|
feed('<LeftMouse><10,0><LeftRelease>') -- go to second tab
|
|
helpers.poke_eventloop()
|
|
feed('<LeftMouse><0,1>')
|
|
screen:expect([[
|
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
|
^this is bar{0:$} |
|
|
{0:~ }|*2
|
|
:tabprevious |
|
|
]])
|
|
feed('<LeftDrag><4,1>')
|
|
screen:expect([[
|
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
|
{vis:this}^ is bar{0:$} |
|
|
{0:~ }|*2
|
|
{sel:-- VISUAL --} |
|
|
]])
|
|
end)
|
|
|
|
it('left drag changes visual selection in split layout', function()
|
|
screen:try_resize(53, 14)
|
|
command('set mouse=a')
|
|
command('vsplit')
|
|
command('wincmd l')
|
|
command('below split')
|
|
command('enew')
|
|
feed('ifoo\nbar<esc>')
|
|
|
|
screen:expect {
|
|
grid = [[
|
|
testing │testing |
|
|
mouse │mouse |
|
|
support and selection │support and selection |
|
|
{0:~ }│{0:~ }|*2
|
|
{0:~ }│{4:[No Name] [+] }|
|
|
{0:~ }│foo{0:$} |
|
|
{0:~ }│ba^r{0:$} |
|
|
{0:~ }│{0:~ }|*4
|
|
{4:[No Name] [+] }{5:[No Name] [+] }|
|
|
|
|
|
]],
|
|
}
|
|
|
|
api.nvim_input_mouse('left', 'press', '', 0, 6, 27)
|
|
screen:expect {
|
|
grid = [[
|
|
testing │testing |
|
|
mouse │mouse |
|
|
support and selection │support and selection |
|
|
{0:~ }│{0:~ }|*2
|
|
{0:~ }│{4:[No Name] [+] }|
|
|
{0:~ }│^foo{0:$} |
|
|
{0:~ }│bar{0:$} |
|
|
{0:~ }│{0:~ }|*4
|
|
{4:[No Name] [+] }{5:[No Name] [+] }|
|
|
|
|
|
]],
|
|
}
|
|
api.nvim_input_mouse('left', 'drag', '', 0, 7, 30)
|
|
|
|
screen:expect {
|
|
grid = [[
|
|
testing │testing |
|
|
mouse │mouse |
|
|
support and selection │support and selection |
|
|
{0:~ }│{0:~ }|*2
|
|
{0:~ }│{4:[No Name] [+] }|
|
|
{0:~ }│{1:foo}{3:$} |
|
|
{0:~ }│{1:bar}{0:^$} |
|
|
{0:~ }│{0:~ }|*4
|
|
{4:[No Name] [+] }{5:[No Name] [+] }|
|
|
{2:-- VISUAL --} |
|
|
]],
|
|
}
|
|
end)
|
|
|
|
it('two clicks will enter VISUAL and dragging selects words', function()
|
|
feed('<LeftMouse><2,2>')
|
|
feed('<LeftRelease><2,2>')
|
|
feed('<LeftMouse><2,2>')
|
|
screen:expect([[
|
|
testing |
|
|
mouse |
|
|
{1:suppor}^t and selection |
|
|
{0:~ }|
|
|
{2:-- VISUAL --} |
|
|
]])
|
|
feed('<LeftDrag><0,1>')
|
|
screen:expect([[
|
|
testing |
|
|
^m{1:ouse} |
|
|
{1:support} and selection |
|
|
{0:~ }|
|
|
{2:-- VISUAL --} |
|
|
]])
|
|
feed('<LeftDrag><4,0>')
|
|
screen:expect([[
|
|
^t{1:esting} |
|
|
{1:mouse} |
|
|
{1:support} and selection |
|
|
{0:~ }|
|
|
{2:-- VISUAL --} |
|
|
]])
|
|
feed('<LeftDrag><14,2>')
|
|
screen:expect([[
|
|
testing |
|
|
mouse |
|
|
{1:support and selectio}^n |
|
|
{0:~ }|
|
|
{2:-- VISUAL --} |
|
|
]])
|
|
end)
|
|
|
|
it('three clicks will enter VISUAL LINE and dragging selects lines', function()
|
|
feed('<LeftMouse><2,2>')
|
|
feed('<LeftRelease><2,2>')
|
|
feed('<LeftMouse><2,2>')
|
|
feed('<LeftRelease><2,2>')
|
|
feed('<LeftMouse><2,2>')
|
|
screen:expect([[
|
|
testing |
|
|
mouse |
|
|
{1:su}^p{1:port and selection} |
|
|
{0:~ }|
|
|
{2:-- VISUAL LINE --} |
|
|
]])
|
|
feed('<LeftDrag><0,1>')
|
|
screen:expect([[
|
|
testing |
|
|
^m{1:ouse} |
|
|
{1:support and selection} |
|
|
{0:~ }|
|
|
{2:-- VISUAL LINE --} |
|
|
]])
|
|
feed('<LeftDrag><4,0>')
|
|
screen:expect([[
|
|
{1:test}^i{1:ng} |
|
|
{1:mouse} |
|
|
{1:support and selection} |
|
|
{0:~ }|
|
|
{2:-- VISUAL LINE --} |
|
|
]])
|
|
feed('<LeftDrag><14,2>')
|
|
screen:expect([[
|
|
testing |
|
|
mouse |
|
|
{1:support and se}^l{1:ection} |
|
|
{0:~ }|
|
|
{2:-- VISUAL LINE --} |
|
|
]])
|
|
end)
|
|
|
|
it('four clicks will enter VISUAL BLOCK and dragging selects blockwise', function()
|
|
feed('<LeftMouse><2,2>')
|
|
feed('<LeftRelease><2,2>')
|
|
feed('<LeftMouse><2,2>')
|
|
feed('<LeftRelease><2,2>')
|
|
feed('<LeftMouse><2,2>')
|
|
feed('<LeftRelease><2,2>')
|
|
feed('<LeftMouse><2,2>')
|
|
screen:expect([[
|
|
testing |
|
|
mouse |
|
|
su^pport and selection |
|
|
{0:~ }|
|
|
{2:-- VISUAL BLOCK --} |
|
|
]])
|
|
feed('<LeftDrag><0,1>')
|
|
screen:expect([[
|
|
testing |
|
|
^m{1:ou}se |
|
|
{1:sup}port and selection |
|
|
{0:~ }|
|
|
{2:-- VISUAL BLOCK --} |
|
|
]])
|
|
feed('<LeftDrag><4,0>')
|
|
screen:expect([[
|
|
te{1:st}^ing |
|
|
mo{1:use} |
|
|
su{1:ppo}rt and selection |
|
|
{0:~ }|
|
|
{2:-- VISUAL BLOCK --} |
|
|
]])
|
|
feed('<LeftDrag><14,2>')
|
|
screen:expect([[
|
|
testing |
|
|
mouse |
|
|
su{1:pport and se}^lection |
|
|
{0:~ }|
|
|
{2:-- VISUAL BLOCK --} |
|
|
]])
|
|
end)
|
|
|
|
it('right click extends visual selection to the clicked location', function()
|
|
feed('<LeftMouse><0,0>')
|
|
screen:expect([[
|
|
^testing |
|
|
mouse |
|
|
support and selection |
|
|
{0:~ }|
|
|
|
|
|
]])
|
|
feed('<RightMouse><2,2>')
|
|
screen:expect([[
|
|
{1:testing} |
|
|
{1:mouse} |
|
|
{1:su}^pport and selection |
|
|
{0:~ }|
|
|
{2:-- VISUAL --} |
|
|
]])
|
|
end)
|
|
|
|
it('ctrl + left click will search for a tag', function()
|
|
api.nvim_set_option_value('tags', './non-existent-tags-file', {})
|
|
feed('<C-LeftMouse><0,0>')
|
|
screen:expect([[
|
|
{6:E433: No tags file} |
|
|
{6:E426: Tag not found: test}|
|
|
{6:ing} |
|
|
{7:Press ENTER or type comma}|
|
|
{7:nd to continue}^ |
|
|
]])
|
|
feed('<cr>')
|
|
end)
|
|
|
|
it('x1 and x2 can be triggered by api', function()
|
|
api.nvim_set_var('x1_pressed', 0)
|
|
api.nvim_set_var('x1_released', 0)
|
|
api.nvim_set_var('x2_pressed', 0)
|
|
api.nvim_set_var('x2_released', 0)
|
|
command('nnoremap <X1Mouse> <Cmd>let g:x1_pressed += 1<CR>')
|
|
command('nnoremap <X1Release> <Cmd>let g:x1_released += 1<CR>')
|
|
command('nnoremap <X2Mouse> <Cmd>let g:x2_pressed += 1<CR>')
|
|
command('nnoremap <X2Release> <Cmd>let g:x2_released += 1<CR>')
|
|
api.nvim_input_mouse('x1', 'press', '', 0, 0, 0)
|
|
api.nvim_input_mouse('x1', 'release', '', 0, 0, 0)
|
|
api.nvim_input_mouse('x2', 'press', '', 0, 0, 0)
|
|
api.nvim_input_mouse('x2', 'release', '', 0, 0, 0)
|
|
eq(1, api.nvim_get_var('x1_pressed'), 'x1 pressed once')
|
|
eq(1, api.nvim_get_var('x1_released'), 'x1 released once')
|
|
eq(1, api.nvim_get_var('x2_pressed'), 'x2 pressed once')
|
|
eq(1, api.nvim_get_var('x2_released'), 'x2 released once')
|
|
end)
|
|
|
|
it('dragging vertical separator', function()
|
|
screen:try_resize(45, 5)
|
|
command('setlocal nowrap')
|
|
local oldwin = api.nvim_get_current_win()
|
|
command('rightbelow vnew')
|
|
screen:expect([[
|
|
testing │{0:^$} |
|
|
mouse │{0:~ }|
|
|
support and selection │{0:~ }|
|
|
{4:[No Name] [+] }{5:[No Name] }|
|
|
|
|
|
]])
|
|
api.nvim_input_mouse('left', 'press', '', 0, 0, 22)
|
|
poke_eventloop()
|
|
api.nvim_input_mouse('left', 'drag', '', 0, 1, 12)
|
|
screen:expect([[
|
|
testing │{0:^$} |
|
|
mouse │{0:~ }|
|
|
support and │{0:~ }|
|
|
{4:< Name] [+] }{5:[No Name] }|
|
|
|
|
|
]])
|
|
api.nvim_input_mouse('left', 'drag', '', 0, 2, 2)
|
|
screen:expect([[
|
|
te│{0:^$} |
|
|
mo│{0:~ }|
|
|
su│{0:~ }|
|
|
{4:< }{5:[No Name] }|
|
|
|
|
|
]])
|
|
api.nvim_input_mouse('left', 'release', '', 0, 2, 2)
|
|
api.nvim_set_option_value('statuscolumn', 'foobar', { win = oldwin })
|
|
screen:expect([[
|
|
{8:fo}│{0:^$} |
|
|
{8:fo}│{0:~ }|*2
|
|
{4:< }{5:[No Name] }|
|
|
|
|
|
]])
|
|
api.nvim_input_mouse('left', 'press', '', 0, 0, 2)
|
|
poke_eventloop()
|
|
api.nvim_input_mouse('left', 'drag', '', 0, 1, 12)
|
|
screen:expect([[
|
|
{8:foobar}testin│{0:^$} |
|
|
{8:foobar}mouse │{0:~ }|
|
|
{8:foobar}suppor│{0:~ }|
|
|
{4:< Name] [+] }{5:[No Name] }|
|
|
|
|
|
]])
|
|
api.nvim_input_mouse('left', 'drag', '', 0, 2, 22)
|
|
screen:expect([[
|
|
{8:foobar}testing │{0:^$} |
|
|
{8:foobar}mouse │{0:~ }|
|
|
{8:foobar}support and sele│{0:~ }|
|
|
{4:[No Name] [+] }{5:[No Name] }|
|
|
|
|
|
]])
|
|
api.nvim_input_mouse('left', 'release', '', 0, 2, 22)
|
|
end)
|
|
|
|
local function wheel(use_api)
|
|
feed('ggdG')
|
|
insert([[
|
|
Inserting
|
|
text
|
|
with
|
|
many
|
|
lines
|
|
to
|
|
test
|
|
mouse scrolling
|
|
]])
|
|
screen:try_resize(53, 14)
|
|
feed('k')
|
|
feed_command('sp', 'vsp')
|
|
screen:expect([[
|
|
lines │lines |
|
|
to │to |
|
|
test │test |
|
|
^mouse scrolling │mouse scrolling |
|
|
│ |
|
|
{0:~ }│{0:~ }|
|
|
{5:[No Name] [+] }{4:[No Name] [+] }|
|
|
to |
|
|
test |
|
|
mouse scrolling |
|
|
|
|
|
{0:~ }|
|
|
{4:[No Name] [+] }|
|
|
:vsp |
|
|
]])
|
|
if use_api then
|
|
api.nvim_input_mouse('wheel', 'down', '', 0, 0, 0)
|
|
else
|
|
feed('<ScrollWheelDown><0,0>')
|
|
end
|
|
screen:expect([[
|
|
^mouse scrolling │lines |
|
|
│to |
|
|
{0:~ }│test |
|
|
{0:~ }│mouse scrolling |
|
|
{0:~ }│ |
|
|
{0:~ }│{0:~ }|
|
|
{5:[No Name] [+] }{4:[No Name] [+] }|
|
|
to |
|
|
test |
|
|
mouse scrolling |
|
|
|
|
|
{0:~ }|
|
|
{4:[No Name] [+] }|
|
|
:vsp |
|
|
]])
|
|
if use_api then
|
|
api.nvim_input_mouse('wheel', 'up', '', 0, 0, 27)
|
|
else
|
|
feed('<ScrollWheelUp><27,0>')
|
|
end
|
|
screen:expect([[
|
|
^mouse scrolling │text |
|
|
│with |
|
|
{0:~ }│many |
|
|
{0:~ }│lines |
|
|
{0:~ }│to |
|
|
{0:~ }│test |
|
|
{5:[No Name] [+] }{4:[No Name] [+] }|
|
|
to |
|
|
test |
|
|
mouse scrolling |
|
|
|
|
|
{0:~ }|
|
|
{4:[No Name] [+] }|
|
|
:vsp |
|
|
]])
|
|
if use_api then
|
|
api.nvim_input_mouse('wheel', 'up', '', 0, 7, 27)
|
|
api.nvim_input_mouse('wheel', 'up', '', 0, 7, 27)
|
|
else
|
|
feed('<ScrollWheelUp><27,7><ScrollWheelUp>')
|
|
end
|
|
screen:expect([[
|
|
^mouse scrolling │text |
|
|
│with |
|
|
{0:~ }│many |
|
|
{0:~ }│lines |
|
|
{0:~ }│to |
|
|
{0:~ }│test |
|
|
{5:[No Name] [+] }{4:[No Name] [+] }|
|
|
Inserting |
|
|
text |
|
|
with |
|
|
many |
|
|
lines |
|
|
{4:[No Name] [+] }|
|
|
:vsp |
|
|
]])
|
|
end
|
|
|
|
it('mouse wheel will target the hovered window (pseudokey)', function()
|
|
wheel(false)
|
|
end)
|
|
|
|
it('mouse wheel will target the hovered window (nvim_input_mouse)', function()
|
|
wheel(true)
|
|
end)
|
|
|
|
it('horizontal scrolling (pseudokey)', function()
|
|
command('set sidescroll=0')
|
|
feed('<esc>:set nowrap<cr>')
|
|
|
|
feed('a <esc>20Ab<esc>')
|
|
screen:expect([[
|
|
|*2
|
|
bbbbbbbbbbbbbbb^b |
|
|
{0:~ }|
|
|
|
|
|
]])
|
|
|
|
feed('<ScrollWheelLeft><0,0>')
|
|
screen:expect([[
|
|
|*2
|
|
n bbbbbbbbbbbbbbbbbbb^b |
|
|
{0:~ }|
|
|
|
|
|
]])
|
|
|
|
feed('^<ScrollWheelRight><0,0>')
|
|
screen:expect([[
|
|
g |
|
|
|
|
|
^t and selection bbbbbbbbb|
|
|
{0:~ }|
|
|
|
|
|
]])
|
|
end)
|
|
|
|
it('horizontal scrolling (nvim_input_mouse)', function()
|
|
command('set sidescroll=0')
|
|
feed('<esc>:set nowrap<cr>')
|
|
|
|
feed('a <esc>20Ab<esc>')
|
|
screen:expect([[
|
|
|*2
|
|
bbbbbbbbbbbbbbb^b |
|
|
{0:~ }|
|
|
|
|
|
]])
|
|
|
|
api.nvim_input_mouse('wheel', 'left', '', 0, 0, 27)
|
|
screen:expect([[
|
|
|*2
|
|
n bbbbbbbbbbbbbbbbbbb^b |
|
|
{0:~ }|
|
|
|
|
|
]])
|
|
|
|
feed('^')
|
|
api.nvim_input_mouse('wheel', 'right', '', 0, 0, 0)
|
|
screen:expect([[
|
|
g |
|
|
|
|
|
^t and selection bbbbbbbbb|
|
|
{0:~ }|
|
|
|
|
|
]])
|
|
end)
|
|
|
|
it("'sidescrolloff' applies to horizontal scrolling", function()
|
|
command('set nowrap')
|
|
command('set sidescrolloff=4')
|
|
|
|
feed('I <esc>020ib<esc>0')
|
|
screen:expect([[
|
|
testing |
|
|
mouse |
|
|
^bbbbbbbbbbbbbbbbbbbb supp|
|
|
{0:~ }|
|
|
|
|
|
]])
|
|
|
|
api.nvim_input_mouse('wheel', 'right', '', 0, 0, 27)
|
|
screen:expect([[
|
|
g |
|
|
|
|
|
bbbb^bbbbbbbbbb support an|
|
|
{0:~ }|
|
|
|
|
|
]])
|
|
|
|
-- window-local 'sidescrolloff' should override global value. #21162
|
|
command('setlocal sidescrolloff=2')
|
|
feed('0')
|
|
screen:expect([[
|
|
testing |
|
|
mouse |
|
|
^bbbbbbbbbbbbbbbbbbbb supp|
|
|
{0:~ }|
|
|
|
|
|
]])
|
|
|
|
api.nvim_input_mouse('wheel', 'right', '', 0, 0, 27)
|
|
screen:expect([[
|
|
g |
|
|
|
|
|
bb^bbbbbbbbbbbb support an|
|
|
{0:~ }|
|
|
|
|
|
]])
|
|
end)
|
|
|
|
local function test_mouse_click_conceal()
|
|
it('(level 1) click on non-wrapped lines', function()
|
|
feed_command('let &conceallevel=1', 'echo')
|
|
|
|
feed('<esc><LeftMouse><0,0>')
|
|
screen:expect([[
|
|
^Section{0:>>--->--->---}{c: }t1{c: } |
|
|
{0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
|
|
{c:>} 私は猫が大好き{0:>---}{c: X } {0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><1,0>')
|
|
screen:expect([[
|
|
S^ection{0:>>--->--->---}{c: }t1{c: } |
|
|
{0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
|
|
{c:>} 私は猫が大好き{0:>---}{c: X } {0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><21,0>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}{c: }^t1{c: } |
|
|
{0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
|
|
{c:>} 私は猫が大好き{0:>---}{c: X } {0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><21,1>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}{c: }t1{c: } |
|
|
{0:>--->--->---} {c: }t2{c: } {c: }t^3{c: } {c: }|
|
|
{c:>} 私は猫が大好き{0:>---}{c: X } {0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><0,2>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}{c: }t1{c: } |
|
|
{0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
|
|
{c:^>} 私は猫が大好き{0:>---}{c: X } {0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><7,2>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}{c: }t1{c: } |
|
|
{0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
|
|
{c:>} 私は^猫が大好き{0:>---}{c: X } {0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><21,2>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}{c: }t1{c: } |
|
|
{0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
|
|
{c:>} 私は猫が大好き{0:>---}{c: ^X } {0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
end) -- level 1 - non wrapped
|
|
|
|
it('(level 1) click on wrapped lines', function()
|
|
feed_command('let &conceallevel=1', 'let &wrap=1', 'echo')
|
|
|
|
feed('<esc><LeftMouse><24,1>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}{c: }t1{c: } |
|
|
{0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c:^ }|
|
|
t4{c: } |
|
|
{c:>} 私は猫が大好き{0:>---}{c: X} |
|
|
{c: } ✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><0,2>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}{c: }t1{c: } |
|
|
{0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
|
|
^t4{c: } |
|
|
{c:>} 私は猫が大好き{0:>---}{c: X} |
|
|
{c: } ✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><8,3>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}{c: }t1{c: } |
|
|
{0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
|
|
t4{c: } |
|
|
{c:>} 私は猫^が大好き{0:>---}{c: X} |
|
|
{c: } ✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><21,3>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}{c: }t1{c: } |
|
|
{0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
|
|
t4{c: } |
|
|
{c:>} 私は猫が大好き{0:>---}{c: ^X} |
|
|
{c: } ✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><4,4>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}{c: }t1{c: } |
|
|
{0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
|
|
t4{c: } |
|
|
{c:>} 私は猫が大好き{0:>---}{c: X} |
|
|
{c: } ✨^🐈✨ |
|
|
|*2
|
|
]])
|
|
end) -- level 1 - wrapped
|
|
|
|
it('(level 2) click on non-wrapped lines', function()
|
|
feed_command('let &conceallevel=2', 'echo')
|
|
|
|
feed('<esc><LeftMouse><20,0>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}^t1 |
|
|
{0:>--->--->---} t2 t3 t4 |
|
|
{c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><14,1>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} ^t2 t3 t4 |
|
|
{c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><18,1>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t^3 t4 |
|
|
{c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><0,2>') -- Weirdness
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 t4 |
|
|
{c:^>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><8,2>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 t4 |
|
|
{c:>} 私は猫^が大好き{0:>---}{c:X} ✨{0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><20,2>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 t4 |
|
|
{c:>} 私は猫が大好き{0:>---}{c:^X} ✨{0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
end) -- level 2 - non wrapped
|
|
|
|
it('(level 2) click on non-wrapped lines (insert mode)', function()
|
|
feed_command('let &conceallevel=2', 'echo')
|
|
|
|
feed('<esc>i<LeftMouse><20,0>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}^t1 |
|
|
{0:>--->--->---} t2 t3 t4 |
|
|
{c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
{sm:-- INSERT --} |
|
|
]])
|
|
|
|
feed('<LeftMouse><14,1>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} ^t2 t3 t4 |
|
|
{c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
{sm:-- INSERT --} |
|
|
]])
|
|
|
|
feed('<LeftMouse><18,1>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t^3 t4 |
|
|
{c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
{sm:-- INSERT --} |
|
|
]])
|
|
|
|
feed('<LeftMouse><0,2>') -- Weirdness
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 t4 |
|
|
{c:^>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
{sm:-- INSERT --} |
|
|
]])
|
|
|
|
feed('<LeftMouse><8,2>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 t4 |
|
|
{c:>} 私は猫^が大好き{0:>---}{c:X} ✨{0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
{sm:-- INSERT --} |
|
|
]])
|
|
|
|
feed('<LeftMouse><20,2>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 t4 |
|
|
{c:>} 私は猫が大好き{0:>---}{c:^X} ✨{0:>}|
|
|
|
|
|
{0:~ }|*2
|
|
{sm:-- INSERT --} |
|
|
]])
|
|
end) -- level 2 - non wrapped (insert mode)
|
|
|
|
it('(level 2) click on wrapped lines', function()
|
|
feed_command('let &conceallevel=2', 'let &wrap=1', 'echo')
|
|
|
|
feed('<esc><LeftMouse><20,0>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}^t1 |
|
|
{0:>--->--->---} t2 t3 |
|
|
t4 |
|
|
{c:>} 私は猫が大好き{0:>---}{c:X} |
|
|
✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><14,1>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} ^t2 t3 |
|
|
t4 |
|
|
{c:>} 私は猫が大好き{0:>---}{c:X} |
|
|
✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><18,1>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t^3 |
|
|
t4 |
|
|
{c:>} 私は猫が大好き{0:>---}{c:X} |
|
|
✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
-- NOTE: The click would ideally be on the 't' in 't4', but wrapping
|
|
-- caused the invisible '*' right before 't4' to remain on the previous
|
|
-- screen line. This is being treated as expected because fixing this is
|
|
-- out of scope for mouse clicks. Should the wrapping behavior of
|
|
-- concealed characters change in the future, this case should be
|
|
-- reevaluated.
|
|
feed('<esc><LeftMouse><0,2>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 ^ |
|
|
t4 |
|
|
{c:>} 私は猫が大好き{0:>---}{c:X} |
|
|
✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><1,2>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 |
|
|
t^4 |
|
|
{c:>} 私は猫が大好き{0:>---}{c:X} |
|
|
✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><0,3>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 |
|
|
t4 |
|
|
{c:^>} 私は猫が大好き{0:>---}{c:X} |
|
|
✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><20,3>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 |
|
|
t4 |
|
|
{c:>} 私は猫が大好き{0:>---}{c:^X} |
|
|
✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><1,4>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 |
|
|
t4 |
|
|
{c:>} 私は猫が大好き{0:>---}{c:X} |
|
|
^✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><5,4>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 |
|
|
t4 |
|
|
{c:>} 私は猫が大好き{0:>---}{c:X} |
|
|
✨🐈^✨ |
|
|
|*2
|
|
]])
|
|
end) -- level 2 - wrapped
|
|
|
|
it('(level 3) click on non-wrapped lines', function()
|
|
feed_command('let &conceallevel=3', 'echo')
|
|
|
|
feed('<esc><LeftMouse><0,2>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 t4 |
|
|
^ 私は猫が大好き{0:>----} ✨🐈|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><1,2>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 t4 |
|
|
^私は猫が大好き{0:>----} ✨🐈|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><13,2>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 t4 |
|
|
私は猫が大好^き{0:>----} ✨🐈|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><20,2>')
|
|
feed('zH') -- FIXME: unnecessary horizontal scrolling
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 t4 |
|
|
私は猫が大好き{0:>----}^ ✨🐈|
|
|
|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
end) -- level 3 - non wrapped
|
|
|
|
it('(level 3) click on wrapped lines', function()
|
|
feed_command('let &conceallevel=3', 'let &wrap=1', 'echo')
|
|
|
|
feed('<esc><LeftMouse><14,1>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} ^t2 t3 |
|
|
t4 |
|
|
私は猫が大好き{0:>----} |
|
|
✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><18,1>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t^3 |
|
|
t4 |
|
|
私は猫が大好き{0:>----} |
|
|
✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><1,2>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 |
|
|
t^4 |
|
|
私は猫が大好き{0:>----} |
|
|
✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><0,3>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 |
|
|
t4 |
|
|
^ 私は猫が大好き{0:>----} |
|
|
✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><20,3>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 |
|
|
t4 |
|
|
私は猫が大好き{0:>----}^ |
|
|
✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><1,4>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 |
|
|
t4 |
|
|
私は猫が大好き{0:>----} |
|
|
^✨🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><3,4>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 |
|
|
t4 |
|
|
私は猫が大好き{0:>----} |
|
|
✨^🐈✨ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<esc><LeftMouse><5,4>')
|
|
screen:expect([[
|
|
Section{0:>>--->--->---}t1 |
|
|
{0:>--->--->---} t2 t3 |
|
|
t4 |
|
|
私は猫が大好き{0:>----} |
|
|
✨🐈^✨ |
|
|
|*2
|
|
]])
|
|
end) -- level 3 - wrapped
|
|
end
|
|
|
|
describe('on concealed text', function()
|
|
-- Helpful for reading the test expectations:
|
|
-- :match Error /\^/
|
|
|
|
before_each(function()
|
|
screen:try_resize(25, 7)
|
|
screen:set_default_attr_ids({
|
|
[0] = { bold = true, foreground = Screen.colors.Blue },
|
|
c = { foreground = Screen.colors.LightGrey, background = Screen.colors.DarkGray },
|
|
sm = { bold = true },
|
|
})
|
|
feed('ggdG')
|
|
|
|
command([[setlocal concealcursor=ni nowrap shiftwidth=2 tabstop=4 list listchars=tab:>-]])
|
|
command([[highlight link X0 Normal]])
|
|
command([[highlight link X1 NonText]])
|
|
command([[highlight link X2 NonText]])
|
|
command([[highlight link X3 NonText]])
|
|
|
|
-- First column is there to retain the tabs.
|
|
insert([[
|
|
|Section *t1*
|
|
| *t2* *t3* *t4*
|
|
|x 私は猫が大好き *cats* ✨🐈✨
|
|
]])
|
|
|
|
feed('gg<c-v>Gxgg')
|
|
end)
|
|
|
|
describe('(syntax)', function()
|
|
before_each(function()
|
|
command([[syntax region X0 matchgroup=X1 start=/\*/ end=/\*/ concealends contains=X2]])
|
|
command([[syntax match X2 /cats/ conceal cchar=X contained]])
|
|
command([[syntax match X3 /\n\@<=x/ conceal cchar=>]])
|
|
end)
|
|
test_mouse_click_conceal()
|
|
end)
|
|
|
|
describe('(matchadd())', function()
|
|
before_each(function()
|
|
fn.matchadd('Conceal', [[\*]])
|
|
fn.matchadd('Conceal', [[cats]], 10, -1, { conceal = 'X' })
|
|
fn.matchadd('Conceal', [[\n\@<=x]], 10, -1, { conceal = '>' })
|
|
end)
|
|
test_mouse_click_conceal()
|
|
end)
|
|
|
|
describe('(extmarks)', function()
|
|
before_each(function()
|
|
local ns = api.nvim_create_namespace('conceal')
|
|
api.nvim_buf_set_extmark(0, ns, 0, 11, { end_col = 12, conceal = '' })
|
|
api.nvim_buf_set_extmark(0, ns, 0, 14, { end_col = 15, conceal = '' })
|
|
api.nvim_buf_set_extmark(0, ns, 1, 5, { end_col = 6, conceal = '' })
|
|
api.nvim_buf_set_extmark(0, ns, 1, 8, { end_col = 9, conceal = '' })
|
|
api.nvim_buf_set_extmark(0, ns, 1, 10, { end_col = 11, conceal = '' })
|
|
api.nvim_buf_set_extmark(0, ns, 1, 13, { end_col = 14, conceal = '' })
|
|
api.nvim_buf_set_extmark(0, ns, 1, 15, { end_col = 16, conceal = '' })
|
|
api.nvim_buf_set_extmark(0, ns, 1, 18, { end_col = 19, conceal = '' })
|
|
api.nvim_buf_set_extmark(0, ns, 2, 24, { end_col = 25, conceal = '' })
|
|
api.nvim_buf_set_extmark(0, ns, 2, 29, { end_col = 30, conceal = '' })
|
|
api.nvim_buf_set_extmark(0, ns, 2, 25, { end_col = 29, conceal = 'X' })
|
|
api.nvim_buf_set_extmark(0, ns, 2, 0, { end_col = 1, conceal = '>' })
|
|
end)
|
|
test_mouse_click_conceal()
|
|
end)
|
|
end)
|
|
|
|
it('virtual text does not change cursor placement on concealed line', function()
|
|
command('%delete')
|
|
insert('aaaaaaaaaa|hidden|bbbbbbbbbb|hidden|cccccccccc')
|
|
command('syntax match test /|hidden|/ conceal cchar=X')
|
|
command('set conceallevel=2 concealcursor=n virtualedit=all')
|
|
screen:expect([[
|
|
aaaaaaaaaa{9:X}bbbbbbb |
|
|
bbb{9:X}ccccccccc^c |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
api.nvim_input_mouse('left', 'press', '', 0, 0, 22)
|
|
screen:expect([[
|
|
aaaaaaaaaa{9:X}bbbbbb^b |
|
|
bbb{9:X}cccccccccc |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
api.nvim_input_mouse('left', 'press', '', 0, 1, 16)
|
|
screen:expect([[
|
|
aaaaaaaaaa{9:X}bbbbbbb |
|
|
bbb{9:X}cccccccccc ^ |
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
|
|
api.nvim_buf_set_extmark(0, api.nvim_create_namespace(''), 0, 0, {
|
|
virt_text = { { '?', 'ErrorMsg' } },
|
|
virt_text_pos = 'right_align',
|
|
virt_text_repeat_linebreak = true,
|
|
})
|
|
screen:expect([[
|
|
aaaaaaaaaa{9:X}bbbbbbb {6:?}|
|
|
bbb{9:X}cccccccccc ^ {6:?}|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
api.nvim_input_mouse('left', 'press', '', 0, 0, 22)
|
|
screen:expect([[
|
|
aaaaaaaaaa{9:X}bbbbbb^b {6:?}|
|
|
bbb{9:X}cccccccccc {6:?}|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
api.nvim_input_mouse('left', 'press', '', 0, 1, 16)
|
|
screen:expect([[
|
|
aaaaaaaaaa{9:X}bbbbbbb {6:?}|
|
|
bbb{9:X}cccccccccc ^ {6:?}|
|
|
{0:~ }|*2
|
|
|
|
|
]])
|
|
end)
|
|
|
|
it('getmousepos() works correctly', function()
|
|
local winwidth = api.nvim_get_option_value('winwidth', {})
|
|
-- Set winwidth=1 so that window sizes don't change.
|
|
api.nvim_set_option_value('winwidth', 1, {})
|
|
command('tabedit')
|
|
local tabpage = api.nvim_get_current_tabpage()
|
|
insert('hello')
|
|
command('vsplit')
|
|
local opts = {
|
|
relative = 'editor',
|
|
width = 12,
|
|
height = 1,
|
|
col = 8,
|
|
row = 1,
|
|
anchor = 'NW',
|
|
style = 'minimal',
|
|
border = 'single',
|
|
focusable = 1,
|
|
}
|
|
local float = api.nvim_open_win(api.nvim_get_current_buf(), false, opts)
|
|
command('redraw')
|
|
local lines = api.nvim_get_option_value('lines', {})
|
|
local columns = api.nvim_get_option_value('columns', {})
|
|
|
|
-- Test that screenrow and screencol are set properly for all positions.
|
|
for row = 0, lines - 1 do
|
|
for col = 0, columns - 1 do
|
|
-- Skip the X button that would close the tab.
|
|
if row ~= 0 or col ~= columns - 1 then
|
|
api.nvim_input_mouse('left', 'press', '', 0, row, col)
|
|
api.nvim_set_current_tabpage(tabpage)
|
|
local mousepos = fn.getmousepos()
|
|
eq(row + 1, mousepos.screenrow)
|
|
eq(col + 1, mousepos.screencol)
|
|
-- All other values should be 0 when clicking on the command line.
|
|
if row == lines - 1 then
|
|
eq(0, mousepos.winid)
|
|
eq(0, mousepos.winrow)
|
|
eq(0, mousepos.wincol)
|
|
eq(0, mousepos.line)
|
|
eq(0, mousepos.column)
|
|
eq(0, mousepos.coladd)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Test that mouse position values are properly set for the floating window
|
|
-- with a border. 1 is added to the height and width to account for the
|
|
-- border.
|
|
for win_row = 0, opts.height + 1 do
|
|
for win_col = 0, opts.width + 1 do
|
|
local row = win_row + opts.row
|
|
local col = win_col + opts.col
|
|
api.nvim_input_mouse('left', 'press', '', 0, row, col)
|
|
local mousepos = fn.getmousepos()
|
|
eq(float, mousepos.winid)
|
|
eq(win_row + 1, mousepos.winrow)
|
|
eq(win_col + 1, mousepos.wincol)
|
|
local line = 0
|
|
local column = 0
|
|
local coladd = 0
|
|
if
|
|
win_row > 0
|
|
and win_row < opts.height + 1
|
|
and win_col > 0
|
|
and win_col < opts.width + 1
|
|
then
|
|
-- Because of border, win_row and win_col don't need to be
|
|
-- incremented by 1.
|
|
line = math.min(win_row, fn.line('$'))
|
|
column = math.min(win_col, #fn.getline(line) + 1)
|
|
coladd = win_col - column
|
|
end
|
|
eq(line, mousepos.line)
|
|
eq(column, mousepos.column)
|
|
eq(coladd, mousepos.coladd)
|
|
end
|
|
end
|
|
|
|
-- Test that mouse position values are properly set for the floating
|
|
-- window, after removing the border.
|
|
opts.border = 'none'
|
|
api.nvim_win_set_config(float, opts)
|
|
command('redraw')
|
|
for win_row = 0, opts.height - 1 do
|
|
for win_col = 0, opts.width - 1 do
|
|
local row = win_row + opts.row
|
|
local col = win_col + opts.col
|
|
api.nvim_input_mouse('left', 'press', '', 0, row, col)
|
|
local mousepos = fn.getmousepos()
|
|
eq(float, mousepos.winid)
|
|
eq(win_row + 1, mousepos.winrow)
|
|
eq(win_col + 1, mousepos.wincol)
|
|
local line = math.min(win_row + 1, fn.line('$'))
|
|
local column = math.min(win_col + 1, #fn.getline(line) + 1)
|
|
local coladd = win_col + 1 - column
|
|
eq(line, mousepos.line)
|
|
eq(column, mousepos.column)
|
|
eq(coladd, mousepos.coladd)
|
|
end
|
|
end
|
|
|
|
-- Test that mouse position values are properly set for ordinary windows.
|
|
-- Set the float to be unfocusable instead of closing, to additionally test
|
|
-- that getmousepos() does not consider unfocusable floats. (see discussion
|
|
-- in PR #14937 for details).
|
|
opts.focusable = false
|
|
api.nvim_win_set_config(float, opts)
|
|
command('redraw')
|
|
for nr = 1, 2 do
|
|
for win_row = 0, fn.winheight(nr) - 1 do
|
|
for win_col = 0, fn.winwidth(nr) - 1 do
|
|
local row = win_row + fn.win_screenpos(nr)[1] - 1
|
|
local col = win_col + fn.win_screenpos(nr)[2] - 1
|
|
api.nvim_input_mouse('left', 'press', '', 0, row, col)
|
|
local mousepos = fn.getmousepos()
|
|
eq(fn.win_getid(nr), mousepos.winid)
|
|
eq(win_row + 1, mousepos.winrow)
|
|
eq(win_col + 1, mousepos.wincol)
|
|
local line = math.min(win_row + 1, fn.line('$'))
|
|
local column = math.min(win_col + 1, #fn.getline(line) + 1)
|
|
local coladd = win_col + 1 - column
|
|
eq(line, mousepos.line)
|
|
eq(column, mousepos.column)
|
|
eq(coladd, mousepos.coladd)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Restore state and release mouse.
|
|
command('tabclose!')
|
|
api.nvim_set_option_value('winwidth', winwidth, {})
|
|
api.nvim_input_mouse('left', 'release', '', 0, 0, 0)
|
|
end)
|
|
|
|
it('scroll keys are not translated into multiclicks and can be mapped #6211 #6989', function()
|
|
api.nvim_set_var('mouse_up', 0)
|
|
api.nvim_set_var('mouse_up2', 0)
|
|
command('nnoremap <ScrollWheelUp> <Cmd>let g:mouse_up += 1<CR>')
|
|
command('nnoremap <2-ScrollWheelUp> <Cmd>let g:mouse_up2 += 1<CR>')
|
|
feed('<ScrollWheelUp><0,0>')
|
|
feed('<ScrollWheelUp><0,0>')
|
|
api.nvim_input_mouse('wheel', 'up', '', 0, 0, 0)
|
|
api.nvim_input_mouse('wheel', 'up', '', 0, 0, 0)
|
|
eq(4, api.nvim_get_var('mouse_up'))
|
|
eq(0, api.nvim_get_var('mouse_up2'))
|
|
end)
|
|
|
|
it('<MouseMove> is not translated into multiclicks and can be mapped', function()
|
|
api.nvim_set_var('mouse_move', 0)
|
|
api.nvim_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>')
|
|
api.nvim_input_mouse('move', '', '', 0, 0, 0)
|
|
api.nvim_input_mouse('move', '', '', 0, 0, 0)
|
|
eq(4, api.nvim_get_var('mouse_move'))
|
|
eq(0, api.nvim_get_var('mouse_move2'))
|
|
end)
|
|
|
|
it('feeding <MouseMove> in Normal mode does not use uninitialized memory #19480', function()
|
|
feed('<MouseMove>')
|
|
helpers.poke_eventloop()
|
|
helpers.assert_alive()
|
|
end)
|
|
|
|
it('mousemodel=popup_setpos', function()
|
|
screen:try_resize(80, 24)
|
|
exec([[
|
|
5new
|
|
call setline(1, ['the dish ran away with the spoon',
|
|
\ 'the cow jumped over the moon' ])
|
|
|
|
set mouse=a mousemodel=popup_setpos
|
|
|
|
aunmenu PopUp
|
|
nmenu PopUp.foo :let g:menustr = 'foo'<CR>
|
|
nmenu PopUp.bar :let g:menustr = 'bar'<CR>
|
|
nmenu PopUp.baz :let g:menustr = 'baz'<CR>
|
|
vmenu PopUp.foo y:<C-U>let g:menustr = 'foo'<CR>
|
|
vmenu PopUp.bar y:<C-U>let g:menustr = 'bar'<CR>
|
|
vmenu PopUp.baz y:<C-U>let g:menustr = 'baz'<CR>
|
|
]])
|
|
|
|
api.nvim_win_set_cursor(0, { 1, 0 })
|
|
api.nvim_input_mouse('right', 'press', '', 0, 0, 4)
|
|
api.nvim_input_mouse('right', 'release', '', 0, 0, 4)
|
|
feed('<Down><Down><CR>')
|
|
eq('bar', api.nvim_get_var('menustr'))
|
|
eq({ 1, 4 }, api.nvim_win_get_cursor(0))
|
|
|
|
-- Test for right click in visual mode inside the selection
|
|
fn.setreg('"', '')
|
|
api.nvim_win_set_cursor(0, { 1, 9 })
|
|
feed('vee')
|
|
api.nvim_input_mouse('right', 'press', '', 0, 0, 11)
|
|
api.nvim_input_mouse('right', 'release', '', 0, 0, 11)
|
|
feed('<Down><CR>')
|
|
eq({ 1, 9 }, api.nvim_win_get_cursor(0))
|
|
eq('ran away', fn.getreg('"'))
|
|
|
|
-- Test for right click in visual mode right before the selection
|
|
fn.setreg('"', '')
|
|
api.nvim_win_set_cursor(0, { 1, 9 })
|
|
feed('vee')
|
|
api.nvim_input_mouse('right', 'press', '', 0, 0, 8)
|
|
api.nvim_input_mouse('right', 'release', '', 0, 0, 8)
|
|
feed('<Down><CR>')
|
|
eq({ 1, 8 }, api.nvim_win_get_cursor(0))
|
|
eq('', fn.getreg('"'))
|
|
|
|
-- Test for right click in visual mode right after the selection
|
|
fn.setreg('"', '')
|
|
api.nvim_win_set_cursor(0, { 1, 9 })
|
|
feed('vee')
|
|
api.nvim_input_mouse('right', 'press', '', 0, 0, 17)
|
|
api.nvim_input_mouse('right', 'release', '', 0, 0, 17)
|
|
feed('<Down><CR>')
|
|
eq({ 1, 17 }, api.nvim_win_get_cursor(0))
|
|
eq('', fn.getreg('"'))
|
|
|
|
-- Test for right click in block-wise visual mode inside the selection
|
|
fn.setreg('"', '')
|
|
api.nvim_win_set_cursor(0, { 1, 15 })
|
|
feed('<C-V>j3l')
|
|
api.nvim_input_mouse('right', 'press', '', 0, 1, 16)
|
|
api.nvim_input_mouse('right', 'release', '', 0, 1, 16)
|
|
feed('<Down><CR>')
|
|
eq({ 1, 15 }, api.nvim_win_get_cursor(0))
|
|
eq('\0224', fn.getregtype('"'))
|
|
|
|
-- Test for right click in block-wise visual mode outside the selection
|
|
fn.setreg('"', '')
|
|
api.nvim_win_set_cursor(0, { 1, 15 })
|
|
feed('<C-V>j3l')
|
|
api.nvim_input_mouse('right', 'press', '', 0, 1, 1)
|
|
api.nvim_input_mouse('right', 'release', '', 0, 1, 1)
|
|
feed('<Down><CR>')
|
|
eq({ 2, 1 }, api.nvim_win_get_cursor(0))
|
|
eq('v', fn.getregtype('"'))
|
|
eq('', fn.getreg('"'))
|
|
|
|
-- Test for right click in line-wise visual mode inside the selection
|
|
fn.setreg('"', '')
|
|
api.nvim_win_set_cursor(0, { 1, 15 })
|
|
feed('V')
|
|
api.nvim_input_mouse('right', 'press', '', 0, 0, 9)
|
|
api.nvim_input_mouse('right', 'release', '', 0, 0, 9)
|
|
feed('<Down><CR>')
|
|
eq({ 1, 0 }, api.nvim_win_get_cursor(0)) -- After yanking, the cursor goes to 1,1
|
|
eq('V', fn.getregtype('"'))
|
|
eq(1, #fn.getreg('"', 1, true))
|
|
|
|
-- Test for right click in multi-line line-wise visual mode inside the selection
|
|
fn.setreg('"', '')
|
|
api.nvim_win_set_cursor(0, { 1, 15 })
|
|
feed('Vj')
|
|
api.nvim_input_mouse('right', 'press', '', 0, 1, 19)
|
|
api.nvim_input_mouse('right', 'release', '', 0, 1, 19)
|
|
feed('<Down><CR>')
|
|
eq({ 1, 0 }, api.nvim_win_get_cursor(0)) -- After yanking, the cursor goes to 1,1
|
|
eq('V', fn.getregtype('"'))
|
|
eq(2, #fn.getreg('"', 1, true))
|
|
|
|
-- Test for right click in line-wise visual mode outside the selection
|
|
fn.setreg('"', '')
|
|
api.nvim_win_set_cursor(0, { 1, 15 })
|
|
feed('V')
|
|
api.nvim_input_mouse('right', 'press', '', 0, 1, 9)
|
|
api.nvim_input_mouse('right', 'release', '', 0, 1, 9)
|
|
feed('<Down><CR>')
|
|
eq({ 2, 9 }, api.nvim_win_get_cursor(0))
|
|
eq('', fn.getreg('"'))
|
|
|
|
-- Try clicking outside the window
|
|
fn.setreg('"', '')
|
|
api.nvim_win_set_cursor(0, { 2, 1 })
|
|
feed('vee')
|
|
api.nvim_input_mouse('right', 'press', '', 0, 6, 1)
|
|
api.nvim_input_mouse('right', 'release', '', 0, 6, 1)
|
|
feed('<Down><CR>')
|
|
eq(2, fn.winnr())
|
|
eq('', fn.getreg('"'))
|
|
|
|
-- Test for right click in visual mode inside the selection with vertical splits
|
|
command('wincmd t')
|
|
command('rightbelow vsplit')
|
|
fn.setreg('"', '')
|
|
api.nvim_win_set_cursor(0, { 1, 9 })
|
|
feed('vee')
|
|
api.nvim_input_mouse('right', 'press', '', 0, 0, 52)
|
|
api.nvim_input_mouse('right', 'release', '', 0, 0, 52)
|
|
feed('<Down><CR>')
|
|
eq({ 1, 9 }, api.nvim_win_get_cursor(0))
|
|
eq('ran away', fn.getreg('"'))
|
|
|
|
-- Test for right click inside visual selection at bottom of window with winbar
|
|
command('setlocal winbar=WINBAR')
|
|
feed('2yyP')
|
|
fn.setreg('"', '')
|
|
feed('G$vbb')
|
|
api.nvim_input_mouse('right', 'press', '', 0, 4, 61)
|
|
api.nvim_input_mouse('right', 'release', '', 0, 4, 61)
|
|
feed('<Down><CR>')
|
|
eq({ 4, 20 }, api.nvim_win_get_cursor(0))
|
|
eq('the moon', fn.getreg('"'))
|
|
end)
|
|
end)
|