comment_spec.lua 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. local t = require('test.testutil')
  2. local n = require('test.functional.testnvim')()
  3. local api = n.api
  4. local clear = n.clear
  5. local eq = t.eq
  6. local exec_capture = n.exec_capture
  7. local exec_lua = n.exec_lua
  8. local feed = n.feed
  9. -- Reference text
  10. -- aa
  11. -- aa
  12. -- aa
  13. --
  14. -- aa
  15. -- aa
  16. -- aa
  17. local example_lines = { 'aa', ' aa', ' aa', '', ' aa', ' aa', 'aa' }
  18. local set_commentstring = function(commentstring)
  19. api.nvim_set_option_value('commentstring', commentstring, { buf = 0 })
  20. end
  21. local get_lines = function(from, to)
  22. from, to = from or 0, to or -1
  23. return api.nvim_buf_get_lines(0, from, to, false)
  24. end
  25. local set_lines = function(lines, from, to)
  26. from, to = from or 0, to or -1
  27. api.nvim_buf_set_lines(0, from, to, false, lines)
  28. end
  29. local set_cursor = function(row, col)
  30. api.nvim_win_set_cursor(0, { row, col })
  31. end
  32. local get_cursor = function()
  33. return api.nvim_win_get_cursor(0)
  34. end
  35. local setup_treesitter = function()
  36. -- NOTE: This leverages bundled Vimscript and Lua tree-sitter parsers
  37. api.nvim_set_option_value('filetype', 'vim', { buf = 0 })
  38. exec_lua('vim.treesitter.start()')
  39. end
  40. before_each(function()
  41. clear({ args_rm = { '--cmd' }, args = { '--clean' } })
  42. end)
  43. describe('commenting', function()
  44. before_each(function()
  45. set_lines(example_lines)
  46. set_commentstring('# %s')
  47. end)
  48. describe('toggle_lines()', function()
  49. local toggle_lines = function(...)
  50. exec_lua('require("vim._comment").toggle_lines(...)', ...)
  51. end
  52. it('works', function()
  53. toggle_lines(3, 5)
  54. eq(get_lines(2, 5), { ' # aa', ' #', ' # aa' })
  55. toggle_lines(3, 5)
  56. eq(get_lines(2, 5), { ' aa', '', ' aa' })
  57. end)
  58. it("works with different 'commentstring' options", function()
  59. local validate = function(lines_before, lines_after, lines_again)
  60. set_lines(lines_before)
  61. toggle_lines(1, #lines_before)
  62. eq(get_lines(), lines_after)
  63. toggle_lines(1, #lines_before)
  64. eq(get_lines(), lines_again or lines_before)
  65. end
  66. -- Single whitespace inside comment parts (main case)
  67. set_commentstring('# %s #')
  68. -- - General case
  69. validate(
  70. { 'aa', ' aa', 'aa ', ' aa ' },
  71. { '# aa #', '# aa #', '# aa #', '# aa #' }
  72. )
  73. -- - Tabs
  74. validate(
  75. { 'aa', '\taa', 'aa\t', '\taa\t' },
  76. { '# aa #', '# \taa #', '# aa\t #', '# \taa\t #' }
  77. )
  78. -- - With indent
  79. validate({ ' aa', ' aa' }, { ' # aa #', ' # aa #' })
  80. -- - With blank/empty lines
  81. validate(
  82. { ' aa', '', ' ', '\t' },
  83. { ' # aa #', ' ##', ' ##', ' ##' },
  84. { ' aa', '', '', '' }
  85. )
  86. set_commentstring('# %s')
  87. validate({ 'aa', ' aa', 'aa ', ' aa ' }, { '# aa', '# aa', '# aa ', '# aa ' })
  88. validate({ 'aa', '\taa', 'aa\t', '\taa\t' }, { '# aa', '# \taa', '# aa\t', '# \taa\t' })
  89. validate({ ' aa', ' aa' }, { ' # aa', ' # aa' })
  90. validate(
  91. { ' aa', '', ' ', '\t' },
  92. { ' # aa', ' #', ' #', ' #' },
  93. { ' aa', '', '', '' }
  94. )
  95. set_commentstring('%s #')
  96. validate({ 'aa', ' aa', 'aa ', ' aa ' }, { 'aa #', ' aa #', 'aa #', ' aa #' })
  97. validate({ 'aa', '\taa', 'aa\t', '\taa\t' }, { 'aa #', '\taa #', 'aa\t #', '\taa\t #' })
  98. validate({ ' aa', ' aa' }, { ' aa #', ' aa #' })
  99. validate(
  100. { ' aa', '', ' ', '\t' },
  101. { ' aa #', ' #', ' #', ' #' },
  102. { ' aa', '', '', '' }
  103. )
  104. -- No whitespace in parts
  105. set_commentstring('#%s#')
  106. validate({ 'aa', ' aa', 'aa ', ' aa ' }, { '#aa#', '# aa#', '#aa #', '# aa #' })
  107. validate({ 'aa', '\taa', 'aa\t', '\taa\t' }, { '#aa#', '#\taa#', '#aa\t#', '#\taa\t#' })
  108. validate({ ' aa', ' aa' }, { ' #aa#', ' # aa#' })
  109. validate(
  110. { ' aa', '', ' ', '\t' },
  111. { ' #aa#', ' ##', ' ##', ' ##' },
  112. { ' aa', '', '', '' }
  113. )
  114. set_commentstring('#%s')
  115. validate({ 'aa', ' aa', 'aa ', ' aa ' }, { '#aa', '# aa', '#aa ', '# aa ' })
  116. validate({ 'aa', '\taa', 'aa\t', '\taa\t' }, { '#aa', '#\taa', '#aa\t', '#\taa\t' })
  117. validate({ ' aa', ' aa' }, { ' #aa', ' # aa' })
  118. validate({ ' aa', '', ' ', '\t' }, { ' #aa', ' #', ' #', ' #' }, { ' aa', '', '', '' })
  119. set_commentstring('%s#')
  120. validate({ 'aa', ' aa', 'aa ', ' aa ' }, { 'aa#', ' aa#', 'aa #', ' aa #' })
  121. validate({ 'aa', '\taa', 'aa\t', '\taa\t' }, { 'aa#', '\taa#', 'aa\t#', '\taa\t#' })
  122. validate({ ' aa', ' aa' }, { ' aa#', ' aa#' })
  123. validate({ ' aa', '', ' ', '\t' }, { ' aa#', ' #', ' #', ' #' }, { ' aa', '', '', '' })
  124. -- Extra whitespace inside comment parts
  125. set_commentstring('# %s #')
  126. validate(
  127. { 'aa', ' aa', 'aa ', ' aa ' },
  128. { '# aa #', '# aa #', '# aa #', '# aa #' }
  129. )
  130. validate(
  131. { 'aa', '\taa', 'aa\t', '\taa\t' },
  132. { '# aa #', '# \taa #', '# aa\t #', '# \taa\t #' }
  133. )
  134. validate({ ' aa', ' aa' }, { ' # aa #', ' # aa #' })
  135. validate(
  136. { ' aa', '', ' ', '\t' },
  137. { ' # aa #', ' ##', ' ##', ' ##' },
  138. { ' aa', '', '', '' }
  139. )
  140. set_commentstring('# %s')
  141. validate({ 'aa', ' aa', 'aa ', ' aa ' }, { '# aa', '# aa', '# aa ', '# aa ' })
  142. validate({ 'aa', '\taa', 'aa\t', '\taa\t' }, { '# aa', '# \taa', '# aa\t', '# \taa\t' })
  143. validate({ ' aa', ' aa' }, { ' # aa', ' # aa' })
  144. validate(
  145. { ' aa', '', ' ', '\t' },
  146. { ' # aa', ' #', ' #', ' #' },
  147. { ' aa', '', '', '' }
  148. )
  149. set_commentstring('%s #')
  150. validate({ 'aa', ' aa', 'aa ', ' aa ' }, { 'aa #', ' aa #', 'aa #', ' aa #' })
  151. validate({ 'aa', '\taa', 'aa\t', '\taa\t' }, { 'aa #', '\taa #', 'aa\t #', '\taa\t #' })
  152. validate({ ' aa', ' aa' }, { ' aa #', ' aa #' })
  153. validate(
  154. { ' aa', '', ' ', '\t' },
  155. { ' aa #', ' #', ' #', ' #' },
  156. { ' aa', '', '', '' }
  157. )
  158. -- Whitespace outside of comment parts
  159. set_commentstring(' # %s # ')
  160. validate(
  161. { 'aa', ' aa', 'aa ', ' aa ' },
  162. { ' # aa # ', ' # aa # ', ' # aa # ', ' # aa # ' }
  163. )
  164. validate(
  165. { 'aa', '\taa', 'aa\t', '\taa\t' },
  166. { ' # aa # ', ' # \taa # ', ' # aa\t # ', ' # \taa\t # ' }
  167. )
  168. validate({ ' aa', ' aa' }, { ' # aa # ', ' # aa # ' })
  169. validate(
  170. { ' aa', '', ' ', '\t' },
  171. { ' # aa # ', ' ##', ' ##', ' ##' },
  172. { ' aa', '', '', '' }
  173. )
  174. set_commentstring(' # %s ')
  175. validate(
  176. { 'aa', ' aa', 'aa ', ' aa ' },
  177. { ' # aa ', ' # aa ', ' # aa ', ' # aa ' }
  178. )
  179. validate(
  180. { 'aa', '\taa', 'aa\t', '\taa\t' },
  181. { ' # aa ', ' # \taa ', ' # aa\t ', ' # \taa\t ' }
  182. )
  183. validate({ ' aa', ' aa' }, { ' # aa ', ' # aa ' })
  184. validate(
  185. { ' aa', '', ' ', '\t' },
  186. { ' # aa ', ' #', ' #', ' #' },
  187. { ' aa', '', '', '' }
  188. )
  189. set_commentstring(' %s # ')
  190. validate(
  191. { 'aa', ' aa', 'aa ', ' aa ' },
  192. { ' aa # ', ' aa # ', ' aa # ', ' aa # ' }
  193. )
  194. validate(
  195. { 'aa', '\taa', 'aa\t', '\taa\t' },
  196. { ' aa # ', ' \taa # ', ' aa\t # ', ' \taa\t # ' }
  197. )
  198. validate({ ' aa', ' aa' }, { ' aa # ', ' aa # ' })
  199. validate(
  200. { ' aa', '', ' ', '\t' },
  201. { ' aa # ', ' #', ' #', ' #' },
  202. { ' aa', '', '', '' }
  203. )
  204. -- LaTeX
  205. set_commentstring('% %s')
  206. validate({ 'aa', ' aa', 'aa ', ' aa ' }, { '% aa', '% aa', '% aa ', '% aa ' })
  207. validate({ 'aa', '\taa', 'aa\t', '\taa\t' }, { '% aa', '% \taa', '% aa\t', '% \taa\t' })
  208. validate({ ' aa', ' aa' }, { ' % aa', ' % aa' })
  209. validate(
  210. { ' aa', '', ' ', '\t' },
  211. { ' % aa', ' %', ' %', ' %' },
  212. { ' aa', '', '', '' }
  213. )
  214. end)
  215. it('respects tree-sitter injections', function()
  216. setup_treesitter()
  217. local lines = {
  218. 'set background=dark',
  219. 'lua << EOF',
  220. 'print(1)',
  221. 'vim.api.nvim_exec2([[',
  222. ' set background=light',
  223. ']])',
  224. 'EOF',
  225. }
  226. -- Single line comments
  227. local validate = function(line, ref_output)
  228. set_lines(lines)
  229. toggle_lines(line, line)
  230. eq(get_lines(line - 1, line)[1], ref_output)
  231. end
  232. validate(1, '"set background=dark')
  233. validate(2, '"lua << EOF')
  234. validate(3, '-- print(1)')
  235. validate(4, '-- vim.api.nvim_exec2([[')
  236. validate(5, ' "set background=light')
  237. validate(6, '-- ]])')
  238. validate(7, '"EOF')
  239. -- Multiline comments should be computed based on first line 'commentstring'
  240. set_lines(lines)
  241. toggle_lines(1, 3)
  242. local out_lines = get_lines()
  243. eq(out_lines[1], '"set background=dark')
  244. eq(out_lines[2], '"lua << EOF')
  245. eq(out_lines[3], '"print(1)')
  246. end)
  247. it('correctly computes indent', function()
  248. toggle_lines(2, 4)
  249. eq(get_lines(1, 4), { ' # aa', ' # aa', ' #' })
  250. end)
  251. it('correctly detects comment/uncomment', function()
  252. local validate = function(from, to, ref_lines)
  253. set_lines({ '', 'aa', '# aa', '# aa', 'aa', '' })
  254. toggle_lines(from, to)
  255. eq(get_lines(), ref_lines)
  256. end
  257. -- It should uncomment only if all non-blank lines are comments
  258. validate(3, 4, { '', 'aa', 'aa', 'aa', 'aa', '' })
  259. validate(2, 4, { '', '# aa', '# # aa', '# # aa', 'aa', '' })
  260. validate(3, 5, { '', 'aa', '# # aa', '# # aa', '# aa', '' })
  261. validate(1, 6, { '#', '# aa', '# # aa', '# # aa', '# aa', '#' })
  262. -- Blank lines should be ignored when making a decision
  263. set_lines({ '# aa', '', ' ', '\t', '# aa' })
  264. toggle_lines(1, 5)
  265. eq(get_lines(), { 'aa', '', ' ', '\t', 'aa' })
  266. end)
  267. it('correctly matches comment parts during checking and uncommenting', function()
  268. local validate = function(from, to, ref_lines)
  269. set_lines({ '/*aa*/', '/* aa */', '/* aa */' })
  270. toggle_lines(from, to)
  271. eq(get_lines(), ref_lines)
  272. end
  273. -- Should first try to match 'commentstring' parts exactly with their
  274. -- whitespace, with fallback on trimmed parts
  275. set_commentstring('/*%s*/')
  276. validate(1, 3, { 'aa', ' aa ', ' aa ' })
  277. validate(2, 3, { '/*aa*/', ' aa ', ' aa ' })
  278. validate(3, 3, { '/*aa*/', '/* aa */', ' aa ' })
  279. set_commentstring('/* %s */')
  280. validate(1, 3, { 'aa', 'aa', ' aa ' })
  281. validate(2, 3, { '/*aa*/', 'aa', ' aa ' })
  282. validate(3, 3, { '/*aa*/', '/* aa */', ' aa ' })
  283. set_commentstring('/* %s */')
  284. validate(1, 3, { 'aa', ' aa ', 'aa' })
  285. validate(2, 3, { '/*aa*/', ' aa ', 'aa' })
  286. validate(3, 3, { '/*aa*/', '/* aa */', 'aa' })
  287. set_commentstring(' /*%s*/ ')
  288. validate(1, 3, { 'aa', ' aa ', ' aa ' })
  289. validate(2, 3, { '/*aa*/', ' aa ', ' aa ' })
  290. validate(3, 3, { '/*aa*/', '/* aa */', ' aa ' })
  291. end)
  292. it('uncomments on inconsistent indent levels', function()
  293. set_lines({ '# aa', ' # aa', ' # aa' })
  294. toggle_lines(1, 3)
  295. eq(get_lines(), { 'aa', ' aa', ' aa' })
  296. end)
  297. it('respects tabs', function()
  298. api.nvim_set_option_value('expandtab', false, { buf = 0 })
  299. set_lines({ '\t\taa', '\t\taa' })
  300. toggle_lines(1, 2)
  301. eq(get_lines(), { '\t\t# aa', '\t\t# aa' })
  302. toggle_lines(1, 2)
  303. eq(get_lines(), { '\t\taa', '\t\taa' })
  304. end)
  305. it('works with trailing whitespace', function()
  306. -- Without right-hand side
  307. set_commentstring('# %s')
  308. set_lines({ ' aa', ' aa ', ' ' })
  309. toggle_lines(1, 3)
  310. eq(get_lines(), { ' # aa', ' # aa ', ' #' })
  311. toggle_lines(1, 3)
  312. eq(get_lines(), { ' aa', ' aa ', '' })
  313. -- With right-hand side
  314. set_commentstring('%s #')
  315. set_lines({ ' aa', ' aa ', ' ' })
  316. toggle_lines(1, 3)
  317. eq(get_lines(), { ' aa #', ' aa #', ' #' })
  318. toggle_lines(1, 3)
  319. eq(get_lines(), { ' aa', ' aa ', '' })
  320. -- Trailing whitespace after right side should be preserved for non-blanks
  321. set_commentstring('%s #')
  322. set_lines({ ' aa # ', ' aa #\t', ' # ', ' #\t' })
  323. toggle_lines(1, 4)
  324. eq(get_lines(), { ' aa ', ' aa\t', '', '' })
  325. end)
  326. end)
  327. describe('Operator', function()
  328. it('works in Normal mode', function()
  329. set_cursor(2, 2)
  330. feed('gc', 'ap')
  331. eq(get_lines(), { '# aa', '# aa', '# aa', '#', ' aa', ' aa', 'aa' })
  332. -- Cursor moves to start line
  333. eq(get_cursor(), { 1, 0 })
  334. -- Supports `v:count`
  335. set_lines(example_lines)
  336. set_cursor(2, 0)
  337. feed('2gc', 'ap')
  338. eq(get_lines(), { '# aa', '# aa', '# aa', '#', '# aa', '# aa', '# aa' })
  339. end)
  340. it('allows dot-repeat in Normal mode', function()
  341. local doubly_commented = { '# # aa', '# # aa', '# # aa', '# #', '# aa', '# aa', '# aa' }
  342. set_lines(example_lines)
  343. set_cursor(2, 2)
  344. feed('gc', 'ap')
  345. feed('.')
  346. eq(get_lines(), doubly_commented)
  347. -- Not immediate dot-repeat
  348. set_lines(example_lines)
  349. set_cursor(2, 2)
  350. feed('gc', 'ap')
  351. set_cursor(7, 0)
  352. feed('.')
  353. eq(get_lines(), doubly_commented)
  354. end)
  355. it('works in Visual mode', function()
  356. set_cursor(2, 2)
  357. feed('v', 'ap', 'gc')
  358. eq(get_lines(), { '# aa', '# aa', '# aa', '#', ' aa', ' aa', 'aa' })
  359. -- Cursor moves to start line
  360. eq(get_cursor(), { 1, 0 })
  361. end)
  362. it('allows dot-repeat after initial Visual mode', function()
  363. -- local example_lines = { 'aa', ' aa', ' aa', '', ' aa', ' aa', 'aa' }
  364. set_lines(example_lines)
  365. set_cursor(2, 2)
  366. feed('vip', 'gc')
  367. eq(get_lines(), { '# aa', '# aa', '# aa', '', ' aa', ' aa', 'aa' })
  368. eq(get_cursor(), { 1, 0 })
  369. -- Dot-repeat after first application in Visual mode should apply to the same
  370. -- relative region
  371. feed('.')
  372. eq(get_lines(), example_lines)
  373. set_cursor(3, 0)
  374. feed('.')
  375. eq(get_lines(), { 'aa', ' aa', ' # aa', ' #', ' # aa', ' aa', 'aa' })
  376. end)
  377. it("respects 'commentstring'", function()
  378. set_commentstring('/*%s*/')
  379. set_cursor(2, 2)
  380. feed('gc', 'ap')
  381. eq(get_lines(), { '/*aa*/', '/* aa*/', '/* aa*/', '/**/', ' aa', ' aa', 'aa' })
  382. end)
  383. it("works with empty 'commentstring'", function()
  384. set_commentstring('')
  385. set_cursor(2, 2)
  386. feed('gc', 'ap')
  387. eq(get_lines(), example_lines)
  388. eq(exec_capture('1messages'), [[Option 'commentstring' is empty.]])
  389. end)
  390. it('respects tree-sitter injections', function()
  391. setup_treesitter()
  392. local lines = {
  393. 'set background=dark',
  394. 'lua << EOF',
  395. 'print(1)',
  396. 'vim.api.nvim_exec2([[',
  397. ' set background=light',
  398. ']])',
  399. 'EOF',
  400. }
  401. -- Single line comments
  402. local validate = function(line, ref_output)
  403. set_lines(lines)
  404. set_cursor(line, 0)
  405. feed('gc_')
  406. eq(get_lines(line - 1, line)[1], ref_output)
  407. end
  408. validate(1, '"set background=dark')
  409. validate(2, '"lua << EOF')
  410. validate(3, '-- print(1)')
  411. validate(4, '-- vim.api.nvim_exec2([[')
  412. validate(5, ' "set background=light')
  413. validate(6, '-- ]])')
  414. validate(7, '"EOF')
  415. -- Has proper dot-repeat which recomputes 'commentstring'
  416. set_lines(lines)
  417. set_cursor(1, 0)
  418. feed('gc_')
  419. eq(get_lines()[1], '"set background=dark')
  420. set_cursor(3, 0)
  421. feed('.')
  422. eq(get_lines()[3], '-- print(1)')
  423. -- Multiline comments should be computed based on cursor position
  424. -- which in case of Visual selection means its left part
  425. set_lines(lines)
  426. set_cursor(1, 0)
  427. feed('v2j', 'gc')
  428. local out_lines = get_lines()
  429. eq(out_lines[1], '"set background=dark')
  430. eq(out_lines[2], '"lua << EOF')
  431. eq(out_lines[3], '"print(1)')
  432. end)
  433. it("recomputes local 'commentstring' based on cursor position", function()
  434. setup_treesitter()
  435. local lines = {
  436. ' print(1)',
  437. 'lua << EOF',
  438. ' print(1)',
  439. 'EOF',
  440. }
  441. set_lines(lines)
  442. set_cursor(1, 1)
  443. feed('gc_')
  444. eq(get_lines()[1], ' "print(1)')
  445. set_lines(lines)
  446. set_cursor(3, 2)
  447. feed('.')
  448. eq(get_lines()[3], ' -- print(1)')
  449. end)
  450. it('preserves marks', function()
  451. set_cursor(2, 0)
  452. -- Set '`<' and '`>' marks
  453. feed('VV')
  454. feed('gc', 'ip')
  455. eq(api.nvim_buf_get_mark(0, '<'), { 2, 0 })
  456. eq(api.nvim_buf_get_mark(0, '>'), { 2, 2147483647 })
  457. end)
  458. end)
  459. describe('Current line', function()
  460. it('works', function()
  461. set_lines(example_lines)
  462. set_cursor(1, 1)
  463. feed('gcc')
  464. eq(get_lines(0, 2), { '# aa', ' aa' })
  465. -- Does not comment empty line
  466. set_lines(example_lines)
  467. set_cursor(4, 0)
  468. feed('gcc')
  469. eq(get_lines(2, 5), { ' aa', '', ' aa' })
  470. -- Supports `v:count`
  471. set_lines(example_lines)
  472. set_cursor(2, 0)
  473. feed('2gcc')
  474. eq(get_lines(0, 3), { 'aa', ' # aa', ' # aa' })
  475. end)
  476. it('allows dot-repeat', function()
  477. set_lines(example_lines)
  478. set_cursor(1, 1)
  479. feed('gcc')
  480. feed('.')
  481. eq(get_lines(), example_lines)
  482. -- Not immediate dot-repeat
  483. set_lines(example_lines)
  484. set_cursor(1, 1)
  485. feed('gcc')
  486. set_cursor(7, 0)
  487. feed('.')
  488. eq(get_lines(6, 7), { '# aa' })
  489. end)
  490. it('respects tree-sitter injections', function()
  491. setup_treesitter()
  492. local lines = {
  493. 'set background=dark',
  494. 'lua << EOF',
  495. 'print(1)',
  496. 'EOF',
  497. }
  498. set_lines(lines)
  499. set_cursor(1, 0)
  500. feed('gcc')
  501. eq(get_lines(), { '"set background=dark', 'lua << EOF', 'print(1)', 'EOF' })
  502. -- Should work with dot-repeat
  503. set_cursor(3, 0)
  504. feed('.')
  505. eq(get_lines(), { '"set background=dark', 'lua << EOF', '-- print(1)', 'EOF' })
  506. end)
  507. end)
  508. describe('Textobject', function()
  509. it('works', function()
  510. set_lines({ 'aa', '# aa', '# aa', 'aa' })
  511. set_cursor(2, 0)
  512. feed('d', 'gc')
  513. eq(get_lines(), { 'aa', 'aa' })
  514. end)
  515. it('allows dot-repeat', function()
  516. set_lines({ 'aa', '# aa', '# aa', 'aa', '# aa' })
  517. set_cursor(2, 0)
  518. feed('d', 'gc')
  519. set_cursor(3, 0)
  520. feed('.')
  521. eq(get_lines(), { 'aa', 'aa' })
  522. end)
  523. it('does nothing when not inside textobject', function()
  524. -- Builtin operators
  525. feed('d', 'gc')
  526. eq(get_lines(), example_lines)
  527. -- Comment operator
  528. local validate_no_action = function(line, col)
  529. set_lines(example_lines)
  530. set_cursor(line, col)
  531. feed('gc', 'gc')
  532. eq(get_lines(), example_lines)
  533. end
  534. validate_no_action(1, 1)
  535. validate_no_action(2, 2)
  536. -- Doesn't work (but should) because both `[` and `]` are set to (1, 0)
  537. -- (instead of more reasonable (1, -1) or (0, 2147483647)).
  538. -- validate_no_action(1, 0)
  539. end)
  540. it('respects tree-sitter injections', function()
  541. setup_treesitter()
  542. local lines = {
  543. '"set background=dark',
  544. '"set termguicolors',
  545. 'lua << EOF',
  546. '-- print(1)',
  547. '-- print(2)',
  548. 'EOF',
  549. }
  550. set_lines(lines)
  551. set_cursor(1, 0)
  552. feed('dgc')
  553. eq(get_lines(), { 'lua << EOF', '-- print(1)', '-- print(2)', 'EOF' })
  554. -- Should work with dot-repeat
  555. set_cursor(2, 0)
  556. feed('.')
  557. eq(get_lines(), { 'lua << EOF', 'EOF' })
  558. end)
  559. end)
  560. end)