12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072 |
- local t = require('test.testutil')
- local n = require('test.functional.testnvim')()
- local Screen = require('test.functional.ui.screen')
- local clear, feed, api = n.clear, n.feed, n.api
- local insert, feed_command = n.insert, n.feed_command
- local eq, fn = t.eq, n.fn
- local poke_eventloop = n.poke_eventloop
- local command = n.command
- local exec = n.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:add_extra_attr_ids {
- [100] = {
- bold = true,
- background = Screen.colors.LightGrey,
- foreground = Screen.colors.Blue1,
- },
- }
- command('set mousemodel=extend')
- feed('itesting<cr>mouse<cr>support and selection<esc>')
- screen:expect([[
- testing |
- mouse |
- support and selectio^n |
- {1:~ }|
- |
- ]])
- end)
- it('single left click moves cursor', function()
- feed('<LeftMouse><2,1>')
- screen:expect {
- grid = [[
- testing |
- mo^use |
- support and selection |
- {1:~ }|
- |
- ]],
- mouse_enabled = true,
- }
- feed('<LeftMouse><0,0>')
- screen:expect([[
- ^testing |
- mouse |
- support and selection |
- {1:~ }|
- |
- ]])
- 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 |
- {1:~ }|
- |
- ]],
- mouse_enabled = false,
- }
- feed('<LeftMouse><0,0>')
- screen:expect([[
- ^testing |
- mouse |
- support and selection |
- {1:~ }|
- |
- ]])
- 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([[
- {17:testin}^g |
- mouse |
- support and selection |
- {1:~ }|
- {5:-- 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{17:esting} |
- mouse |
- support and selection |
- {1:~ }|
- {5:-- 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 |
- {1:~ }|
- {5:-- VISUAL BLOCK --} |
- ]])
- end)
- describe('tab drag', function()
- 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([[
- {24: + foo }{5: + bar }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*2
- |
- ]])
- feed('<LeftMouse><4,0>')
- screen:expect([[
- {5: + foo }{24: + bar }{2: }{24:X}|
- this is fo^o |
- {1:~ }|*2
- |
- ]])
- feed('<LeftDrag><14,0>')
- screen:expect([[
- {24: + bar }{5: + foo }{2: }{24:X}|
- this is fo^o |
- {1:~ }|*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([[
- {24: + foo }{5: + bar }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*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 = [[
- {24: + foo }{5: + bar }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*2
- |
- ]],
- unchanged = true,
- }
- feed('<LeftDrag><6,0>')
- screen:expect([[
- {5: + bar }{24: + foo }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*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([[
- {24: + foo }{5: + bar }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*2
- |
- ]])
- feed('<LeftMouse><4,0>')
- screen:expect([[
- {5: + foo }{24: + bar }{2: }{24:X}|
- this is fo^o |
- {1:~ }|*2
- |
- ]])
- feed('<LeftDrag><7,0>')
- screen:expect([[
- {24: + bar }{5: + foo }{2: }{24:X}|
- this is fo^o |
- {1:~ }|*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([[
- {24: + foo }{5: + bar }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*2
- |
- ]])
- feed('<LeftMouse><4,0>')
- screen:expect([[
- {5: + foo }{24: + bar }{2: }{24:X}|
- this is fo^o |
- {1:~ }|*2
- |
- ]])
- feed('<LeftDrag><4,1>')
- screen:expect {
- grid = [[
- {5: + foo }{24: + bar }{2: }{24:X}|
- this is fo^o |
- {1:~ }|*2
- |
- ]],
- unchanged = true,
- }
- feed('<LeftDrag><14,1>')
- screen:expect([[
- {24: + bar }{5: + foo }{2: }{24:X}|
- this is fo^o |
- {1:~ }|*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([[
- {24: + foo }{5: + bar }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*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 = [[
- {24: + foo }{5: + bar }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*2
- |
- ]],
- unchanged = true,
- }
- feed('<LeftDrag><11,1>')
- screen:expect {
- grid = [[
- {24: + foo }{5: + bar }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*2
- |
- ]],
- unchanged = true,
- }
- feed('<LeftDrag><6,1>')
- screen:expect([[
- {5: + bar }{24: + foo }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*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([[
- {24: + foo }{5: + bar }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*2
- |
- ]])
- feed('<LeftMouse><4,0>')
- screen:expect([[
- {5: + foo }{24: + bar }{2: }{24:X}|
- this is fo^o |
- {1:~ }|*2
- |
- ]])
- feed('<LeftDrag><4,1>')
- screen:expect {
- grid = [[
- {5: + foo }{24: + bar }{2: }{24:X}|
- this is fo^o |
- {1:~ }|*2
- |
- ]],
- unchanged = true,
- }
- feed('<LeftDrag><7,1>')
- screen:expect([[
- {24: + bar }{5: + foo }{2: }{24:X}|
- this is fo^o |
- {1:~ }|*2
- |
- ]])
- end)
- end)
- describe('tabline', function()
- it('left click in default tabline (tabpage label) 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([[
- {24: + foo }{5: + bar }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*2
- |
- ]])
- feed('<LeftMouse><4,0>')
- screen:expect([[
- {5: + foo }{24: + bar }{2: }{24:X}|
- this is fo^o |
- {1:~ }|*2
- |
- ]])
- feed('<LeftMouse><6,0>')
- screen:expect_unchanged()
- feed('<LeftMouse><10,0>')
- screen:expect([[
- {24: + foo }{5: + bar }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*2
- |
- ]])
- feed('<LeftMouse><12,0>')
- screen:expect_unchanged()
- end)
- it('left click in default tabline (blank space) switches tab', function()
- feed_command('%delete')
- insert('this is foo')
- feed_command('silent file foo | tabnew | file bar')
- insert('this is bar')
- screen:expect([[
- {24: + foo }{5: + bar }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*2
- |
- ]])
- feed('<LeftMouse><20,0>')
- screen:expect([[
- {5: + foo }{24: + bar }{2: }{24:X}|
- this is fo^o |
- {1:~ }|*2
- |
- ]])
- feed('<LeftMouse><22,0>')
- screen:expect([[
- {24: + foo }{5: + bar }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*2
- |
- ]])
- end)
- it('left click in default tabline (close label) 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([[
- {24: + foo }{5: + bar }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*2
- |
- ]])
- feed('<LeftMouse><24,0>')
- screen:expect([[
- this is fo^o |
- {1:~ }|*3
- |
- ]])
- end)
- it('double click in default tabline opens new tab before', function()
- feed_command('%delete')
- insert('this is foo')
- feed_command('silent file foo | tabnew | file bar')
- insert('this is bar')
- screen:expect([[
- {24: + foo }{5: + bar }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*2
- |
- ]])
- feed('<2-LeftMouse><4,0>')
- screen:expect([[
- {5: Name] }{24: + foo + bar }{2: }{24:X}|
- {1:^$} |
- {1:~ }|*2
- |
- ]])
- command('tabclose')
- screen:expect([[
- {5: + foo }{24: + bar }{2: }{24:X}|
- this is fo^o |
- {1:~ }|*2
- |
- ]])
- feed('<2-LeftMouse><20,0>')
- screen:expect([[
- {24: + foo + bar }{5: Name] }{2: }{24:X}|
- {1:^$} |
- {1:~ }|*2
- |
- ]])
- command('tabclose')
- screen:expect([[
- {24: + foo }{5: + bar }{2: }{24:X}|
- this is ba^r{1:$} |
- {1:~ }|*2
- |
- ]])
- feed('<2-LeftMouse><10,0>')
- screen:expect([[
- {24: + foo }{5: Name] }{24: + bar }{2: }{24:X}|
- {1:^$} |
- {1:~ }|*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([[
- {2: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 |
- {1:~ }|
- |
- ]])
- feed('<LeftDrag><4,1>')
- screen:expect([[
- testing |
- mo{17:us}^e |
- support and selection |
- {1:~ }|
- {5:-- VISUAL --} |
- ]])
- feed('<LeftDrag><2,2>')
- screen:expect([[
- testing |
- mo{17:use} |
- {17:su}^pport and selection |
- {1:~ }|
- {5:-- VISUAL --} |
- ]])
- feed('<LeftDrag><0,0>')
- screen:expect([[
- ^t{17:esting} |
- {17:mou}se |
- support and selection |
- {1:~ }|
- {5:-- VISUAL --} |
- ]])
- end)
- it('left drag changes visual selection after tab click', function()
- feed_command('silent file foo | tabnew | file bar')
- insert('this is bar')
- feed_command('tabprevious') -- go to first tab
- screen:expect([[
- {5: + foo }{24: + bar }{2: }{24:X}|
- testing |
- mouse |
- support and selectio^n |
- :tabprevious |
- ]])
- feed('<LeftMouse><10,0><LeftRelease>') -- go to second tab
- n.poke_eventloop()
- feed('<LeftMouse><0,1>')
- screen:expect([[
- {24: + foo }{5: + bar }{2: }{24:X}|
- ^this is bar{1:$} |
- {1:~ }|*2
- :tabprevious |
- ]])
- feed('<LeftDrag><4,1>')
- screen:expect([[
- {24: + foo }{5: + bar }{2: }{24:X}|
- {17:this}^ is bar{1:$} |
- {1:~ }|*2
- {5:-- 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 |
- {1:~ }│{1:~ }|*2
- {1:~ }│{2:[No Name] [+] }|
- {1:~ }│foo{1:$} |
- {1:~ }│ba^r{1:$} |
- {1:~ }│{1:~ }|*4
- {2:[No Name] [+] }{3:[No Name] [+] }|
- |
- ]],
- }
- api.nvim_input_mouse('left', 'press', '', 0, 6, 27)
- screen:expect {
- grid = [[
- testing │testing |
- mouse │mouse |
- support and selection │support and selection |
- {1:~ }│{1:~ }|*2
- {1:~ }│{2:[No Name] [+] }|
- {1:~ }│^foo{1:$} |
- {1:~ }│bar{1:$} |
- {1:~ }│{1:~ }|*4
- {2:[No Name] [+] }{3:[No Name] [+] }|
- |
- ]],
- }
- api.nvim_input_mouse('left', 'drag', '', 0, 7, 30)
- screen:expect {
- grid = [[
- testing │testing |
- mouse │mouse |
- support and selection │support and selection |
- {1:~ }│{1:~ }|*2
- {1:~ }│{2:[No Name] [+] }|
- {1:~ }│{17:foo}{100:$} |
- {1:~ }│{17:bar}{1:^$} |
- {1:~ }│{1:~ }|*4
- {2:[No Name] [+] }{3:[No Name] [+] }|
- {5:-- 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 |
- {17:suppor}^t and selection |
- {1:~ }|
- {5:-- VISUAL --} |
- ]])
- feed('<LeftDrag><0,1>')
- screen:expect([[
- testing |
- ^m{17:ouse} |
- {17:support} and selection |
- {1:~ }|
- {5:-- VISUAL --} |
- ]])
- feed('<LeftDrag><4,0>')
- screen:expect([[
- ^t{17:esting} |
- {17:mouse} |
- {17:support} and selection |
- {1:~ }|
- {5:-- VISUAL --} |
- ]])
- feed('<LeftDrag><14,2>')
- screen:expect([[
- testing |
- mouse |
- {17:support and selectio}^n |
- {1:~ }|
- {5:-- 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 |
- {17:su}^p{17:port and selection} |
- {1:~ }|
- {5:-- VISUAL LINE --} |
- ]])
- feed('<LeftDrag><0,1>')
- screen:expect([[
- testing |
- ^m{17:ouse} |
- {17:support and selection} |
- {1:~ }|
- {5:-- VISUAL LINE --} |
- ]])
- feed('<LeftDrag><4,0>')
- screen:expect([[
- {17:test}^i{17:ng} |
- {17:mouse} |
- {17:support and selection} |
- {1:~ }|
- {5:-- VISUAL LINE --} |
- ]])
- feed('<LeftDrag><14,2>')
- screen:expect([[
- testing |
- mouse |
- {17:support and se}^l{17:ection} |
- {1:~ }|
- {5:-- 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 |
- {1:~ }|
- {5:-- VISUAL BLOCK --} |
- ]])
- feed('<LeftDrag><0,1>')
- screen:expect([[
- testing |
- ^m{17:ou}se |
- {17:sup}port and selection |
- {1:~ }|
- {5:-- VISUAL BLOCK --} |
- ]])
- feed('<LeftDrag><4,0>')
- screen:expect([[
- te{17:st}^ing |
- mo{17:use} |
- su{17:ppo}rt and selection |
- {1:~ }|
- {5:-- VISUAL BLOCK --} |
- ]])
- feed('<LeftDrag><14,2>')
- screen:expect([[
- testing |
- mouse |
- su{17:pport and se}^lection |
- {1:~ }|
- {5:-- 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 |
- {1:~ }|
- |
- ]])
- feed('<RightMouse><2,2>')
- screen:expect([[
- {17:testing} |
- {17:mouse} |
- {17:su}^pport and selection |
- {1:~ }|
- {5:-- 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([[
- {9:E433: No tags file} |
- {9:E426: Tag not found: test}|
- {9:ing} |
- {6:Press ENTER or type comma}|
- {6: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 │{1:^$} |
- mouse │{1:~ }|
- support and selection │{1:~ }|
- {2:[No Name] [+] }{3:[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 │{1:^$} |
- mouse │{1:~ }|
- support and │{1:~ }|
- {2:< Name] [+] }{3:[No Name] }|
- |
- ]])
- api.nvim_input_mouse('left', 'drag', '', 0, 2, 2)
- screen:expect([[
- te│{1:^$} |
- mo│{1:~ }|
- su│{1:~ }|
- {2:< }{3:[No Name] }|
- |
- ]])
- api.nvim_input_mouse('left', 'release', '', 0, 2, 2)
- api.nvim_set_option_value('statuscolumn', 'foobar', { win = oldwin })
- screen:expect([[
- {8:fo}│{1:^$} |
- {8:fo}│{1:~ }|*2
- {2:< }{3:[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│{1:^$} |
- {8:foobar}mouse │{1:~ }|
- {8:foobar}suppor│{1:~ }|
- {2:< Name] [+] }{3:[No Name] }|
- |
- ]])
- api.nvim_input_mouse('left', 'drag', '', 0, 2, 22)
- screen:expect([[
- {8:foobar}testing │{1:^$} |
- {8:foobar}mouse │{1:~ }|
- {8:foobar}support and sele│{1:~ }|
- {2:[No Name] [+] }{3:[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 |
- │ |
- {1:~ }│{1:~ }|
- {3:[No Name] [+] }{2:[No Name] [+] }|
- to |
- test |
- mouse scrolling |
- |
- {1:~ }|
- {2:[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 |
- {1:~ }│test |
- {1:~ }│mouse scrolling |
- {1:~ }│ |
- {1:~ }│{1:~ }|
- {3:[No Name] [+] }{2:[No Name] [+] }|
- to |
- test |
- mouse scrolling |
- |
- {1:~ }|
- {2:[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 |
- {1:~ }│many |
- {1:~ }│lines |
- {1:~ }│to |
- {1:~ }│test |
- {3:[No Name] [+] }{2:[No Name] [+] }|
- to |
- test |
- mouse scrolling |
- |
- {1:~ }|
- {2:[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 |
- {1:~ }│many |
- {1:~ }│lines |
- {1:~ }│to |
- {1:~ }│test |
- {3:[No Name] [+] }{2:[No Name] [+] }|
- Inserting |
- text |
- with |
- many |
- lines |
- {2:[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>17Ab<esc>3Ab<esc>')
- screen:expect([[
- |*2
- bbbbbbbbbbbbbbb^b |
- {1:~ }|
- |
- ]])
- feed('<ScrollWheelLeft><0,0>')
- screen:expect([[
- |*2
- n bbbbbbbbbbbbbbbbbbb^b |
- {1:~ }|
- |
- ]])
- feed('^<ScrollWheelRight><0,0>')
- screen:expect([[
- g |
- |
- ^t and selection bbbbbbbbb|
- {1:~ }|
- |
- ]])
- end)
- it('horizontal scrolling (nvim_input_mouse)', function()
- command('set sidescroll=0')
- feed('<esc>:set nowrap<cr>')
- feed('a <esc>17Ab<esc>3Ab<esc>')
- screen:expect([[
- |*2
- bbbbbbbbbbbbbbb^b |
- {1:~ }|
- |
- ]])
- api.nvim_input_mouse('wheel', 'left', '', 0, 0, 27)
- screen:expect([[
- |*2
- n bbbbbbbbbbbbbbbbbbb^b |
- {1:~ }|
- |
- ]])
- feed('^')
- api.nvim_input_mouse('wheel', 'right', '', 0, 0, 0)
- screen:expect([[
- g |
- |
- ^t and selection bbbbbbbbb|
- {1:~ }|
- |
- ]])
- 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|
- {1:~ }|
- |
- ]])
- api.nvim_input_mouse('wheel', 'right', '', 0, 0, 27)
- screen:expect([[
- g |
- |
- bbbb^bbbbbbbbbb support an|
- {1:~ }|
- |
- ]])
- -- window-local 'sidescrolloff' should override global value. #21162
- command('setlocal sidescrolloff=2')
- feed('0')
- screen:expect([[
- testing |
- mouse |
- ^bbbbbbbbbbbbbbbbbbbb supp|
- {1:~ }|
- |
- ]])
- api.nvim_input_mouse('wheel', 'right', '', 0, 0, 27)
- screen:expect([[
- g |
- |
- bb^bbbbbbbbbbbb support an|
- {1:~ }|
- |
- ]])
- 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{1:>>--->--->---}{14: }t1{14: } |
- {1:>--->--->---} {14: }t2{14: } {14: }t3{14: } {14: }|
- {14:>} 私は猫が大好き{1:>---}{14: X } {1:>}|
- |
- {1:~ }|*2
- |
- ]])
- feed('<esc><LeftMouse><1,0>')
- screen:expect([[
- S^ection{1:>>--->--->---}{14: }t1{14: } |
- {1:>--->--->---} {14: }t2{14: } {14: }t3{14: } {14: }|
- {14:>} 私は猫が大好き{1:>---}{14: X } {1:>}|
- |
- {1:~ }|*2
- |
- ]])
- feed('<esc><LeftMouse><21,0>')
- screen:expect([[
- Section{1:>>--->--->---}{14: }^t1{14: } |
- {1:>--->--->---} {14: }t2{14: } {14: }t3{14: } {14: }|
- {14:>} 私は猫が大好き{1:>---}{14: X } {1:>}|
- |
- {1:~ }|*2
- |
- ]])
- feed('<esc><LeftMouse><21,1>')
- screen:expect([[
- Section{1:>>--->--->---}{14: }t1{14: } |
- {1:>--->--->---} {14: }t2{14: } {14: }t^3{14: } {14: }|
- {14:>} 私は猫が大好き{1:>---}{14: X } {1:>}|
- |
- {1:~ }|*2
- |
- ]])
- feed('<esc><LeftMouse><0,2>')
- screen:expect([[
- Section{1:>>--->--->---}{14: }t1{14: } |
- {1:>--->--->---} {14: }t2{14: } {14: }t3{14: } {14: }|
- {14:^>} 私は猫が大好き{1:>---}{14: X } {1:>}|
- |
- {1:~ }|*2
- |
- ]])
- feed('<esc><LeftMouse><7,2>')
- screen:expect([[
- Section{1:>>--->--->---}{14: }t1{14: } |
- {1:>--->--->---} {14: }t2{14: } {14: }t3{14: } {14: }|
- {14:>} 私は^猫が大好き{1:>---}{14: X } {1:>}|
- |
- {1:~ }|*2
- |
- ]])
- feed('<esc><LeftMouse><21,2>')
- screen:expect([[
- Section{1:>>--->--->---}{14: }t1{14: } |
- {1:>--->--->---} {14: }t2{14: } {14: }t3{14: } {14: }|
- {14:>} 私は猫が大好き{1:>---}{14: ^X } {1:>}|
- |
- {1:~ }|*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{1:>>--->--->---}{14: }t1{14: } |
- {1:>--->--->---} {14: }t2{14: } {14: }t3{14: } {14:^ }|
- t4{14: } |
- {14:>} 私は猫が大好き{1:>---}{14: X} |
- {14: } ✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><0,2>')
- screen:expect([[
- Section{1:>>--->--->---}{14: }t1{14: } |
- {1:>--->--->---} {14: }t2{14: } {14: }t3{14: } {14: }|
- ^t4{14: } |
- {14:>} 私は猫が大好き{1:>---}{14: X} |
- {14: } ✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><8,3>')
- screen:expect([[
- Section{1:>>--->--->---}{14: }t1{14: } |
- {1:>--->--->---} {14: }t2{14: } {14: }t3{14: } {14: }|
- t4{14: } |
- {14:>} 私は猫^が大好き{1:>---}{14: X} |
- {14: } ✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><21,3>')
- screen:expect([[
- Section{1:>>--->--->---}{14: }t1{14: } |
- {1:>--->--->---} {14: }t2{14: } {14: }t3{14: } {14: }|
- t4{14: } |
- {14:>} 私は猫が大好き{1:>---}{14: ^X} |
- {14: } ✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><4,4>')
- screen:expect([[
- Section{1:>>--->--->---}{14: }t1{14: } |
- {1:>--->--->---} {14: }t2{14: } {14: }t3{14: } {14: }|
- t4{14: } |
- {14:>} 私は猫が大好き{1:>---}{14: X} |
- {14: } ✨^🐈✨ |
- |*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{1:>>--->--->---}^t1 |
- {1:>--->--->---} t2 t3 t4 |
- {14:>} 私は猫が大好き{1:>---}{14:X} ✨{1:>}|
- |
- {1:~ }|*2
- |
- ]])
- feed('<esc><LeftMouse><14,1>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} ^t2 t3 t4 |
- {14:>} 私は猫が大好き{1:>---}{14:X} ✨{1:>}|
- |
- {1:~ }|*2
- |
- ]])
- feed('<esc><LeftMouse><18,1>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t^3 t4 |
- {14:>} 私は猫が大好き{1:>---}{14:X} ✨{1:>}|
- |
- {1:~ }|*2
- |
- ]])
- feed('<esc><LeftMouse><0,2>') -- Weirdness
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 t4 |
- {14:^>} 私は猫が大好き{1:>---}{14:X} ✨{1:>}|
- |
- {1:~ }|*2
- |
- ]])
- feed('<esc><LeftMouse><8,2>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 t4 |
- {14:>} 私は猫^が大好き{1:>---}{14:X} ✨{1:>}|
- |
- {1:~ }|*2
- |
- ]])
- feed('<esc><LeftMouse><20,2>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 t4 |
- {14:>} 私は猫が大好き{1:>---}{14:^X} ✨{1:>}|
- |
- {1:~ }|*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{1:>>--->--->---}^t1 |
- {1:>--->--->---} t2 t3 t4 |
- {14:>} 私は猫が大好き{1:>---}{14:X} ✨{1:>}|
- |
- {1:~ }|*2
- {5:-- INSERT --} |
- ]])
- feed('<LeftMouse><14,1>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} ^t2 t3 t4 |
- {14:>} 私は猫が大好き{1:>---}{14:X} ✨{1:>}|
- |
- {1:~ }|*2
- {5:-- INSERT --} |
- ]])
- feed('<LeftMouse><18,1>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t^3 t4 |
- {14:>} 私は猫が大好き{1:>---}{14:X} ✨{1:>}|
- |
- {1:~ }|*2
- {5:-- INSERT --} |
- ]])
- feed('<LeftMouse><0,2>') -- Weirdness
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 t4 |
- {14:^>} 私は猫が大好き{1:>---}{14:X} ✨{1:>}|
- |
- {1:~ }|*2
- {5:-- INSERT --} |
- ]])
- feed('<LeftMouse><8,2>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 t4 |
- {14:>} 私は猫^が大好き{1:>---}{14:X} ✨{1:>}|
- |
- {1:~ }|*2
- {5:-- INSERT --} |
- ]])
- feed('<LeftMouse><20,2>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 t4 |
- {14:>} 私は猫が大好き{1:>---}{14:^X} ✨{1:>}|
- |
- {1:~ }|*2
- {5:-- 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{1:>>--->--->---}^t1 |
- {1:>--->--->---} t2 t3 |
- t4 |
- {14:>} 私は猫が大好き{1:>---}{14:X} |
- ✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><14,1>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} ^t2 t3 |
- t4 |
- {14:>} 私は猫が大好き{1:>---}{14:X} |
- ✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><18,1>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t^3 |
- t4 |
- {14:>} 私は猫が大好き{1:>---}{14: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{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 ^ |
- t4 |
- {14:>} 私は猫が大好き{1:>---}{14:X} |
- ✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><1,2>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 |
- t^4 |
- {14:>} 私は猫が大好き{1:>---}{14:X} |
- ✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><0,3>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 |
- t4 |
- {14:^>} 私は猫が大好き{1:>---}{14:X} |
- ✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><20,3>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 |
- t4 |
- {14:>} 私は猫が大好き{1:>---}{14:^X} |
- ✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><1,4>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 |
- t4 |
- {14:>} 私は猫が大好き{1:>---}{14:X} |
- ^✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><5,4>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 |
- t4 |
- {14:>} 私は猫が大好き{1:>---}{14: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{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 t4 |
- ^ 私は猫が大好き{1:>----} ✨🐈|
- |
- {1:~ }|*2
- |
- ]])
- feed('<esc><LeftMouse><1,2>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 t4 |
- ^私は猫が大好き{1:>----} ✨🐈|
- |
- {1:~ }|*2
- |
- ]])
- feed('<esc><LeftMouse><13,2>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 t4 |
- 私は猫が大好^き{1:>----} ✨🐈|
- |
- {1:~ }|*2
- |
- ]])
- feed('<esc><LeftMouse><20,2>')
- feed('zH') -- FIXME: unnecessary horizontal scrolling
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 t4 |
- 私は猫が大好き{1:>----}^ ✨🐈|
- |
- {1:~ }|*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{1:>>--->--->---}t1 |
- {1:>--->--->---} ^t2 t3 |
- t4 |
- 私は猫が大好き{1:>----} |
- ✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><18,1>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t^3 |
- t4 |
- 私は猫が大好き{1:>----} |
- ✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><1,2>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 |
- t^4 |
- 私は猫が大好き{1:>----} |
- ✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><0,3>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 |
- t4 |
- ^ 私は猫が大好き{1:>----} |
- ✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><20,3>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 |
- t4 |
- 私は猫が大好き{1:>----}^ |
- ✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><1,4>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 |
- t4 |
- 私は猫が大好き{1:>----} |
- ^✨🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><3,4>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 |
- t4 |
- 私は猫が大好き{1:>----} |
- ✨^🐈✨ |
- |*2
- ]])
- feed('<esc><LeftMouse><5,4>')
- screen:expect([[
- Section{1:>>--->--->---}t1 |
- {1:>--->--->---} t2 t3 |
- t4 |
- 私は猫が大好き{1:>----} |
- ✨🐈^✨ |
- |*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)
- 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{14:X}bbbbbbb |
- bbb{14:X}ccccccccc^c |
- {1:~ }|*2
- |
- ]])
- api.nvim_input_mouse('left', 'press', '', 0, 0, 22)
- screen:expect([[
- aaaaaaaaaa{14:X}bbbbbb^b |
- bbb{14:X}cccccccccc |
- {1:~ }|*2
- |
- ]])
- api.nvim_input_mouse('left', 'press', '', 0, 1, 16)
- screen:expect([[
- aaaaaaaaaa{14:X}bbbbbbb |
- bbb{14:X}cccccccccc ^ |
- {1:~ }|*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{14:X}bbbbbbb {9:?}|
- bbb{14:X}cccccccccc ^ {9:?}|
- {1:~ }|*2
- |
- ]])
- api.nvim_input_mouse('left', 'press', '', 0, 0, 22)
- screen:expect([[
- aaaaaaaaaa{14:X}bbbbbb^b {9:?}|
- bbb{14:X}cccccccccc {9:?}|
- {1:~ }|*2
- |
- ]])
- api.nvim_input_mouse('left', 'press', '', 0, 1, 16)
- screen:expect([[
- aaaaaaaaaa{14:X}bbbbbbb {9:?}|
- bbb{14:X}cccccccccc ^ {9:?}|
- {1:~ }|*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> to different locations 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><1,0>')
- feed('<MouseMove><2,0>')
- api.nvim_input_mouse('move', '', '', 0, 0, 3)
- api.nvim_input_mouse('move', '', '', 0, 0, 4)
- eq(4, api.nvim_get_var('mouse_move'))
- eq(0, api.nvim_get_var('mouse_move2'))
- end)
- it('<MouseMove> to same location does not generate events #31103', 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>')
- api.nvim_input_mouse('move', '', '', 0, 0, 3)
- eq(1, api.nvim_get_var('mouse_move'))
- eq(0, api.nvim_get_var('mouse_move2'))
- feed('<MouseMove><3,0>')
- feed('<MouseMove><3,0>')
- api.nvim_input_mouse('move', '', '', 0, 0, 3)
- api.nvim_input_mouse('move', '', '', 0, 0, 3)
- eq(1, api.nvim_get_var('mouse_move'))
- eq(0, api.nvim_get_var('mouse_move2'))
- eq({ mode = 'n', blocking = false }, api.nvim_get_mode())
- feed('<MouseMove><3,0><Insert>')
- eq(1, api.nvim_get_var('mouse_move'))
- eq(0, api.nvim_get_var('mouse_move2'))
- eq({ mode = 'i', blocking = false }, api.nvim_get_mode())
- end)
- it('feeding <MouseMove> in Normal mode does not use uninitialized memory #19480', function()
- feed('<MouseMove>')
- n.poke_eventloop()
- n.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('"'))
- -- Try clicking in the cmdline
- api.nvim_input_mouse('right', 'press', '', 0, 23, 0)
- api.nvim_input_mouse('right', 'release', '', 0, 23, 0)
- feed('<Down><Down><Down><CR>')
- eq('baz', api.nvim_get_var('menustr'))
- -- Try clicking in horizontal separator with global statusline
- command('set laststatus=3')
- api.nvim_input_mouse('right', 'press', '', 0, 5, 0)
- api.nvim_input_mouse('right', 'release', '', 0, 5, 0)
- feed('<Down><CR>')
- eq('foo', api.nvim_get_var('menustr'))
- -- Try clicking in the cmdline with global statusline
- api.nvim_input_mouse('right', 'press', '', 0, 23, 0)
- api.nvim_input_mouse('right', 'release', '', 0, 23, 0)
- feed('<Down><Down><CR>')
- eq('bar', api.nvim_get_var('menustr'))
- end)
- end)
|