mouse_spec.lua 41 KB

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