mouse_spec.lua 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388
  1. local helpers = require('test.functional.helpers')(after_each)
  2. local Screen = require('test.functional.ui.screen')
  3. local clear, feed, meths = helpers.clear, helpers.feed, helpers.meths
  4. local insert, feed_command = helpers.insert, helpers.feed_command
  5. local eq, funcs = helpers.eq, helpers.funcs
  6. local command = helpers.command
  7. describe('ui/mouse/input', function()
  8. local screen
  9. before_each(function()
  10. clear()
  11. meths.set_option('mouse', 'a')
  12. meths.set_option('list', true)
  13. -- NB: this is weird, but mostly irrelevant to the test
  14. -- So I didn't bother to change it
  15. command('set listchars=eol:$')
  16. command('setl listchars=nbsp:x')
  17. screen = Screen.new(25, 5)
  18. screen:attach()
  19. screen:set_default_attr_ids({
  20. [0] = {bold=true, foreground=Screen.colors.Blue},
  21. [1] = {background = Screen.colors.LightGrey},
  22. [2] = {bold = true},
  23. [3] = {
  24. foreground = Screen.colors.Blue,
  25. background = Screen.colors.LightGrey,
  26. bold = true,
  27. },
  28. [4] = {reverse = true},
  29. [5] = {bold = true, reverse = true},
  30. [6] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
  31. [7] = {bold = true, foreground = Screen.colors.SeaGreen4},
  32. })
  33. command("set display-=msgsep")
  34. feed('itesting<cr>mouse<cr>support and selection<esc>')
  35. screen:expect([[
  36. testing |
  37. mouse |
  38. support and selectio^n |
  39. {0:~ }|
  40. |
  41. ]])
  42. end)
  43. it('single left click moves cursor', function()
  44. feed('<LeftMouse><2,1>')
  45. screen:expect{grid=[[
  46. testing |
  47. mo^use |
  48. support and selection |
  49. {0:~ }|
  50. |
  51. ]], mouse_enabled=true}
  52. feed('<LeftMouse><0,0>')
  53. screen:expect([[
  54. ^testing |
  55. mouse |
  56. support and selection |
  57. {0:~ }|
  58. |
  59. ]])
  60. end)
  61. it("in external ui works with unset 'mouse'", function()
  62. meths.set_option('mouse', '')
  63. feed('<LeftMouse><2,1>')
  64. screen:expect{grid=[[
  65. testing |
  66. mo^use |
  67. support and selection |
  68. {0:~ }|
  69. |
  70. ]], mouse_enabled=false}
  71. feed('<LeftMouse><0,0>')
  72. screen:expect([[
  73. ^testing |
  74. mouse |
  75. support and selection |
  76. {0:~ }|
  77. |
  78. ]])
  79. end)
  80. it('double left click enters visual mode', function()
  81. feed('<LeftMouse><0,0>')
  82. feed('<LeftRelease><0,0>')
  83. feed('<LeftMouse><0,0>')
  84. feed('<LeftRelease><0,0>')
  85. screen:expect([[
  86. {1:testin}^g |
  87. mouse |
  88. support and selection |
  89. {0:~ }|
  90. {2:-- VISUAL --} |
  91. ]])
  92. end)
  93. it('triple left click enters visual line mode', function()
  94. feed('<LeftMouse><0,0>')
  95. feed('<LeftRelease><0,0>')
  96. feed('<LeftMouse><0,0>')
  97. feed('<LeftRelease><0,0>')
  98. feed('<LeftMouse><0,0>')
  99. feed('<LeftRelease><0,0>')
  100. screen:expect([[
  101. ^t{1:esting} |
  102. mouse |
  103. support and selection |
  104. {0:~ }|
  105. {2:-- VISUAL LINE --} |
  106. ]])
  107. end)
  108. it('quadruple left click enters visual block mode', function()
  109. feed('<LeftMouse><0,0>')
  110. feed('<LeftRelease><0,0>')
  111. feed('<LeftMouse><0,0>')
  112. feed('<LeftRelease><0,0>')
  113. feed('<LeftMouse><0,0>')
  114. feed('<LeftRelease><0,0>')
  115. feed('<LeftMouse><0,0>')
  116. feed('<LeftRelease><0,0>')
  117. screen:expect([[
  118. ^testing |
  119. mouse |
  120. support and selection |
  121. {0:~ }|
  122. {2:-- VISUAL BLOCK --} |
  123. ]])
  124. end)
  125. describe('tab drag', function()
  126. before_each(function()
  127. screen:set_default_attr_ids( {
  128. [0] = {bold=true, foreground=Screen.colors.Blue},
  129. tab = { background=Screen.colors.LightGrey, underline=true },
  130. sel = { bold=true },
  131. fill = { reverse=true }
  132. })
  133. end)
  134. it('in tabline on filler space moves tab to the end', function()
  135. feed_command('%delete')
  136. insert('this is foo')
  137. feed_command('silent file foo | tabnew | file bar')
  138. insert('this is bar')
  139. screen:expect([[
  140. {tab: + foo }{sel: + bar }{fill: }{tab:X}|
  141. this is ba^r{0:$} |
  142. {0:~ }|
  143. {0:~ }|
  144. |
  145. ]])
  146. feed('<LeftMouse><4,0>')
  147. screen:expect([[
  148. {sel: + foo }{tab: + bar }{fill: }{tab:X}|
  149. this is fo^o |
  150. {0:~ }|
  151. {0:~ }|
  152. |
  153. ]])
  154. feed('<LeftDrag><14,0>')
  155. screen:expect([[
  156. {tab: + bar }{sel: + foo }{fill: }{tab:X}|
  157. this is fo^o |
  158. {0:~ }|
  159. {0:~ }|
  160. |
  161. ]])
  162. end)
  163. it('in tabline to the left moves tab left', function()
  164. feed_command('%delete')
  165. insert('this is foo')
  166. feed_command('silent file foo | tabnew | file bar')
  167. insert('this is bar')
  168. screen:expect([[
  169. {tab: + foo }{sel: + bar }{fill: }{tab:X}|
  170. this is ba^r{0:$} |
  171. {0:~ }|
  172. {0:~ }|
  173. |
  174. ]])
  175. feed('<LeftMouse><11,0>')
  176. screen:expect{grid=[[
  177. {tab: + foo }{sel: + bar }{fill: }{tab:X}|
  178. this is ba^r{0:$} |
  179. {0:~ }|
  180. {0:~ }|
  181. |
  182. ]], unchanged=true}
  183. feed('<LeftDrag><6,0>')
  184. screen:expect([[
  185. {sel: + bar }{tab: + foo }{fill: }{tab:X}|
  186. this is ba^r{0:$} |
  187. {0:~ }|
  188. {0:~ }|
  189. |
  190. ]])
  191. end)
  192. it('in tabline to the right moves tab right', function()
  193. feed_command('%delete')
  194. insert('this is foo')
  195. feed_command('silent file foo | tabnew | file bar')
  196. insert('this is bar')
  197. screen:expect([[
  198. {tab: + foo }{sel: + bar }{fill: }{tab:X}|
  199. this is ba^r{0:$} |
  200. {0:~ }|
  201. {0:~ }|
  202. |
  203. ]])
  204. feed('<LeftMouse><4,0>')
  205. screen:expect([[
  206. {sel: + foo }{tab: + bar }{fill: }{tab:X}|
  207. this is fo^o |
  208. {0:~ }|
  209. {0:~ }|
  210. |
  211. ]])
  212. feed('<LeftDrag><7,0>')
  213. screen:expect([[
  214. {tab: + bar }{sel: + foo }{fill: }{tab:X}|
  215. this is fo^o |
  216. {0:~ }|
  217. {0:~ }|
  218. |
  219. ]])
  220. end)
  221. it('out of tabline under filler space moves tab to the end', function()
  222. feed_command('%delete')
  223. insert('this is foo')
  224. feed_command('silent file foo | tabnew | file bar')
  225. insert('this is bar')
  226. screen:expect([[
  227. {tab: + foo }{sel: + bar }{fill: }{tab:X}|
  228. this is ba^r{0:$} |
  229. {0:~ }|
  230. {0:~ }|
  231. |
  232. ]])
  233. feed('<LeftMouse><4,0>')
  234. screen:expect([[
  235. {sel: + foo }{tab: + bar }{fill: }{tab:X}|
  236. this is fo^o |
  237. {0:~ }|
  238. {0:~ }|
  239. |
  240. ]])
  241. feed('<LeftDrag><4,1>')
  242. screen:expect{grid=[[
  243. {sel: + foo }{tab: + bar }{fill: }{tab:X}|
  244. this is fo^o |
  245. {0:~ }|
  246. {0:~ }|
  247. |
  248. ]], unchanged=true}
  249. feed('<LeftDrag><14,1>')
  250. screen:expect([[
  251. {tab: + bar }{sel: + foo }{fill: }{tab:X}|
  252. this is fo^o |
  253. {0:~ }|
  254. {0:~ }|
  255. |
  256. ]])
  257. end)
  258. it('out of tabline to the left moves tab left', function()
  259. feed_command('%delete')
  260. insert('this is foo')
  261. feed_command('silent file foo | tabnew | file bar')
  262. insert('this is bar')
  263. screen:expect([[
  264. {tab: + foo }{sel: + bar }{fill: }{tab:X}|
  265. this is ba^r{0:$} |
  266. {0:~ }|
  267. {0:~ }|
  268. |
  269. ]])
  270. feed('<LeftMouse><11,0>')
  271. screen:expect{grid=[[
  272. {tab: + foo }{sel: + bar }{fill: }{tab:X}|
  273. this is ba^r{0:$} |
  274. {0:~ }|
  275. {0:~ }|
  276. |
  277. ]], unchanged=true}
  278. feed('<LeftDrag><11,1>')
  279. screen:expect{grid=[[
  280. {tab: + foo }{sel: + bar }{fill: }{tab:X}|
  281. this is ba^r{0:$} |
  282. {0:~ }|
  283. {0:~ }|
  284. |
  285. ]], unchanged=true}
  286. feed('<LeftDrag><6,1>')
  287. screen:expect([[
  288. {sel: + bar }{tab: + foo }{fill: }{tab:X}|
  289. this is ba^r{0:$} |
  290. {0:~ }|
  291. {0:~ }|
  292. |
  293. ]])
  294. end)
  295. it('out of tabline to the right moves tab right', function()
  296. feed_command('%delete')
  297. insert('this is foo')
  298. feed_command('silent file foo | tabnew | file bar')
  299. insert('this is bar')
  300. screen:expect([[
  301. {tab: + foo }{sel: + bar }{fill: }{tab:X}|
  302. this is ba^r{0:$} |
  303. {0:~ }|
  304. {0:~ }|
  305. |
  306. ]])
  307. feed('<LeftMouse><4,0>')
  308. screen:expect([[
  309. {sel: + foo }{tab: + bar }{fill: }{tab:X}|
  310. this is fo^o |
  311. {0:~ }|
  312. {0:~ }|
  313. |
  314. ]])
  315. feed('<LeftDrag><4,1>')
  316. screen:expect{grid=[[
  317. {sel: + foo }{tab: + bar }{fill: }{tab:X}|
  318. this is fo^o |
  319. {0:~ }|
  320. {0:~ }|
  321. |
  322. ]], unchanged=true}
  323. feed('<LeftDrag><7,1>')
  324. screen:expect([[
  325. {tab: + bar }{sel: + foo }{fill: }{tab:X}|
  326. this is fo^o |
  327. {0:~ }|
  328. {0:~ }|
  329. |
  330. ]])
  331. end)
  332. end)
  333. describe('tabline', function()
  334. before_each(function()
  335. screen:set_default_attr_ids( {
  336. [0] = {bold=true, foreground=Screen.colors.Blue},
  337. tab = { background=Screen.colors.LightGrey, underline=true },
  338. sel = { bold=true },
  339. fill = { reverse=true }
  340. })
  341. end)
  342. it('left click in default tabline (position 4) switches to tab', function()
  343. feed_command('%delete')
  344. insert('this is foo')
  345. feed_command('silent file foo | tabnew | file bar')
  346. insert('this is bar')
  347. screen:expect([[
  348. {tab: + foo }{sel: + bar }{fill: }{tab:X}|
  349. this is ba^r{0:$} |
  350. {0:~ }|
  351. {0:~ }|
  352. |
  353. ]])
  354. feed('<LeftMouse><4,0>')
  355. screen:expect([[
  356. {sel: + foo }{tab: + bar }{fill: }{tab:X}|
  357. this is fo^o |
  358. {0:~ }|
  359. {0:~ }|
  360. |
  361. ]])
  362. end)
  363. it('left click in default tabline (position 24) closes tab', function()
  364. meths.set_option('hidden', true)
  365. feed_command('%delete')
  366. insert('this is foo')
  367. feed_command('silent file foo | tabnew | file bar')
  368. insert('this is bar')
  369. screen:expect([[
  370. {tab: + foo }{sel: + bar }{fill: }{tab:X}|
  371. this is ba^r{0:$} |
  372. {0:~ }|
  373. {0:~ }|
  374. |
  375. ]])
  376. feed('<LeftMouse><24,0>')
  377. screen:expect([[
  378. this is fo^o |
  379. {0:~ }|
  380. {0:~ }|
  381. {0:~ }|
  382. |
  383. ]])
  384. end)
  385. it('double click in default tabline (position 4) opens new tab', function()
  386. meths.set_option('hidden', true)
  387. feed_command('%delete')
  388. insert('this is foo')
  389. feed_command('silent file foo | tabnew | file bar')
  390. insert('this is bar')
  391. screen:expect([[
  392. {tab: + foo }{sel: + bar }{fill: }{tab:X}|
  393. this is ba^r{0:$} |
  394. {0:~ }|
  395. {0:~ }|
  396. |
  397. ]])
  398. feed('<2-LeftMouse><4,0>')
  399. screen:expect([[
  400. {sel: Name] }{tab: + foo + bar }{fill: }{tab:X}|
  401. {0:^$} |
  402. {0:~ }|
  403. {0:~ }|
  404. |
  405. ]])
  406. end)
  407. describe('%@ label', function()
  408. before_each(function()
  409. feed_command([[
  410. function Test(...)
  411. let g:reply = a:000
  412. return copy(a:000) " Check for memory leaks: return should be freed
  413. endfunction
  414. ]])
  415. feed_command([[
  416. function Test2(...)
  417. return call('Test', a:000 + [2])
  418. endfunction
  419. ]])
  420. meths.set_option('tabline', '%@Test@test%X-%5@Test2@test2')
  421. meths.set_option('showtabline', 2)
  422. screen:expect([[
  423. {fill:test-test2 }|
  424. testing |
  425. mouse |
  426. support and selectio^n |
  427. |
  428. ]])
  429. meths.set_var('reply', {})
  430. end)
  431. local check_reply = function(expected)
  432. eq(expected, meths.get_var('reply'))
  433. meths.set_var('reply', {})
  434. end
  435. local test_click = function(name, click_str, click_num, mouse_button,
  436. modifiers)
  437. local function doit(do_click)
  438. eq(1, funcs.has('tablineat'))
  439. do_click(0,3)
  440. check_reply({0, click_num, mouse_button, modifiers})
  441. do_click(0,4)
  442. check_reply({})
  443. do_click(0,6)
  444. check_reply({5, click_num, mouse_button, modifiers, 2})
  445. do_click(0,13)
  446. check_reply({5, click_num, mouse_button, modifiers, 2})
  447. end
  448. it(name .. ' works (pseudokey)', function()
  449. doit(function (row,col)
  450. feed(click_str .. '<' .. col .. ',' .. row .. '>')
  451. end)
  452. end)
  453. it(name .. ' works (nvim_input_mouse)', function()
  454. doit(function (row,col)
  455. local buttons = {l='left',m='middle',r='right'}
  456. local modstr = (click_num > 1) and tostring(click_num) or ''
  457. for char in string.gmatch(modifiers, '%w') do
  458. modstr = modstr .. char .. '-' -- - not needed but should be accepted
  459. end
  460. meths.input_mouse(buttons[mouse_button], 'press', modstr, 0, row, col)
  461. end)
  462. end)
  463. end
  464. test_click('single left click', '<LeftMouse>', 1, 'l', ' ')
  465. test_click('shifted single left click', '<S-LeftMouse>', 1, 'l', 's ')
  466. test_click('shifted single left click with alt modifier',
  467. '<S-A-LeftMouse>', 1, 'l', 's a ')
  468. test_click('shifted single left click with alt and ctrl modifiers',
  469. '<S-C-A-LeftMouse>', 1, 'l', 'sca ')
  470. -- <C-RightMouse> does not work
  471. test_click('shifted single right click with alt modifier',
  472. '<S-A-RightMouse>', 1, 'r', 's a ')
  473. -- Modifiers do not work with MiddleMouse
  474. test_click('shifted single middle click with alt and ctrl modifiers',
  475. '<MiddleMouse>', 1, 'm', ' ')
  476. -- Modifiers do not work with N-*Mouse
  477. test_click('double left click', '<2-LeftMouse>', 2, 'l', ' ')
  478. test_click('triple left click', '<3-LeftMouse>', 3, 'l', ' ')
  479. test_click('quadruple left click', '<4-LeftMouse>', 4, 'l', ' ')
  480. test_click('double right click', '<2-RightMouse>', 2, 'r', ' ')
  481. test_click('triple right click', '<3-RightMouse>', 3, 'r', ' ')
  482. test_click('quadruple right click', '<4-RightMouse>', 4, 'r', ' ')
  483. test_click('double middle click', '<2-MiddleMouse>', 2, 'm', ' ')
  484. test_click('triple middle click', '<3-MiddleMouse>', 3, 'm', ' ')
  485. test_click('quadruple middle click', '<4-MiddleMouse>', 4, 'm', ' ')
  486. end)
  487. end)
  488. it('left drag changes visual selection', function()
  489. -- drag events must be preceded by a click
  490. feed('<LeftMouse><2,1>')
  491. screen:expect([[
  492. testing |
  493. mo^use |
  494. support and selection |
  495. {0:~ }|
  496. |
  497. ]])
  498. feed('<LeftDrag><4,1>')
  499. screen:expect([[
  500. testing |
  501. mo{1:us}^e |
  502. support and selection |
  503. {0:~ }|
  504. {2:-- VISUAL --} |
  505. ]])
  506. feed('<LeftDrag><2,2>')
  507. screen:expect([[
  508. testing |
  509. mo{1:use} |
  510. {1:su}^pport and selection |
  511. {0:~ }|
  512. {2:-- VISUAL --} |
  513. ]])
  514. feed('<LeftDrag><0,0>')
  515. screen:expect([[
  516. ^t{1:esting} |
  517. {1:mou}se |
  518. support and selection |
  519. {0:~ }|
  520. {2:-- VISUAL --} |
  521. ]])
  522. end)
  523. it('left drag changes visual selection after tab click', function()
  524. screen:set_default_attr_ids({
  525. [0] = {bold=true, foreground=Screen.colors.Blue},
  526. tab = { background=Screen.colors.LightGrey, underline=true },
  527. sel = { bold=true },
  528. fill = { reverse=true },
  529. vis = { background=Screen.colors.LightGrey }
  530. })
  531. feed_command('silent file foo | tabnew | file bar')
  532. insert('this is bar')
  533. feed_command('tabprevious') -- go to first tab
  534. screen:expect([[
  535. {sel: + foo }{tab: + bar }{fill: }{tab:X}|
  536. testing |
  537. mouse |
  538. support and selectio^n |
  539. :tabprevious |
  540. ]])
  541. feed('<LeftMouse><10,0><LeftRelease>') -- go to second tab
  542. helpers.poke_eventloop()
  543. feed('<LeftMouse><0,1>')
  544. screen:expect([[
  545. {tab: + foo }{sel: + bar }{fill: }{tab:X}|
  546. ^this is bar{0:$} |
  547. {0:~ }|
  548. {0:~ }|
  549. :tabprevious |
  550. ]])
  551. feed('<LeftDrag><4,1>')
  552. screen:expect([[
  553. {tab: + foo }{sel: + bar }{fill: }{tab:X}|
  554. {vis:this}^ is bar{0:$} |
  555. {0:~ }|
  556. {0:~ }|
  557. {sel:-- VISUAL --} |
  558. ]])
  559. end)
  560. it('two clicks will select the word and enter VISUAL', function()
  561. feed('<LeftMouse><2,2><LeftMouse><2,2>')
  562. screen:expect([[
  563. testing |
  564. mouse |
  565. {1:suppor}^t and selection |
  566. {0:~ }|
  567. {2:-- VISUAL --} |
  568. ]])
  569. end)
  570. it('three clicks will select the line and enter VISUAL LINE', function()
  571. feed('<LeftMouse><2,2><LeftMouse><2,2><LeftMouse><2,2>')
  572. screen:expect([[
  573. testing |
  574. mouse |
  575. {1:su}^p{1:port and selection} |
  576. {0:~ }|
  577. {2:-- VISUAL LINE --} |
  578. ]])
  579. end)
  580. it('four clicks will enter VISUAL BLOCK', function()
  581. feed('<LeftMouse><2,2><LeftMouse><2,2><LeftMouse><2,2><LeftMouse><2,2>')
  582. screen:expect([[
  583. testing |
  584. mouse |
  585. su^pport and selection |
  586. {0:~ }|
  587. {2:-- VISUAL BLOCK --} |
  588. ]])
  589. end)
  590. it('right click extends visual selection to the clicked location', function()
  591. feed('<LeftMouse><0,0>')
  592. screen:expect([[
  593. ^testing |
  594. mouse |
  595. support and selection |
  596. {0:~ }|
  597. |
  598. ]])
  599. feed('<RightMouse><2,2>')
  600. screen:expect([[
  601. {1:testing} |
  602. {1:mouse} |
  603. {1:su}^pport and selection |
  604. {0:~ }|
  605. {2:-- VISUAL --} |
  606. ]])
  607. end)
  608. it('ctrl + left click will search for a tag', function()
  609. meths.set_option('tags', './non-existent-tags-file')
  610. feed('<C-LeftMouse><0,0>')
  611. screen:expect([[
  612. {6:E433: No tags file} |
  613. {6:E426: tag not found: test}|
  614. {6:ing} |
  615. {7:Press ENTER or type comma}|
  616. {7:nd to continue}^ |
  617. ]])
  618. feed('<cr>')
  619. end)
  620. local function wheel(use_api)
  621. feed('ggdG')
  622. insert([[
  623. Inserting
  624. text
  625. with
  626. many
  627. lines
  628. to
  629. test
  630. mouse scrolling
  631. ]])
  632. screen:try_resize(53, 14)
  633. feed('k')
  634. feed_command('sp', 'vsp')
  635. screen:expect([[
  636. lines {4:│}lines |
  637. to {4:│}to |
  638. test {4:│}test |
  639. ^mouse scrolling {4:│}mouse scrolling |
  640. {4:│} |
  641. {0:~ }{4:│}{0:~ }|
  642. {5:[No Name] [+] }{4:[No Name] [+] }|
  643. to |
  644. test |
  645. mouse scrolling |
  646. |
  647. {0:~ }|
  648. {4:[No Name] [+] }|
  649. :vsp |
  650. ]])
  651. if use_api then
  652. meths.input_mouse('wheel', 'down', '', 0, 0, 0)
  653. else
  654. feed('<ScrollWheelDown><0,0>')
  655. end
  656. screen:expect([[
  657. ^mouse scrolling {4:│}lines |
  658. {4:│}to |
  659. {0:~ }{4:│}test |
  660. {0:~ }{4:│}mouse scrolling |
  661. {0:~ }{4:│} |
  662. {0:~ }{4:│}{0:~ }|
  663. {5:[No Name] [+] }{4:[No Name] [+] }|
  664. to |
  665. test |
  666. mouse scrolling |
  667. |
  668. {0:~ }|
  669. {4:[No Name] [+] }|
  670. :vsp |
  671. ]])
  672. if use_api then
  673. meths.input_mouse('wheel', 'up', '', 0, 0, 27)
  674. else
  675. feed('<ScrollWheelUp><27,0>')
  676. end
  677. screen:expect([[
  678. ^mouse scrolling {4:│}text |
  679. {4:│}with |
  680. {0:~ }{4:│}many |
  681. {0:~ }{4:│}lines |
  682. {0:~ }{4:│}to |
  683. {0:~ }{4:│}test |
  684. {5:[No Name] [+] }{4:[No Name] [+] }|
  685. to |
  686. test |
  687. mouse scrolling |
  688. |
  689. {0:~ }|
  690. {4:[No Name] [+] }|
  691. :vsp |
  692. ]])
  693. if use_api then
  694. meths.input_mouse('wheel', 'up', '', 0, 7, 27)
  695. meths.input_mouse('wheel', 'up', '', 0, 7, 27)
  696. else
  697. feed('<ScrollWheelUp><27,7><ScrollWheelUp>')
  698. end
  699. screen:expect([[
  700. ^mouse scrolling {4:│}text |
  701. {4:│}with |
  702. {0:~ }{4:│}many |
  703. {0:~ }{4:│}lines |
  704. {0:~ }{4:│}to |
  705. {0:~ }{4:│}test |
  706. {5:[No Name] [+] }{4:[No Name] [+] }|
  707. Inserting |
  708. text |
  709. with |
  710. many |
  711. lines |
  712. {4:[No Name] [+] }|
  713. :vsp |
  714. ]])
  715. end
  716. it('mouse wheel will target the hovered window (pseudokey)', function()
  717. wheel(false)
  718. end)
  719. it('mouse wheel will target the hovered window (nvim_input_mouse)', function()
  720. wheel(true)
  721. end)
  722. it('horizontal scrolling (pseudokey)', function()
  723. command('set sidescroll=0')
  724. feed("<esc>:set nowrap<cr>")
  725. feed("a <esc>20Ab<esc>")
  726. screen:expect([[
  727. |
  728. |
  729. bbbbbbbbbbbbbbb^b |
  730. {0:~ }|
  731. |
  732. ]])
  733. feed("<ScrollWheelLeft><0,0>")
  734. screen:expect([[
  735. |
  736. |
  737. n bbbbbbbbbbbbbbbbbbb^b |
  738. {0:~ }|
  739. |
  740. ]])
  741. feed("^<ScrollWheelRight><0,0>")
  742. screen:expect([[
  743. g |
  744. |
  745. ^t and selection bbbbbbbbb|
  746. {0:~ }|
  747. |
  748. ]])
  749. end)
  750. it('horizontal scrolling (nvim_input_mouse)', function()
  751. command('set sidescroll=0')
  752. feed("<esc>:set nowrap<cr>")
  753. feed("a <esc>20Ab<esc>")
  754. screen:expect([[
  755. |
  756. |
  757. bbbbbbbbbbbbbbb^b |
  758. {0:~ }|
  759. |
  760. ]])
  761. meths.input_mouse('wheel', 'left', '', 0, 0, 27)
  762. screen:expect([[
  763. |
  764. |
  765. n bbbbbbbbbbbbbbbbbbb^b |
  766. {0:~ }|
  767. |
  768. ]])
  769. feed("^")
  770. meths.input_mouse('wheel', 'right', '', 0, 0, 0)
  771. screen:expect([[
  772. g |
  773. |
  774. ^t and selection bbbbbbbbb|
  775. {0:~ }|
  776. |
  777. ]])
  778. end)
  779. describe('on concealed text', function()
  780. -- Helpful for reading the test expectations:
  781. -- :match Error /\^/
  782. before_each(function()
  783. screen:try_resize(25, 7)
  784. screen:set_default_attr_ids({
  785. [0] = {bold=true, foreground=Screen.colors.Blue},
  786. c = { foreground = Screen.colors.LightGrey, background = Screen.colors.DarkGray },
  787. sm = {bold = true},
  788. })
  789. feed('ggdG')
  790. feed_command('set concealcursor=ni')
  791. feed_command('set nowrap')
  792. feed_command('set shiftwidth=2 tabstop=4 list')
  793. feed_command('setl listchars=tab:>-')
  794. feed_command('syntax match NonText "\\*" conceal')
  795. feed_command('syntax match NonText "cats" conceal cchar=X')
  796. feed_command('syntax match NonText "x" conceal cchar=>')
  797. -- First column is there to retain the tabs.
  798. insert([[
  799. |Section *t1*
  800. | *t2* *t3* *t4*
  801. |x 私は猫が大好き *cats* ✨🐈✨
  802. ]])
  803. feed('gg<c-v>Gxgg')
  804. end)
  805. it('(level 1) click on non-wrapped lines', function()
  806. feed_command('let &conceallevel=1', 'echo')
  807. feed('<esc><LeftMouse><0,0>')
  808. screen:expect([[
  809. ^Section{0:>>--->--->---}{c: }t1{c: } |
  810. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  811. {c:>} 私は猫が大好き{0:>---}{c: X } {0:>}|
  812. |
  813. {0:~ }|
  814. {0:~ }|
  815. |
  816. ]])
  817. feed('<esc><LeftMouse><1,0>')
  818. screen:expect([[
  819. S^ection{0:>>--->--->---}{c: }t1{c: } |
  820. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  821. {c:>} 私は猫が大好き{0:>---}{c: X } {0:>}|
  822. |
  823. {0:~ }|
  824. {0:~ }|
  825. |
  826. ]])
  827. feed('<esc><LeftMouse><21,0>')
  828. screen:expect([[
  829. Section{0:>>--->--->---}{c: }^t1{c: } |
  830. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  831. {c:>} 私は猫が大好き{0:>---}{c: X } {0:>}|
  832. |
  833. {0:~ }|
  834. {0:~ }|
  835. |
  836. ]])
  837. feed('<esc><LeftMouse><21,1>')
  838. screen:expect([[
  839. Section{0:>>--->--->---}{c: }t1{c: } |
  840. {0:>--->--->---} {c: }t2{c: } {c: }t^3{c: } {c: }|
  841. {c:>} 私は猫が大好き{0:>---}{c: X } {0:>}|
  842. |
  843. {0:~ }|
  844. {0:~ }|
  845. |
  846. ]])
  847. feed('<esc><LeftMouse><0,2>')
  848. screen:expect([[
  849. Section{0:>>--->--->---}{c: }t1{c: } |
  850. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  851. {c:^>} 私は猫が大好き{0:>---}{c: X } {0:>}|
  852. |
  853. {0:~ }|
  854. {0:~ }|
  855. |
  856. ]])
  857. feed('<esc><LeftMouse><7,2>')
  858. screen:expect([[
  859. Section{0:>>--->--->---}{c: }t1{c: } |
  860. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  861. {c:>} 私は^猫が大好き{0:>---}{c: X } {0:>}|
  862. |
  863. {0:~ }|
  864. {0:~ }|
  865. |
  866. ]])
  867. feed('<esc><LeftMouse><21,2>')
  868. screen:expect([[
  869. Section{0:>>--->--->---}{c: }t1{c: } |
  870. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  871. {c:>} 私は猫が大好き{0:>---}{c: ^X } {0:>}|
  872. |
  873. {0:~ }|
  874. {0:~ }|
  875. |
  876. ]])
  877. end) -- level 1 - non wrapped
  878. it('(level 1) click on wrapped lines', function()
  879. feed_command('let &conceallevel=1', 'let &wrap=1', 'echo')
  880. feed('<esc><LeftMouse><24,1>')
  881. screen:expect([[
  882. Section{0:>>--->--->---}{c: }t1{c: } |
  883. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c:^ }|
  884. t4{c: } |
  885. {c:>} 私は猫が大好き{0:>---}{c: X} |
  886. {c: } ✨🐈✨ |
  887. |
  888. |
  889. ]])
  890. feed('<esc><LeftMouse><0,2>')
  891. screen:expect([[
  892. Section{0:>>--->--->---}{c: }t1{c: } |
  893. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  894. ^t4{c: } |
  895. {c:>} 私は猫が大好き{0:>---}{c: X} |
  896. {c: } ✨🐈✨ |
  897. |
  898. |
  899. ]])
  900. feed('<esc><LeftMouse><8,3>')
  901. screen:expect([[
  902. Section{0:>>--->--->---}{c: }t1{c: } |
  903. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  904. t4{c: } |
  905. {c:>} 私は猫^が大好き{0:>---}{c: X} |
  906. {c: } ✨🐈✨ |
  907. |
  908. |
  909. ]])
  910. feed('<esc><LeftMouse><21,3>')
  911. screen:expect([[
  912. Section{0:>>--->--->---}{c: }t1{c: } |
  913. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  914. t4{c: } |
  915. {c:>} 私は猫が大好き{0:>---}{c: ^X} |
  916. {c: } ✨🐈✨ |
  917. |
  918. |
  919. ]])
  920. feed('<esc><LeftMouse><4,4>')
  921. screen:expect([[
  922. Section{0:>>--->--->---}{c: }t1{c: } |
  923. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  924. t4{c: } |
  925. {c:>} 私は猫が大好き{0:>---}{c: X} |
  926. {c: } ✨^🐈✨ |
  927. |
  928. |
  929. ]])
  930. end) -- level 1 - wrapped
  931. it('(level 2) click on non-wrapped lines', function()
  932. feed_command('let &conceallevel=2', 'echo')
  933. feed('<esc><LeftMouse><20,0>')
  934. screen:expect([[
  935. Section{0:>>--->--->---}^t1 |
  936. {0:>--->--->---} t2 t3 t4 |
  937. {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
  938. |
  939. {0:~ }|
  940. {0:~ }|
  941. |
  942. ]])
  943. feed('<esc><LeftMouse><14,1>')
  944. screen:expect([[
  945. Section{0:>>--->--->---}t1 |
  946. {0:>--->--->---} ^t2 t3 t4 |
  947. {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
  948. |
  949. {0:~ }|
  950. {0:~ }|
  951. |
  952. ]])
  953. feed('<esc><LeftMouse><18,1>')
  954. screen:expect([[
  955. Section{0:>>--->--->---}t1 |
  956. {0:>--->--->---} t2 t^3 t4 |
  957. {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
  958. |
  959. {0:~ }|
  960. {0:~ }|
  961. |
  962. ]])
  963. feed('<esc><LeftMouse><0,2>') -- Weirdness
  964. screen:expect([[
  965. Section{0:>>--->--->---}t1 |
  966. {0:>--->--->---} t2 t3 t4 |
  967. {c:^>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
  968. |
  969. {0:~ }|
  970. {0:~ }|
  971. |
  972. ]])
  973. feed('<esc><LeftMouse><8,2>')
  974. screen:expect([[
  975. Section{0:>>--->--->---}t1 |
  976. {0:>--->--->---} t2 t3 t4 |
  977. {c:>} 私は猫^が大好き{0:>---}{c:X} ✨{0:>}|
  978. |
  979. {0:~ }|
  980. {0:~ }|
  981. |
  982. ]])
  983. feed('<esc><LeftMouse><20,2>')
  984. screen:expect([[
  985. Section{0:>>--->--->---}t1 |
  986. {0:>--->--->---} t2 t3 t4 |
  987. {c:>} 私は猫が大好き{0:>---}{c:^X} ✨{0:>}|
  988. |
  989. {0:~ }|
  990. {0:~ }|
  991. |
  992. ]])
  993. end) -- level 2 - non wrapped
  994. it('(level 2) click on non-wrapped lines (insert mode)', function()
  995. feed_command('let &conceallevel=2', 'echo')
  996. feed('<esc>i<LeftMouse><20,0>')
  997. screen:expect([[
  998. Section{0:>>--->--->---}^t1 |
  999. {0:>--->--->---} t2 t3 t4 |
  1000. {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
  1001. |
  1002. {0:~ }|
  1003. {0:~ }|
  1004. {sm:-- INSERT --} |
  1005. ]])
  1006. feed('<LeftMouse><14,1>')
  1007. screen:expect([[
  1008. Section{0:>>--->--->---}t1 |
  1009. {0:>--->--->---} ^t2 t3 t4 |
  1010. {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
  1011. |
  1012. {0:~ }|
  1013. {0:~ }|
  1014. {sm:-- INSERT --} |
  1015. ]])
  1016. feed('<LeftMouse><18,1>')
  1017. screen:expect([[
  1018. Section{0:>>--->--->---}t1 |
  1019. {0:>--->--->---} t2 t^3 t4 |
  1020. {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
  1021. |
  1022. {0:~ }|
  1023. {0:~ }|
  1024. {sm:-- INSERT --} |
  1025. ]])
  1026. feed('<LeftMouse><0,2>') -- Weirdness
  1027. screen:expect([[
  1028. Section{0:>>--->--->---}t1 |
  1029. {0:>--->--->---} t2 t3 t4 |
  1030. {c:^>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
  1031. |
  1032. {0:~ }|
  1033. {0:~ }|
  1034. {sm:-- INSERT --} |
  1035. ]])
  1036. feed('<LeftMouse><8,2>')
  1037. screen:expect([[
  1038. Section{0:>>--->--->---}t1 |
  1039. {0:>--->--->---} t2 t3 t4 |
  1040. {c:>} 私は猫^が大好き{0:>---}{c:X} ✨{0:>}|
  1041. |
  1042. {0:~ }|
  1043. {0:~ }|
  1044. {sm:-- INSERT --} |
  1045. ]])
  1046. feed('<LeftMouse><20,2>')
  1047. screen:expect([[
  1048. Section{0:>>--->--->---}t1 |
  1049. {0:>--->--->---} t2 t3 t4 |
  1050. {c:>} 私は猫が大好き{0:>---}{c:^X} ✨{0:>}|
  1051. |
  1052. {0:~ }|
  1053. {0:~ }|
  1054. {sm:-- INSERT --} |
  1055. ]])
  1056. end) -- level 2 - non wrapped (insert mode)
  1057. it('(level 2) click on wrapped lines', function()
  1058. feed_command('let &conceallevel=2', 'let &wrap=1', 'echo')
  1059. feed('<esc><LeftMouse><20,0>')
  1060. screen:expect([[
  1061. Section{0:>>--->--->---}^t1 |
  1062. {0:>--->--->---} t2 t3 |
  1063. t4 |
  1064. {c:>} 私は猫が大好き{0:>---}{c:X} |
  1065. ✨🐈✨ |
  1066. |
  1067. |
  1068. ]])
  1069. feed('<esc><LeftMouse><14,1>')
  1070. screen:expect([[
  1071. Section{0:>>--->--->---}t1 |
  1072. {0:>--->--->---} ^t2 t3 |
  1073. t4 |
  1074. {c:>} 私は猫が大好き{0:>---}{c:X} |
  1075. ✨🐈✨ |
  1076. |
  1077. |
  1078. ]])
  1079. feed('<esc><LeftMouse><18,1>')
  1080. screen:expect([[
  1081. Section{0:>>--->--->---}t1 |
  1082. {0:>--->--->---} t2 t^3 |
  1083. t4 |
  1084. {c:>} 私は猫が大好き{0:>---}{c:X} |
  1085. ✨🐈✨ |
  1086. |
  1087. |
  1088. ]])
  1089. -- NOTE: The click would ideally be on the 't' in 't4', but wrapping
  1090. -- caused the invisible '*' right before 't4' to remain on the previous
  1091. -- screen line. This is being treated as expected because fixing this is
  1092. -- out of scope for mouse clicks. Should the wrapping behavior of
  1093. -- concealed characters change in the future, this case should be
  1094. -- reevaluated.
  1095. feed('<esc><LeftMouse><0,2>')
  1096. screen:expect([[
  1097. Section{0:>>--->--->---}t1 |
  1098. {0:>--->--->---} t2 t3 ^ |
  1099. t4 |
  1100. {c:>} 私は猫が大好き{0:>---}{c:X} |
  1101. ✨🐈✨ |
  1102. |
  1103. |
  1104. ]])
  1105. feed('<esc><LeftMouse><1,2>')
  1106. screen:expect([[
  1107. Section{0:>>--->--->---}t1 |
  1108. {0:>--->--->---} t2 t3 |
  1109. t^4 |
  1110. {c:>} 私は猫が大好き{0:>---}{c:X} |
  1111. ✨🐈✨ |
  1112. |
  1113. |
  1114. ]])
  1115. feed('<esc><LeftMouse><0,3>')
  1116. screen:expect([[
  1117. Section{0:>>--->--->---}t1 |
  1118. {0:>--->--->---} t2 t3 |
  1119. t4 |
  1120. {c:^>} 私は猫が大好き{0:>---}{c:X} |
  1121. ✨🐈✨ |
  1122. |
  1123. |
  1124. ]])
  1125. feed('<esc><LeftMouse><20,3>')
  1126. screen:expect([[
  1127. Section{0:>>--->--->---}t1 |
  1128. {0:>--->--->---} t2 t3 |
  1129. t4 |
  1130. {c:>} 私は猫が大好き{0:>---}{c:^X} |
  1131. ✨🐈✨ |
  1132. |
  1133. |
  1134. ]])
  1135. feed('<esc><LeftMouse><1,4>')
  1136. screen:expect([[
  1137. Section{0:>>--->--->---}t1 |
  1138. {0:>--->--->---} t2 t3 |
  1139. t4 |
  1140. {c:>} 私は猫が大好き{0:>---}{c:X} |
  1141. ^✨🐈✨ |
  1142. |
  1143. |
  1144. ]])
  1145. feed('<esc><LeftMouse><5,4>')
  1146. screen:expect([[
  1147. Section{0:>>--->--->---}t1 |
  1148. {0:>--->--->---} t2 t3 |
  1149. t4 |
  1150. {c:>} 私は猫が大好き{0:>---}{c:X} |
  1151. ✨🐈^✨ |
  1152. |
  1153. |
  1154. ]])
  1155. end) -- level 2 - wrapped
  1156. it('(level 3) click on non-wrapped lines', function()
  1157. feed_command('let &conceallevel=3', 'echo')
  1158. feed('<esc><LeftMouse><0,2>')
  1159. screen:expect([[
  1160. Section{0:>>--->--->---}t1 |
  1161. {0:>--->--->---} t2 t3 t4 |
  1162. ^ 私は猫が大好き{0:>----} ✨🐈|
  1163. |
  1164. {0:~ }|
  1165. {0:~ }|
  1166. |
  1167. ]])
  1168. feed('<esc><LeftMouse><1,2>')
  1169. screen:expect([[
  1170. Section{0:>>--->--->---}t1 |
  1171. {0:>--->--->---} t2 t3 t4 |
  1172. ^私は猫が大好き{0:>----} ✨🐈|
  1173. |
  1174. {0:~ }|
  1175. {0:~ }|
  1176. |
  1177. ]])
  1178. feed('<esc><LeftMouse><13,2>')
  1179. screen:expect([[
  1180. Section{0:>>--->--->---}t1 |
  1181. {0:>--->--->---} t2 t3 t4 |
  1182. 私は猫が大好^き{0:>----} ✨🐈|
  1183. |
  1184. {0:~ }|
  1185. {0:~ }|
  1186. |
  1187. ]])
  1188. feed('<esc><LeftMouse><20,2>')
  1189. screen:expect([[
  1190. Section{0:>>--->--->---}t1 |
  1191. {0:>--->--->---} t2 t3 t4 |
  1192. 私は猫が大好き{0:>----}^ ✨🐈|
  1193. |
  1194. {0:~ }|
  1195. {0:~ }|
  1196. |
  1197. ]])
  1198. end) -- level 3 - non wrapped
  1199. it('(level 3) click on wrapped lines', function()
  1200. feed_command('let &conceallevel=3', 'let &wrap=1', 'echo')
  1201. feed('<esc><LeftMouse><14,1>')
  1202. screen:expect([[
  1203. Section{0:>>--->--->---}t1 |
  1204. {0:>--->--->---} ^t2 t3 |
  1205. t4 |
  1206. 私は猫が大好き{0:>----} |
  1207. ✨🐈✨ |
  1208. |
  1209. |
  1210. ]])
  1211. feed('<esc><LeftMouse><18,1>')
  1212. screen:expect([[
  1213. Section{0:>>--->--->---}t1 |
  1214. {0:>--->--->---} t2 t^3 |
  1215. t4 |
  1216. 私は猫が大好き{0:>----} |
  1217. ✨🐈✨ |
  1218. |
  1219. |
  1220. ]])
  1221. feed('<esc><LeftMouse><1,2>')
  1222. screen:expect([[
  1223. Section{0:>>--->--->---}t1 |
  1224. {0:>--->--->---} t2 t3 |
  1225. t^4 |
  1226. 私は猫が大好き{0:>----} |
  1227. ✨🐈✨ |
  1228. |
  1229. |
  1230. ]])
  1231. feed('<esc><LeftMouse><0,3>')
  1232. screen:expect([[
  1233. Section{0:>>--->--->---}t1 |
  1234. {0:>--->--->---} t2 t3 |
  1235. t4 |
  1236. ^ 私は猫が大好き{0:>----} |
  1237. ✨🐈✨ |
  1238. |
  1239. |
  1240. ]])
  1241. feed('<esc><LeftMouse><20,3>')
  1242. screen:expect([[
  1243. Section{0:>>--->--->---}t1 |
  1244. {0:>--->--->---} t2 t3 |
  1245. t4 |
  1246. 私は猫が大好き{0:>----}^ |
  1247. ✨🐈✨ |
  1248. |
  1249. |
  1250. ]])
  1251. feed('<esc><LeftMouse><1,4>')
  1252. screen:expect([[
  1253. Section{0:>>--->--->---}t1 |
  1254. {0:>--->--->---} t2 t3 |
  1255. t4 |
  1256. 私は猫が大好き{0:>----} |
  1257. ^✨🐈✨ |
  1258. |
  1259. |
  1260. ]])
  1261. feed('<esc><LeftMouse><3,4>')
  1262. screen:expect([[
  1263. Section{0:>>--->--->---}t1 |
  1264. {0:>--->--->---} t2 t3 |
  1265. t4 |
  1266. 私は猫が大好き{0:>----} |
  1267. ✨^🐈✨ |
  1268. |
  1269. |
  1270. ]])
  1271. feed('<esc><LeftMouse><5,4>')
  1272. screen:expect([[
  1273. Section{0:>>--->--->---}t1 |
  1274. {0:>--->--->---} t2 t3 |
  1275. t4 |
  1276. 私は猫が大好き{0:>----} |
  1277. ✨🐈^✨ |
  1278. |
  1279. |
  1280. ]])
  1281. end) -- level 3 - wrapped
  1282. end)
  1283. end)