mouse_spec.lua 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594
  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('left drag changes visual selection in split layout', function()
  561. screen:try_resize(53,14)
  562. command('set mouse=a')
  563. command('vsplit')
  564. command('wincmd l')
  565. command('below split')
  566. command('enew')
  567. feed('ifoo\nbar<esc>')
  568. screen:expect{grid=[[
  569. testing {4:│}testing |
  570. mouse {4:│}mouse |
  571. support and selection {4:│}support and selection |
  572. {0:~ }{4:│}{0:~ }|
  573. {0:~ }{4:│}{0:~ }|
  574. {0:~ }{4:│[No Name] [+] }|
  575. {0:~ }{4:│}foo{0:$} |
  576. {0:~ }{4:│}ba^r{0:$} |
  577. {0:~ }{4:│}{0:~ }|
  578. {0:~ }{4:│}{0:~ }|
  579. {0:~ }{4:│}{0:~ }|
  580. {0:~ }{4:│}{0:~ }|
  581. {4:[No Name] [+] }{5:[No Name] [+] }|
  582. |
  583. ]]}
  584. meths.input_mouse('left', 'press', '', 0, 6, 27)
  585. screen:expect{grid=[[
  586. testing {4:│}testing |
  587. mouse {4:│}mouse |
  588. support and selection {4:│}support and selection |
  589. {0:~ }{4:│}{0:~ }|
  590. {0:~ }{4:│}{0:~ }|
  591. {0:~ }{4:│[No Name] [+] }|
  592. {0:~ }{4:│}^foo{0:$} |
  593. {0:~ }{4:│}bar{0:$} |
  594. {0:~ }{4:│}{0:~ }|
  595. {0:~ }{4:│}{0:~ }|
  596. {0:~ }{4:│}{0:~ }|
  597. {0:~ }{4:│}{0:~ }|
  598. {4:[No Name] [+] }{5:[No Name] [+] }|
  599. |
  600. ]]}
  601. meths.input_mouse('left', 'drag', '', 0, 7, 30)
  602. screen:expect{grid=[[
  603. testing {4:│}testing |
  604. mouse {4:│}mouse |
  605. support and selection {4:│}support and selection |
  606. {0:~ }{4:│}{0:~ }|
  607. {0:~ }{4:│}{0:~ }|
  608. {0:~ }{4:│[No Name] [+] }|
  609. {0:~ }{4:│}{1:foo}{3:$} |
  610. {0:~ }{4:│}{1:bar}{0:^$} |
  611. {0:~ }{4:│}{0:~ }|
  612. {0:~ }{4:│}{0:~ }|
  613. {0:~ }{4:│}{0:~ }|
  614. {0:~ }{4:│}{0:~ }|
  615. {4:[No Name] [+] }{5:[No Name] [+] }|
  616. {2:-- VISUAL --} |
  617. ]]}
  618. end)
  619. it('two clicks will select the word and enter VISUAL', function()
  620. feed('<LeftMouse><2,2><LeftMouse><2,2>')
  621. screen:expect([[
  622. testing |
  623. mouse |
  624. {1:suppor}^t and selection |
  625. {0:~ }|
  626. {2:-- VISUAL --} |
  627. ]])
  628. end)
  629. it('three clicks will select the line and enter VISUAL LINE', function()
  630. feed('<LeftMouse><2,2><LeftMouse><2,2><LeftMouse><2,2>')
  631. screen:expect([[
  632. testing |
  633. mouse |
  634. {1:su}^p{1:port and selection} |
  635. {0:~ }|
  636. {2:-- VISUAL LINE --} |
  637. ]])
  638. end)
  639. it('four clicks will enter VISUAL BLOCK', function()
  640. feed('<LeftMouse><2,2><LeftMouse><2,2><LeftMouse><2,2><LeftMouse><2,2>')
  641. screen:expect([[
  642. testing |
  643. mouse |
  644. su^pport and selection |
  645. {0:~ }|
  646. {2:-- VISUAL BLOCK --} |
  647. ]])
  648. end)
  649. it('right click extends visual selection to the clicked location', function()
  650. feed('<LeftMouse><0,0>')
  651. screen:expect([[
  652. ^testing |
  653. mouse |
  654. support and selection |
  655. {0:~ }|
  656. |
  657. ]])
  658. feed('<RightMouse><2,2>')
  659. screen:expect([[
  660. {1:testing} |
  661. {1:mouse} |
  662. {1:su}^pport and selection |
  663. {0:~ }|
  664. {2:-- VISUAL --} |
  665. ]])
  666. end)
  667. it('ctrl + left click will search for a tag', function()
  668. meths.set_option('tags', './non-existent-tags-file')
  669. feed('<C-LeftMouse><0,0>')
  670. screen:expect([[
  671. {6:E433: No tags file} |
  672. {6:E426: tag not found: test}|
  673. {6:ing} |
  674. {7:Press ENTER or type comma}|
  675. {7:nd to continue}^ |
  676. ]])
  677. feed('<cr>')
  678. end)
  679. local function wheel(use_api)
  680. feed('ggdG')
  681. insert([[
  682. Inserting
  683. text
  684. with
  685. many
  686. lines
  687. to
  688. test
  689. mouse scrolling
  690. ]])
  691. screen:try_resize(53, 14)
  692. feed('k')
  693. feed_command('sp', 'vsp')
  694. screen:expect([[
  695. lines {4:│}lines |
  696. to {4:│}to |
  697. test {4:│}test |
  698. ^mouse scrolling {4:│}mouse scrolling |
  699. {4:│} |
  700. {0:~ }{4:│}{0:~ }|
  701. {5:[No Name] [+] }{4:[No Name] [+] }|
  702. to |
  703. test |
  704. mouse scrolling |
  705. |
  706. {0:~ }|
  707. {4:[No Name] [+] }|
  708. :vsp |
  709. ]])
  710. if use_api then
  711. meths.input_mouse('wheel', 'down', '', 0, 0, 0)
  712. else
  713. feed('<ScrollWheelDown><0,0>')
  714. end
  715. screen:expect([[
  716. ^mouse scrolling {4:│}lines |
  717. {4:│}to |
  718. {0:~ }{4:│}test |
  719. {0:~ }{4:│}mouse scrolling |
  720. {0:~ }{4:│} |
  721. {0:~ }{4:│}{0:~ }|
  722. {5:[No Name] [+] }{4:[No Name] [+] }|
  723. to |
  724. test |
  725. mouse scrolling |
  726. |
  727. {0:~ }|
  728. {4:[No Name] [+] }|
  729. :vsp |
  730. ]])
  731. if use_api then
  732. meths.input_mouse('wheel', 'up', '', 0, 0, 27)
  733. else
  734. feed('<ScrollWheelUp><27,0>')
  735. end
  736. screen:expect([[
  737. ^mouse scrolling {4:│}text |
  738. {4:│}with |
  739. {0:~ }{4:│}many |
  740. {0:~ }{4:│}lines |
  741. {0:~ }{4:│}to |
  742. {0:~ }{4:│}test |
  743. {5:[No Name] [+] }{4:[No Name] [+] }|
  744. to |
  745. test |
  746. mouse scrolling |
  747. |
  748. {0:~ }|
  749. {4:[No Name] [+] }|
  750. :vsp |
  751. ]])
  752. if use_api then
  753. meths.input_mouse('wheel', 'up', '', 0, 7, 27)
  754. meths.input_mouse('wheel', 'up', '', 0, 7, 27)
  755. else
  756. feed('<ScrollWheelUp><27,7><ScrollWheelUp>')
  757. end
  758. screen:expect([[
  759. ^mouse scrolling {4:│}text |
  760. {4:│}with |
  761. {0:~ }{4:│}many |
  762. {0:~ }{4:│}lines |
  763. {0:~ }{4:│}to |
  764. {0:~ }{4:│}test |
  765. {5:[No Name] [+] }{4:[No Name] [+] }|
  766. Inserting |
  767. text |
  768. with |
  769. many |
  770. lines |
  771. {4:[No Name] [+] }|
  772. :vsp |
  773. ]])
  774. end
  775. it('mouse wheel will target the hovered window (pseudokey)', function()
  776. wheel(false)
  777. end)
  778. it('mouse wheel will target the hovered window (nvim_input_mouse)', function()
  779. wheel(true)
  780. end)
  781. it('horizontal scrolling (pseudokey)', function()
  782. command('set sidescroll=0')
  783. feed("<esc>:set nowrap<cr>")
  784. feed("a <esc>20Ab<esc>")
  785. screen:expect([[
  786. |
  787. |
  788. bbbbbbbbbbbbbbb^b |
  789. {0:~ }|
  790. |
  791. ]])
  792. feed("<ScrollWheelLeft><0,0>")
  793. screen:expect([[
  794. |
  795. |
  796. n bbbbbbbbbbbbbbbbbbb^b |
  797. {0:~ }|
  798. |
  799. ]])
  800. feed("^<ScrollWheelRight><0,0>")
  801. screen:expect([[
  802. g |
  803. |
  804. ^t and selection bbbbbbbbb|
  805. {0:~ }|
  806. |
  807. ]])
  808. end)
  809. it('horizontal scrolling (nvim_input_mouse)', function()
  810. command('set sidescroll=0')
  811. feed("<esc>:set nowrap<cr>")
  812. feed("a <esc>20Ab<esc>")
  813. screen:expect([[
  814. |
  815. |
  816. bbbbbbbbbbbbbbb^b |
  817. {0:~ }|
  818. |
  819. ]])
  820. meths.input_mouse('wheel', 'left', '', 0, 0, 27)
  821. screen:expect([[
  822. |
  823. |
  824. n bbbbbbbbbbbbbbbbbbb^b |
  825. {0:~ }|
  826. |
  827. ]])
  828. feed("^")
  829. meths.input_mouse('wheel', 'right', '', 0, 0, 0)
  830. screen:expect([[
  831. g |
  832. |
  833. ^t and selection bbbbbbbbb|
  834. {0:~ }|
  835. |
  836. ]])
  837. end)
  838. describe('on concealed text', function()
  839. -- Helpful for reading the test expectations:
  840. -- :match Error /\^/
  841. before_each(function()
  842. screen:try_resize(25, 7)
  843. screen:set_default_attr_ids({
  844. [0] = {bold=true, foreground=Screen.colors.Blue},
  845. c = { foreground = Screen.colors.LightGrey, background = Screen.colors.DarkGray },
  846. sm = {bold = true},
  847. })
  848. feed('ggdG')
  849. feed_command('set concealcursor=ni')
  850. feed_command('set nowrap')
  851. feed_command('set shiftwidth=2 tabstop=4 list')
  852. feed_command('setl listchars=tab:>-')
  853. feed_command('syntax match NonText "\\*" conceal')
  854. feed_command('syntax match NonText "cats" conceal cchar=X')
  855. feed_command('syntax match NonText "x" conceal cchar=>')
  856. -- First column is there to retain the tabs.
  857. insert([[
  858. |Section *t1*
  859. | *t2* *t3* *t4*
  860. |x 私は猫が大好き *cats* ✨🐈✨
  861. ]])
  862. feed('gg<c-v>Gxgg')
  863. end)
  864. it('(level 1) click on non-wrapped lines', function()
  865. feed_command('let &conceallevel=1', 'echo')
  866. feed('<esc><LeftMouse><0,0>')
  867. screen:expect([[
  868. ^Section{0:>>--->--->---}{c: }t1{c: } |
  869. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  870. {c:>} 私は猫が大好き{0:>---}{c: X } {0:>}|
  871. |
  872. {0:~ }|
  873. {0:~ }|
  874. |
  875. ]])
  876. feed('<esc><LeftMouse><1,0>')
  877. screen:expect([[
  878. S^ection{0:>>--->--->---}{c: }t1{c: } |
  879. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  880. {c:>} 私は猫が大好き{0:>---}{c: X } {0:>}|
  881. |
  882. {0:~ }|
  883. {0:~ }|
  884. |
  885. ]])
  886. feed('<esc><LeftMouse><21,0>')
  887. screen:expect([[
  888. Section{0:>>--->--->---}{c: }^t1{c: } |
  889. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  890. {c:>} 私は猫が大好き{0:>---}{c: X } {0:>}|
  891. |
  892. {0:~ }|
  893. {0:~ }|
  894. |
  895. ]])
  896. feed('<esc><LeftMouse><21,1>')
  897. screen:expect([[
  898. Section{0:>>--->--->---}{c: }t1{c: } |
  899. {0:>--->--->---} {c: }t2{c: } {c: }t^3{c: } {c: }|
  900. {c:>} 私は猫が大好き{0:>---}{c: X } {0:>}|
  901. |
  902. {0:~ }|
  903. {0:~ }|
  904. |
  905. ]])
  906. feed('<esc><LeftMouse><0,2>')
  907. screen:expect([[
  908. Section{0:>>--->--->---}{c: }t1{c: } |
  909. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  910. {c:^>} 私は猫が大好き{0:>---}{c: X } {0:>}|
  911. |
  912. {0:~ }|
  913. {0:~ }|
  914. |
  915. ]])
  916. feed('<esc><LeftMouse><7,2>')
  917. screen:expect([[
  918. Section{0:>>--->--->---}{c: }t1{c: } |
  919. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  920. {c:>} 私は^猫が大好き{0:>---}{c: X } {0:>}|
  921. |
  922. {0:~ }|
  923. {0:~ }|
  924. |
  925. ]])
  926. feed('<esc><LeftMouse><21,2>')
  927. screen:expect([[
  928. Section{0:>>--->--->---}{c: }t1{c: } |
  929. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  930. {c:>} 私は猫が大好き{0:>---}{c: ^X } {0:>}|
  931. |
  932. {0:~ }|
  933. {0:~ }|
  934. |
  935. ]])
  936. end) -- level 1 - non wrapped
  937. it('(level 1) click on wrapped lines', function()
  938. feed_command('let &conceallevel=1', 'let &wrap=1', 'echo')
  939. feed('<esc><LeftMouse><24,1>')
  940. screen:expect([[
  941. Section{0:>>--->--->---}{c: }t1{c: } |
  942. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c:^ }|
  943. t4{c: } |
  944. {c:>} 私は猫が大好き{0:>---}{c: X} |
  945. {c: } ✨🐈✨ |
  946. |
  947. |
  948. ]])
  949. feed('<esc><LeftMouse><0,2>')
  950. screen:expect([[
  951. Section{0:>>--->--->---}{c: }t1{c: } |
  952. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  953. ^t4{c: } |
  954. {c:>} 私は猫が大好き{0:>---}{c: X} |
  955. {c: } ✨🐈✨ |
  956. |
  957. |
  958. ]])
  959. feed('<esc><LeftMouse><8,3>')
  960. screen:expect([[
  961. Section{0:>>--->--->---}{c: }t1{c: } |
  962. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  963. t4{c: } |
  964. {c:>} 私は猫^が大好き{0:>---}{c: X} |
  965. {c: } ✨🐈✨ |
  966. |
  967. |
  968. ]])
  969. feed('<esc><LeftMouse><21,3>')
  970. screen:expect([[
  971. Section{0:>>--->--->---}{c: }t1{c: } |
  972. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  973. t4{c: } |
  974. {c:>} 私は猫が大好き{0:>---}{c: ^X} |
  975. {c: } ✨🐈✨ |
  976. |
  977. |
  978. ]])
  979. feed('<esc><LeftMouse><4,4>')
  980. screen:expect([[
  981. Section{0:>>--->--->---}{c: }t1{c: } |
  982. {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }|
  983. t4{c: } |
  984. {c:>} 私は猫が大好き{0:>---}{c: X} |
  985. {c: } ✨^🐈✨ |
  986. |
  987. |
  988. ]])
  989. end) -- level 1 - wrapped
  990. it('(level 2) click on non-wrapped lines', function()
  991. feed_command('let &conceallevel=2', 'echo')
  992. feed('<esc><LeftMouse><20,0>')
  993. screen:expect([[
  994. Section{0:>>--->--->---}^t1 |
  995. {0:>--->--->---} t2 t3 t4 |
  996. {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
  997. |
  998. {0:~ }|
  999. {0:~ }|
  1000. |
  1001. ]])
  1002. feed('<esc><LeftMouse><14,1>')
  1003. screen:expect([[
  1004. Section{0:>>--->--->---}t1 |
  1005. {0:>--->--->---} ^t2 t3 t4 |
  1006. {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
  1007. |
  1008. {0:~ }|
  1009. {0:~ }|
  1010. |
  1011. ]])
  1012. feed('<esc><LeftMouse><18,1>')
  1013. screen:expect([[
  1014. Section{0:>>--->--->---}t1 |
  1015. {0:>--->--->---} t2 t^3 t4 |
  1016. {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
  1017. |
  1018. {0:~ }|
  1019. {0:~ }|
  1020. |
  1021. ]])
  1022. feed('<esc><LeftMouse><0,2>') -- Weirdness
  1023. screen:expect([[
  1024. Section{0:>>--->--->---}t1 |
  1025. {0:>--->--->---} t2 t3 t4 |
  1026. {c:^>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
  1027. |
  1028. {0:~ }|
  1029. {0:~ }|
  1030. |
  1031. ]])
  1032. feed('<esc><LeftMouse><8,2>')
  1033. screen:expect([[
  1034. Section{0:>>--->--->---}t1 |
  1035. {0:>--->--->---} t2 t3 t4 |
  1036. {c:>} 私は猫^が大好き{0:>---}{c:X} ✨{0:>}|
  1037. |
  1038. {0:~ }|
  1039. {0:~ }|
  1040. |
  1041. ]])
  1042. feed('<esc><LeftMouse><20,2>')
  1043. screen:expect([[
  1044. Section{0:>>--->--->---}t1 |
  1045. {0:>--->--->---} t2 t3 t4 |
  1046. {c:>} 私は猫が大好き{0:>---}{c:^X} ✨{0:>}|
  1047. |
  1048. {0:~ }|
  1049. {0:~ }|
  1050. |
  1051. ]])
  1052. end) -- level 2 - non wrapped
  1053. it('(level 2) click on non-wrapped lines (insert mode)', function()
  1054. feed_command('let &conceallevel=2', 'echo')
  1055. feed('<esc>i<LeftMouse><20,0>')
  1056. screen:expect([[
  1057. Section{0:>>--->--->---}^t1 |
  1058. {0:>--->--->---} t2 t3 t4 |
  1059. {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
  1060. |
  1061. {0:~ }|
  1062. {0:~ }|
  1063. {sm:-- INSERT --} |
  1064. ]])
  1065. feed('<LeftMouse><14,1>')
  1066. screen:expect([[
  1067. Section{0:>>--->--->---}t1 |
  1068. {0:>--->--->---} ^t2 t3 t4 |
  1069. {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
  1070. |
  1071. {0:~ }|
  1072. {0:~ }|
  1073. {sm:-- INSERT --} |
  1074. ]])
  1075. feed('<LeftMouse><18,1>')
  1076. screen:expect([[
  1077. Section{0:>>--->--->---}t1 |
  1078. {0:>--->--->---} t2 t^3 t4 |
  1079. {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
  1080. |
  1081. {0:~ }|
  1082. {0:~ }|
  1083. {sm:-- INSERT --} |
  1084. ]])
  1085. feed('<LeftMouse><0,2>') -- Weirdness
  1086. screen:expect([[
  1087. Section{0:>>--->--->---}t1 |
  1088. {0:>--->--->---} t2 t3 t4 |
  1089. {c:^>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}|
  1090. |
  1091. {0:~ }|
  1092. {0:~ }|
  1093. {sm:-- INSERT --} |
  1094. ]])
  1095. feed('<LeftMouse><8,2>')
  1096. screen:expect([[
  1097. Section{0:>>--->--->---}t1 |
  1098. {0:>--->--->---} t2 t3 t4 |
  1099. {c:>} 私は猫^が大好き{0:>---}{c:X} ✨{0:>}|
  1100. |
  1101. {0:~ }|
  1102. {0:~ }|
  1103. {sm:-- INSERT --} |
  1104. ]])
  1105. feed('<LeftMouse><20,2>')
  1106. screen:expect([[
  1107. Section{0:>>--->--->---}t1 |
  1108. {0:>--->--->---} t2 t3 t4 |
  1109. {c:>} 私は猫が大好き{0:>---}{c:^X} ✨{0:>}|
  1110. |
  1111. {0:~ }|
  1112. {0:~ }|
  1113. {sm:-- INSERT --} |
  1114. ]])
  1115. end) -- level 2 - non wrapped (insert mode)
  1116. it('(level 2) click on wrapped lines', function()
  1117. feed_command('let &conceallevel=2', 'let &wrap=1', 'echo')
  1118. feed('<esc><LeftMouse><20,0>')
  1119. screen:expect([[
  1120. Section{0:>>--->--->---}^t1 |
  1121. {0:>--->--->---} t2 t3 |
  1122. t4 |
  1123. {c:>} 私は猫が大好き{0:>---}{c:X} |
  1124. ✨🐈✨ |
  1125. |
  1126. |
  1127. ]])
  1128. feed('<esc><LeftMouse><14,1>')
  1129. screen:expect([[
  1130. Section{0:>>--->--->---}t1 |
  1131. {0:>--->--->---} ^t2 t3 |
  1132. t4 |
  1133. {c:>} 私は猫が大好き{0:>---}{c:X} |
  1134. ✨🐈✨ |
  1135. |
  1136. |
  1137. ]])
  1138. feed('<esc><LeftMouse><18,1>')
  1139. screen:expect([[
  1140. Section{0:>>--->--->---}t1 |
  1141. {0:>--->--->---} t2 t^3 |
  1142. t4 |
  1143. {c:>} 私は猫が大好き{0:>---}{c:X} |
  1144. ✨🐈✨ |
  1145. |
  1146. |
  1147. ]])
  1148. -- NOTE: The click would ideally be on the 't' in 't4', but wrapping
  1149. -- caused the invisible '*' right before 't4' to remain on the previous
  1150. -- screen line. This is being treated as expected because fixing this is
  1151. -- out of scope for mouse clicks. Should the wrapping behavior of
  1152. -- concealed characters change in the future, this case should be
  1153. -- reevaluated.
  1154. feed('<esc><LeftMouse><0,2>')
  1155. screen:expect([[
  1156. Section{0:>>--->--->---}t1 |
  1157. {0:>--->--->---} t2 t3 ^ |
  1158. t4 |
  1159. {c:>} 私は猫が大好き{0:>---}{c:X} |
  1160. ✨🐈✨ |
  1161. |
  1162. |
  1163. ]])
  1164. feed('<esc><LeftMouse><1,2>')
  1165. screen:expect([[
  1166. Section{0:>>--->--->---}t1 |
  1167. {0:>--->--->---} t2 t3 |
  1168. t^4 |
  1169. {c:>} 私は猫が大好き{0:>---}{c:X} |
  1170. ✨🐈✨ |
  1171. |
  1172. |
  1173. ]])
  1174. feed('<esc><LeftMouse><0,3>')
  1175. screen:expect([[
  1176. Section{0:>>--->--->---}t1 |
  1177. {0:>--->--->---} t2 t3 |
  1178. t4 |
  1179. {c:^>} 私は猫が大好き{0:>---}{c:X} |
  1180. ✨🐈✨ |
  1181. |
  1182. |
  1183. ]])
  1184. feed('<esc><LeftMouse><20,3>')
  1185. screen:expect([[
  1186. Section{0:>>--->--->---}t1 |
  1187. {0:>--->--->---} t2 t3 |
  1188. t4 |
  1189. {c:>} 私は猫が大好き{0:>---}{c:^X} |
  1190. ✨🐈✨ |
  1191. |
  1192. |
  1193. ]])
  1194. feed('<esc><LeftMouse><1,4>')
  1195. screen:expect([[
  1196. Section{0:>>--->--->---}t1 |
  1197. {0:>--->--->---} t2 t3 |
  1198. t4 |
  1199. {c:>} 私は猫が大好き{0:>---}{c:X} |
  1200. ^✨🐈✨ |
  1201. |
  1202. |
  1203. ]])
  1204. feed('<esc><LeftMouse><5,4>')
  1205. screen:expect([[
  1206. Section{0:>>--->--->---}t1 |
  1207. {0:>--->--->---} t2 t3 |
  1208. t4 |
  1209. {c:>} 私は猫が大好き{0:>---}{c:X} |
  1210. ✨🐈^✨ |
  1211. |
  1212. |
  1213. ]])
  1214. end) -- level 2 - wrapped
  1215. it('(level 3) click on non-wrapped lines', function()
  1216. feed_command('let &conceallevel=3', 'echo')
  1217. feed('<esc><LeftMouse><0,2>')
  1218. screen:expect([[
  1219. Section{0:>>--->--->---}t1 |
  1220. {0:>--->--->---} t2 t3 t4 |
  1221. ^ 私は猫が大好き{0:>----} ✨🐈|
  1222. |
  1223. {0:~ }|
  1224. {0:~ }|
  1225. |
  1226. ]])
  1227. feed('<esc><LeftMouse><1,2>')
  1228. screen:expect([[
  1229. Section{0:>>--->--->---}t1 |
  1230. {0:>--->--->---} t2 t3 t4 |
  1231. ^私は猫が大好き{0:>----} ✨🐈|
  1232. |
  1233. {0:~ }|
  1234. {0:~ }|
  1235. |
  1236. ]])
  1237. feed('<esc><LeftMouse><13,2>')
  1238. screen:expect([[
  1239. Section{0:>>--->--->---}t1 |
  1240. {0:>--->--->---} t2 t3 t4 |
  1241. 私は猫が大好^き{0:>----} ✨🐈|
  1242. |
  1243. {0:~ }|
  1244. {0:~ }|
  1245. |
  1246. ]])
  1247. feed('<esc><LeftMouse><20,2>')
  1248. screen:expect([[
  1249. Section{0:>>--->--->---}t1 |
  1250. {0:>--->--->---} t2 t3 t4 |
  1251. 私は猫が大好き{0:>----}^ ✨🐈|
  1252. |
  1253. {0:~ }|
  1254. {0:~ }|
  1255. |
  1256. ]])
  1257. end) -- level 3 - non wrapped
  1258. it('(level 3) click on wrapped lines', function()
  1259. feed_command('let &conceallevel=3', 'let &wrap=1', 'echo')
  1260. feed('<esc><LeftMouse><14,1>')
  1261. screen:expect([[
  1262. Section{0:>>--->--->---}t1 |
  1263. {0:>--->--->---} ^t2 t3 |
  1264. t4 |
  1265. 私は猫が大好き{0:>----} |
  1266. ✨🐈✨ |
  1267. |
  1268. |
  1269. ]])
  1270. feed('<esc><LeftMouse><18,1>')
  1271. screen:expect([[
  1272. Section{0:>>--->--->---}t1 |
  1273. {0:>--->--->---} t2 t^3 |
  1274. t4 |
  1275. 私は猫が大好き{0:>----} |
  1276. ✨🐈✨ |
  1277. |
  1278. |
  1279. ]])
  1280. feed('<esc><LeftMouse><1,2>')
  1281. screen:expect([[
  1282. Section{0:>>--->--->---}t1 |
  1283. {0:>--->--->---} t2 t3 |
  1284. t^4 |
  1285. 私は猫が大好き{0:>----} |
  1286. ✨🐈✨ |
  1287. |
  1288. |
  1289. ]])
  1290. feed('<esc><LeftMouse><0,3>')
  1291. screen:expect([[
  1292. Section{0:>>--->--->---}t1 |
  1293. {0:>--->--->---} t2 t3 |
  1294. t4 |
  1295. ^ 私は猫が大好き{0:>----} |
  1296. ✨🐈✨ |
  1297. |
  1298. |
  1299. ]])
  1300. feed('<esc><LeftMouse><20,3>')
  1301. screen:expect([[
  1302. Section{0:>>--->--->---}t1 |
  1303. {0:>--->--->---} t2 t3 |
  1304. t4 |
  1305. 私は猫が大好き{0:>----}^ |
  1306. ✨🐈✨ |
  1307. |
  1308. |
  1309. ]])
  1310. feed('<esc><LeftMouse><1,4>')
  1311. screen:expect([[
  1312. Section{0:>>--->--->---}t1 |
  1313. {0:>--->--->---} t2 t3 |
  1314. t4 |
  1315. 私は猫が大好き{0:>----} |
  1316. ^✨🐈✨ |
  1317. |
  1318. |
  1319. ]])
  1320. feed('<esc><LeftMouse><3,4>')
  1321. screen:expect([[
  1322. Section{0:>>--->--->---}t1 |
  1323. {0:>--->--->---} t2 t3 |
  1324. t4 |
  1325. 私は猫が大好き{0:>----} |
  1326. ✨^🐈✨ |
  1327. |
  1328. |
  1329. ]])
  1330. feed('<esc><LeftMouse><5,4>')
  1331. screen:expect([[
  1332. Section{0:>>--->--->---}t1 |
  1333. {0:>--->--->---} t2 t3 |
  1334. t4 |
  1335. 私は猫が大好き{0:>----} |
  1336. ✨🐈^✨ |
  1337. |
  1338. |
  1339. ]])
  1340. end) -- level 3 - wrapped
  1341. end)
  1342. it('getmousepos works correctly', function()
  1343. local winwidth = meths.get_option('winwidth')
  1344. -- Set winwidth=1 so that window sizes don't change.
  1345. meths.set_option('winwidth', 1)
  1346. command('tabedit')
  1347. local tabpage = meths.get_current_tabpage()
  1348. insert('hello')
  1349. command('vsplit')
  1350. local opts = {
  1351. relative='editor',
  1352. width=12,
  1353. height=1,
  1354. col=8,
  1355. row=1,
  1356. anchor='NW',
  1357. style='minimal',
  1358. border='single',
  1359. focusable=1
  1360. }
  1361. local float = meths.open_win(meths.get_current_buf(), false, opts)
  1362. command('redraw')
  1363. local lines = meths.get_option('lines')
  1364. local columns = meths.get_option('columns')
  1365. -- Test that screenrow and screencol are set properly for all positions.
  1366. for row = 0, lines - 1 do
  1367. for col = 0, columns - 1 do
  1368. -- Skip the X button that would close the tab.
  1369. if row ~= 0 or col ~= columns - 1 then
  1370. meths.input_mouse('left', 'press', '', 0, row, col)
  1371. meths.set_current_tabpage(tabpage)
  1372. local mousepos = funcs.getmousepos()
  1373. eq(row + 1, mousepos.screenrow)
  1374. eq(col + 1, mousepos.screencol)
  1375. -- All other values should be 0 when clicking on the command line.
  1376. if row == lines - 1 then
  1377. eq(0, mousepos.winid)
  1378. eq(0, mousepos.winrow)
  1379. eq(0, mousepos.wincol)
  1380. eq(0, mousepos.line)
  1381. eq(0, mousepos.column)
  1382. end
  1383. end
  1384. end
  1385. end
  1386. -- Test that mouse position values are properly set for the floating window
  1387. -- with a border. 1 is added to the height and width to account for the
  1388. -- border.
  1389. for win_row = 0, opts.height + 1 do
  1390. for win_col = 0, opts.width + 1 do
  1391. local row = win_row + opts.row
  1392. local col = win_col + opts.col
  1393. meths.input_mouse('left', 'press', '', 0, row, col)
  1394. local mousepos = funcs.getmousepos()
  1395. eq(float.id, mousepos.winid)
  1396. eq(win_row + 1, mousepos.winrow)
  1397. eq(win_col + 1, mousepos.wincol)
  1398. local line = 0
  1399. local column = 0
  1400. if win_row > 0 and win_row < opts.height + 1
  1401. and win_col > 0 and win_col < opts.width + 1 then
  1402. -- Because of border, win_row and win_col don't need to be
  1403. -- incremented by 1.
  1404. line = math.min(win_row, funcs.line('$'))
  1405. column = math.min(win_col, #funcs.getline(line) + 1)
  1406. end
  1407. eq(line, mousepos.line)
  1408. eq(column, mousepos.column)
  1409. end
  1410. end
  1411. -- Test that mouse position values are properly set for the floating
  1412. -- window, after removing the border.
  1413. opts.border = 'none'
  1414. meths.win_set_config(float, opts)
  1415. command('redraw')
  1416. for win_row = 0, opts.height - 1 do
  1417. for win_col = 0, opts.width - 1 do
  1418. local row = win_row + opts.row
  1419. local col = win_col + opts.col
  1420. meths.input_mouse('left', 'press', '', 0, row, col)
  1421. local mousepos = funcs.getmousepos()
  1422. eq(float.id, mousepos.winid)
  1423. eq(win_row + 1, mousepos.winrow)
  1424. eq(win_col + 1, mousepos.wincol)
  1425. local line = math.min(win_row + 1, funcs.line('$'))
  1426. local column = math.min(win_col + 1, #funcs.getline(line) + 1)
  1427. eq(line, mousepos.line)
  1428. eq(column, mousepos.column)
  1429. end
  1430. end
  1431. -- Test that mouse position values are properly set for ordinary windows.
  1432. -- Set the float to be unfocusable instead of closing, to additionally test
  1433. -- that getmousepos does not consider unfocusable floats. (see discussion
  1434. -- in PR #14937 for details).
  1435. opts.focusable = false
  1436. meths.win_set_config(float, opts)
  1437. command('redraw')
  1438. for nr = 1, 2 do
  1439. for win_row = 0, funcs.winheight(nr) - 1 do
  1440. for win_col = 0, funcs.winwidth(nr) - 1 do
  1441. local row = win_row + funcs.win_screenpos(nr)[1] - 1
  1442. local col = win_col + funcs.win_screenpos(nr)[2] - 1
  1443. meths.input_mouse('left', 'press', '', 0, row, col)
  1444. local mousepos = funcs.getmousepos()
  1445. eq(funcs.win_getid(nr), mousepos.winid)
  1446. eq(win_row + 1, mousepos.winrow)
  1447. eq(win_col + 1, mousepos.wincol)
  1448. local line = math.min(win_row + 1, funcs.line('$'))
  1449. local column = math.min(win_col + 1, #funcs.getline(line) + 1)
  1450. eq(line, mousepos.line)
  1451. eq(column, mousepos.column)
  1452. end
  1453. end
  1454. end
  1455. -- Restore state and release mouse.
  1456. command('tabclose!')
  1457. meths.set_option('winwidth', winwidth)
  1458. meths.input_mouse('left', 'release', '', 0, 0, 0)
  1459. end)
  1460. it('scroll keys are not translated into multiclicks #6211 #6989', function()
  1461. meths.set_var('mouse_up', 0)
  1462. meths.set_var('mouse_up2', 0)
  1463. meths.set_var('mouse_up3', 0)
  1464. meths.set_var('mouse_up4', 0)
  1465. command('nnoremap <ScrollWheelUp> <Cmd>let g:mouse_up += 1<CR>')
  1466. command('nnoremap <2-ScrollWheelUp> <Cmd>let g:mouse_up2 += 1<CR>')
  1467. command('nnoremap <3-ScrollWheelUp> <Cmd>let g:mouse_up3 += 1<CR>')
  1468. command('nnoremap <4-ScrollWheelUp> <Cmd>let g:mouse_up4 += 1<CR>')
  1469. meths.input_mouse('wheel', 'up', '', 0, 0, 0)
  1470. meths.input_mouse('wheel', 'up', '', 0, 0, 0)
  1471. meths.input_mouse('wheel', 'up', '', 0, 0, 0)
  1472. meths.input_mouse('wheel', 'up', '', 0, 0, 0)
  1473. eq(4, meths.get_var('mouse_up'))
  1474. eq(0, meths.get_var('mouse_up2'))
  1475. eq(0, meths.get_var('mouse_up3'))
  1476. eq(0, meths.get_var('mouse_up4'))
  1477. end)
  1478. end)