parser_spec.lua 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437
  1. local t = require('test.testutil')
  2. local n = require('test.functional.testnvim')()
  3. local ts_t = require('test.functional.treesitter.testutil')
  4. local clear = n.clear
  5. local dedent = t.dedent
  6. local eq = t.eq
  7. local insert = n.insert
  8. local exec_lua = n.exec_lua
  9. local pcall_err = t.pcall_err
  10. local feed = n.feed
  11. local run_query = ts_t.run_query
  12. local assert_alive = n.assert_alive
  13. describe('treesitter parser API', function()
  14. before_each(function()
  15. clear()
  16. exec_lua(function()
  17. vim.g.__ts_debug = 1
  18. end)
  19. end)
  20. it('parses buffer', function()
  21. insert([[
  22. int main() {
  23. int x = 3;
  24. }]])
  25. exec_lua(function()
  26. _G.parser = vim.treesitter.get_parser(0, 'c')
  27. _G.tree = _G.parser:parse()[1]
  28. _G.root = _G.tree:root()
  29. _G.lang = vim.treesitter.language.inspect('c')
  30. end)
  31. eq('<tree>', exec_lua('return tostring(tree)'))
  32. eq('<node translation_unit>', exec_lua('return tostring(root)'))
  33. eq({ 0, 0, 3, 0 }, exec_lua('return {root:range()}'))
  34. eq(1, exec_lua('return root:child_count()'))
  35. exec_lua('child = root:child(0)')
  36. eq('<node function_definition>', exec_lua('return tostring(child)'))
  37. eq({ 0, 0, 2, 1 }, exec_lua('return {child:range()}'))
  38. eq('function_definition', exec_lua('return child:type()'))
  39. eq(true, exec_lua('return child:named()'))
  40. eq('number', type(exec_lua('return child:symbol()')))
  41. eq(true, exec_lua('return lang.symbols[child:type()]'))
  42. exec_lua('anon = root:descendant_for_range(0,8,0,9)')
  43. eq('(', exec_lua('return anon:type()'))
  44. eq(false, exec_lua('return anon:named()'))
  45. eq('number', type(exec_lua('return anon:symbol()')))
  46. eq(false, exec_lua([=[return lang.symbols[string.format('"%s"', anon:type())]]=]))
  47. exec_lua('descendant = root:descendant_for_range(1,2,1,12)')
  48. eq('<node declaration>', exec_lua('return tostring(descendant)'))
  49. eq({ 1, 2, 1, 12 }, exec_lua('return {descendant:range()}'))
  50. eq(
  51. '(declaration type: (primitive_type) declarator: (init_declarator declarator: (identifier) value: (number_literal)))',
  52. exec_lua('return descendant:sexpr()')
  53. )
  54. feed('2G7|ay')
  55. exec_lua(function()
  56. _G.tree2 = _G.parser:parse()[1]
  57. _G.root2 = _G.tree2:root()
  58. _G.descendant2 = _G.root2:descendant_for_range(1, 2, 1, 13)
  59. end)
  60. eq(false, exec_lua('return tree2 == tree1'))
  61. eq(false, exec_lua('return root2 == root'))
  62. eq('<node declaration>', exec_lua('return tostring(descendant2)'))
  63. eq({ 1, 2, 1, 13 }, exec_lua('return {descendant2:range()}'))
  64. eq(true, exec_lua('return child == child'))
  65. -- separate lua object, but represents same node
  66. eq(true, exec_lua('return child == root:child(0)'))
  67. eq(false, exec_lua('return child == descendant2'))
  68. eq(false, exec_lua('return child == nil'))
  69. eq(false, exec_lua('return child == tree'))
  70. eq('string', exec_lua('return type(child:id())'))
  71. eq(true, exec_lua('return child:id() == child:id()'))
  72. -- separate lua object, but represents same node
  73. eq(true, exec_lua('return child:id() == root:child(0):id()'))
  74. eq(false, exec_lua('return child:id() == descendant2:id()'))
  75. eq(false, exec_lua('return child:id() == nil'))
  76. eq(false, exec_lua('return child:id() == tree'))
  77. -- unchanged buffer: return the same tree
  78. eq(true, exec_lua('return parser:parse()[1] == tree2'))
  79. end)
  80. it('parses buffer asynchronously', function()
  81. insert([[
  82. int main() {
  83. int x = 3;
  84. }]])
  85. exec_lua(function()
  86. _G.parser = vim.treesitter.get_parser(0, 'c')
  87. _G.lang = vim.treesitter.language.inspect('c')
  88. _G.parser:parse(nil, function(_, trees)
  89. _G.tree = trees[1]
  90. _G.root = _G.tree:root()
  91. end)
  92. vim.wait(100, function() end)
  93. end)
  94. eq('<tree>', exec_lua('return tostring(tree)'))
  95. eq('<node translation_unit>', exec_lua('return tostring(root)'))
  96. eq({ 0, 0, 3, 0 }, exec_lua('return {root:range()}'))
  97. eq(1, exec_lua('return root:child_count()'))
  98. exec_lua('child = root:child(0)')
  99. eq('<node function_definition>', exec_lua('return tostring(child)'))
  100. eq({ 0, 0, 2, 1 }, exec_lua('return {child:range()}'))
  101. eq('function_definition', exec_lua('return child:type()'))
  102. eq(true, exec_lua('return child:named()'))
  103. eq('number', type(exec_lua('return child:symbol()')))
  104. eq(true, exec_lua('return lang.symbols[child:type()]'))
  105. exec_lua('anon = root:descendant_for_range(0,8,0,9)')
  106. eq('(', exec_lua('return anon:type()'))
  107. eq(false, exec_lua('return anon:named()'))
  108. eq('number', type(exec_lua('return anon:symbol()')))
  109. eq(false, exec_lua([=[return lang.symbols[string.format('"%s"', anon:type())]]=]))
  110. exec_lua('descendant = root:descendant_for_range(1,2,1,12)')
  111. eq('<node declaration>', exec_lua('return tostring(descendant)'))
  112. eq({ 1, 2, 1, 12 }, exec_lua('return {descendant:range()}'))
  113. eq(
  114. '(declaration type: (primitive_type) declarator: (init_declarator declarator: (identifier) value: (number_literal)))',
  115. exec_lua('return descendant:sexpr()')
  116. )
  117. feed('2G7|ay')
  118. exec_lua(function()
  119. _G.parser:parse(nil, function(_, trees)
  120. _G.tree2 = trees[1]
  121. _G.root2 = _G.tree2:root()
  122. _G.descendant2 = _G.root2:descendant_for_range(1, 2, 1, 13)
  123. end)
  124. vim.wait(100, function() end)
  125. end)
  126. eq(false, exec_lua('return tree2 == tree1'))
  127. eq(false, exec_lua('return root2 == root'))
  128. eq('<node declaration>', exec_lua('return tostring(descendant2)'))
  129. eq({ 1, 2, 1, 13 }, exec_lua('return {descendant2:range()}'))
  130. eq(true, exec_lua('return child == child'))
  131. -- separate lua object, but represents same node
  132. eq(true, exec_lua('return child == root:child(0)'))
  133. eq(false, exec_lua('return child == descendant2'))
  134. eq(false, exec_lua('return child == nil'))
  135. eq(false, exec_lua('return child == tree'))
  136. eq('string', exec_lua('return type(child:id())'))
  137. eq(true, exec_lua('return child:id() == child:id()'))
  138. -- separate lua object, but represents same node
  139. eq(true, exec_lua('return child:id() == root:child(0):id()'))
  140. eq(false, exec_lua('return child:id() == descendant2:id()'))
  141. eq(false, exec_lua('return child:id() == nil'))
  142. eq(false, exec_lua('return child:id() == tree'))
  143. -- unchanged buffer: return the same tree
  144. eq(true, exec_lua('return parser:parse()[1] == tree2'))
  145. end)
  146. it('does not crash when editing large files', function()
  147. insert([[printf("%s", "some text");]])
  148. feed('yy49999p')
  149. exec_lua(function()
  150. _G.parser = vim.treesitter.get_parser(0, 'c')
  151. _G.done = false
  152. vim.treesitter.start(0, 'c')
  153. _G.parser:parse(nil, function()
  154. _G.done = true
  155. end)
  156. while not _G.done do
  157. -- Busy wait until async parsing has completed
  158. vim.wait(100, function() end)
  159. end
  160. end)
  161. eq(true, exec_lua([[return done]]))
  162. exec_lua(function()
  163. vim.api.nvim_input('Lxj')
  164. end)
  165. exec_lua(function()
  166. vim.api.nvim_input('xj')
  167. end)
  168. exec_lua(function()
  169. vim.api.nvim_input('xj')
  170. end)
  171. assert_alive()
  172. end)
  173. it('resets parsing state on tree changes', function()
  174. insert([[vim.api.nvim_set_hl(0, 'test2', { bg = 'green' })]])
  175. feed('yy1000p')
  176. exec_lua(function()
  177. vim.cmd('set ft=lua')
  178. vim.treesitter.start(0)
  179. local parser = assert(vim.treesitter.get_parser(0))
  180. parser:parse(true, function() end)
  181. vim.api.nvim_buf_set_lines(0, 1, -1, false, {})
  182. parser:parse(true)
  183. end)
  184. end)
  185. it('resets when buffer was editing during an async parse', function()
  186. insert([[printf("%s", "some text");]])
  187. feed('yy49999p')
  188. feed('gg4jO// Comment<Esc>')
  189. exec_lua(function()
  190. _G.parser = vim.treesitter.get_parser(0, 'c')
  191. _G.done = false
  192. vim.treesitter.start(0, 'c')
  193. _G.parser:parse(nil, function()
  194. _G.done = true
  195. end)
  196. end)
  197. exec_lua(function()
  198. vim.api.nvim_input('ggdj')
  199. end)
  200. eq(false, exec_lua([[return done]]))
  201. exec_lua(function()
  202. while not _G.done do
  203. -- Busy wait until async parsing finishes
  204. vim.wait(100, function() end)
  205. end
  206. end)
  207. eq(true, exec_lua([[return done]]))
  208. eq('comment', exec_lua([[return parser:parse()[1]:root():named_child(2):type()]]))
  209. eq({ 2, 0, 2, 10 }, exec_lua([[return {parser:parse()[1]:root():named_child(2):range()}]]))
  210. end)
  211. it('handles multiple async parse calls', function()
  212. insert([[printf("%s", "some text");]])
  213. feed('yy49999p')
  214. exec_lua(function()
  215. -- Spy on vim.schedule
  216. local schedule = vim.schedule
  217. vim.schedule = function(fn)
  218. _G.schedules = _G.schedules + 1
  219. schedule(fn)
  220. end
  221. _G.schedules = 0
  222. _G.parser = vim.treesitter.get_parser(0, 'c')
  223. for i = 1, 5 do
  224. _G['done' .. i] = false
  225. _G.parser:parse(nil, function()
  226. _G['done' .. i] = true
  227. end)
  228. end
  229. schedule(function()
  230. _G.schedules_snapshot = _G.schedules
  231. end)
  232. end)
  233. eq(2, exec_lua([[return schedules_snapshot]]))
  234. eq(
  235. { false, false, false, false, false },
  236. exec_lua([[return { done1, done2, done3, done4, done5 }]])
  237. )
  238. exec_lua(function()
  239. while not _G.done1 do
  240. -- Busy wait until async parsing finishes
  241. vim.wait(100, function() end)
  242. end
  243. end)
  244. eq({ true, true, true, true, true }, exec_lua([[return { done1, done2, done3, done4, done5 }]]))
  245. end)
  246. local test_text = [[
  247. void ui_refresh(void)
  248. {
  249. int width = INT_MAX, height = INT_MAX;
  250. bool ext_widgets[kUIExtCount];
  251. for (UIExtension i = 0; (int)i < kUIExtCount; i++) {
  252. ext_widgets[i] = true;
  253. }
  254. bool inclusive = ui_override();
  255. for (size_t i = 0; i < ui_count; i++) {
  256. UI *ui = uis[i];
  257. width = MIN(ui->width, width);
  258. height = MIN(ui->height, height);
  259. foo = BAR(ui->bazaar, bazaar);
  260. for (UIExtension j = 0; (int)j < kUIExtCount; j++) {
  261. ext_widgets[j] &= (ui->ui_ext[j] || inclusive);
  262. }
  263. }
  264. }]]
  265. it('allows to iterate over nodes children', function()
  266. insert(test_text)
  267. local res = exec_lua(function()
  268. local parser = vim.treesitter.get_parser(0, 'c')
  269. local func_node = parser:parse()[1]:root():child(0)
  270. local res = {}
  271. for node, field in func_node:iter_children() do
  272. table.insert(res, { node:type(), field })
  273. end
  274. return res
  275. end)
  276. eq({
  277. { 'primitive_type', 'type' },
  278. { 'function_declarator', 'declarator' },
  279. { 'compound_statement', 'body' },
  280. }, res)
  281. end)
  282. it('does not get parser for empty filetype', function()
  283. insert(test_text)
  284. eq(
  285. '.../treesitter.lua:0: Parser not found for buffer 1: language could not be determined',
  286. pcall_err(exec_lua, 'vim.treesitter.get_parser(0)')
  287. )
  288. -- Must provide language for buffers with an empty filetype
  289. exec_lua("vim.treesitter.get_parser(0, 'c')")
  290. end)
  291. it('allows to get a child by field', function()
  292. insert(test_text)
  293. local res = exec_lua(function()
  294. local parser = vim.treesitter.get_parser(0, 'c')
  295. _G.func_node = parser:parse()[1]:root():child(0)
  296. local res = {}
  297. for _, node in ipairs(_G.func_node:field('type')) do
  298. table.insert(res, { node:type(), node:range() })
  299. end
  300. return res
  301. end)
  302. eq({ { 'primitive_type', 0, 0, 0, 4 } }, res)
  303. local res_fail = exec_lua(function()
  304. vim.treesitter.get_parser(0, 'c')
  305. return #_G.func_node:field('foo') == 0
  306. end)
  307. assert(res_fail)
  308. end)
  309. it('supports getting text of multiline node', function()
  310. insert(test_text)
  311. local res = exec_lua(function()
  312. local parser = vim.treesitter.get_parser(0, 'c')
  313. local tree = parser:parse()[1]
  314. return vim.treesitter.get_node_text(tree:root(), 0)
  315. end)
  316. eq(test_text, res)
  317. local res2 = exec_lua(function()
  318. local parser = vim.treesitter.get_parser(0, 'c')
  319. local root = parser:parse()[1]:root()
  320. return vim.treesitter.get_node_text(root:child(0):child(0), 0)
  321. end)
  322. eq('void', res2)
  323. end)
  324. it('supports getting text where start of node is one past EOF', function()
  325. local text = [[
  326. def run
  327. a = <<~E
  328. end]]
  329. insert(text)
  330. eq(
  331. '',
  332. exec_lua(function()
  333. local fake_node = {}
  334. function fake_node:start()
  335. return 3, 0, 23
  336. end
  337. function fake_node:end_()
  338. return 3, 0, 23
  339. end
  340. function fake_node:range(bytes)
  341. if bytes then
  342. return 3, 0, 23, 3, 0, 23
  343. end
  344. return 3, 0, 3, 0
  345. end
  346. return vim.treesitter.get_node_text(fake_node, 0)
  347. end)
  348. )
  349. end)
  350. it('supports getting empty text if node range is zero width', function()
  351. local text = [[
  352. ```lua
  353. {}
  354. ```]]
  355. insert(text)
  356. local result = exec_lua(function()
  357. local fake_node = {}
  358. function fake_node:start()
  359. return 1, 0, 7
  360. end
  361. function fake_node:end_()
  362. return 1, 0, 7
  363. end
  364. function fake_node:range()
  365. return 1, 0, 1, 0
  366. end
  367. return vim.treesitter.get_node_text(fake_node, 0) == ''
  368. end)
  369. eq(true, result)
  370. end)
  371. it('allows to set simple ranges', function()
  372. insert(test_text)
  373. local res = exec_lua(function()
  374. _G.parser = vim.treesitter.get_parser(0, 'c')
  375. return { _G.parser:parse()[1]:root():range() }
  376. end)
  377. eq({ 0, 0, 19, 0 }, res)
  378. -- The following sets the included ranges for the current parser
  379. -- As stated here, this only includes the function (thus the whole buffer, without the last line)
  380. local res2 = exec_lua(function()
  381. local root = _G.parser:parse()[1]:root()
  382. _G.parser:set_included_regions({ { root:child(0) } })
  383. _G.parser:invalidate()
  384. return { _G.parser:parse(true)[1]:root():range() }
  385. end)
  386. eq({ 0, 0, 18, 1 }, res2)
  387. eq({ { { 0, 0, 0, 18, 1, 512 } } }, exec_lua [[ return parser:included_regions() ]])
  388. local range_tbl = exec_lua(function()
  389. _G.parser:set_included_regions { { { 0, 0, 17, 1 } } }
  390. _G.parser:parse()
  391. return _G.parser:included_regions()
  392. end)
  393. eq({ { { 0, 0, 0, 17, 1, 508 } } }, range_tbl)
  394. end)
  395. it('allows to set complex ranges', function()
  396. insert(test_text)
  397. local res = exec_lua(function()
  398. local parser = vim.treesitter.get_parser(0, 'c')
  399. local query = vim.treesitter.query.parse('c', '(declaration) @decl')
  400. local nodes = {}
  401. for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do
  402. table.insert(nodes, node)
  403. end
  404. parser:set_included_regions({ nodes })
  405. local root = parser:parse(true)[1]:root()
  406. local res = {}
  407. for i = 0, (root:named_child_count() - 1) do
  408. table.insert(res, { root:named_child(i):range() })
  409. end
  410. return res
  411. end)
  412. eq({
  413. { 2, 2, 2, 40 },
  414. { 3, 2, 3, 32 },
  415. { 4, 7, 4, 25 },
  416. { 8, 2, 8, 33 },
  417. { 9, 7, 9, 20 },
  418. { 10, 4, 10, 20 },
  419. { 14, 9, 14, 27 },
  420. }, res)
  421. end)
  422. it('allows to create string parsers', function()
  423. local ret = exec_lua(function()
  424. local parser = vim.treesitter.get_string_parser('int foo = 42;', 'c')
  425. return { parser:parse()[1]:root():range() }
  426. end)
  427. eq({ 0, 0, 0, 13 }, ret)
  428. end)
  429. it('can run async parses with string parsers', function()
  430. local ret = exec_lua(function()
  431. local parser = vim.treesitter.get_string_parser('int foo = 42;', 'c')
  432. return { parser:parse(nil, function() end)[1]:root():range() }
  433. end)
  434. eq({ 0, 0, 0, 13 }, ret)
  435. end)
  436. it('allows to run queries with string parsers', function()
  437. local txt = [[
  438. int foo = 42;
  439. int bar = 13;
  440. ]]
  441. local ret = exec_lua(function(str)
  442. local parser = vim.treesitter.get_string_parser(str, 'c')
  443. local nodes = {}
  444. local query = vim.treesitter.query.parse('c', '((identifier) @id (#eq? @id "foo"))')
  445. for _, node in query:iter_captures(parser:parse()[1]:root(), str) do
  446. table.insert(nodes, { node:range() })
  447. end
  448. return nodes
  449. end, txt)
  450. eq({ { 0, 10, 0, 13 } }, ret)
  451. end)
  452. describe('when creating a language tree', function()
  453. local function get_ranges()
  454. return exec_lua(function()
  455. local result = {}
  456. _G.parser:for_each_tree(function(tree)
  457. table.insert(result, { tree:root():range() })
  458. end)
  459. return result
  460. end)
  461. end
  462. before_each(function()
  463. insert([[
  464. int x = INT_MAX;
  465. #define READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
  466. #define READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
  467. #define VALUE 123
  468. #define VALUE1 123
  469. #define VALUE2 123
  470. ]])
  471. end)
  472. describe('when parsing regions independently', function()
  473. it('should inject a language', function()
  474. exec_lua(function()
  475. _G.parser = vim.treesitter.get_parser(0, 'c', {
  476. injections = {
  477. c = (
  478. '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c")) '
  479. .. '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c"))'
  480. ),
  481. },
  482. })
  483. _G.parser:parse(true)
  484. end)
  485. eq('table', exec_lua('return type(parser:children().c)'))
  486. eq(5, exec_lua('return #parser:children().c:trees()'))
  487. eq({
  488. { 0, 0, 7, 0 }, -- root tree
  489. { 1, 26, 1, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
  490. { 2, 29, 2, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
  491. { 3, 14, 3, 17 }, -- VALUE 123
  492. { 4, 15, 4, 18 }, -- VALUE1 123
  493. { 5, 15, 5, 18 }, -- VALUE2 123
  494. }, get_ranges())
  495. n.feed('ggo<esc>')
  496. eq(5, exec_lua('return #parser:children().c:trees()'))
  497. eq({
  498. { 0, 0, 8, 0 }, -- root tree
  499. { 2, 26, 2, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
  500. { 3, 29, 3, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
  501. { 4, 14, 4, 17 }, -- VALUE 123
  502. { 5, 15, 5, 18 }, -- VALUE1 123
  503. { 6, 15, 6, 18 }, -- VALUE2 123
  504. }, get_ranges())
  505. end)
  506. end)
  507. describe('when parsing regions combined', function()
  508. it('should inject a language', function()
  509. exec_lua(function()
  510. _G.parser = vim.treesitter.get_parser(0, 'c', {
  511. injections = {
  512. c = (
  513. '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c") (#set! injection.combined)) '
  514. .. '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c") (#set! injection.combined))'
  515. ),
  516. },
  517. })
  518. _G.parser:parse(true)
  519. end)
  520. eq('table', exec_lua('return type(parser:children().c)'))
  521. eq(2, exec_lua('return #parser:children().c:trees()'))
  522. eq({
  523. { 0, 0, 7, 0 }, -- root tree
  524. { 1, 26, 2, 66 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
  525. -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
  526. { 3, 14, 5, 18 }, -- VALUE 123
  527. -- VALUE1 123
  528. -- VALUE2 123
  529. }, get_ranges())
  530. n.feed('ggo<esc>')
  531. eq('table', exec_lua('return type(parser:children().c)'))
  532. eq(2, exec_lua('return #parser:children().c:trees()'))
  533. eq({
  534. { 0, 0, 8, 0 }, -- root tree
  535. { 2, 26, 3, 66 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
  536. -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
  537. -- VALUE 123
  538. { 4, 14, 6, 18 }, -- VALUE1 123
  539. -- VALUE2 123
  540. }, get_ranges())
  541. n.feed('7ggI//<esc>')
  542. exec_lua([[parser:parse(true)]])
  543. eq('table', exec_lua('return type(parser:children().c)'))
  544. eq(2, exec_lua('return #parser:children().c:trees()'))
  545. eq({
  546. { 0, 0, 8, 0 }, -- root tree
  547. { 2, 26, 3, 66 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
  548. -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
  549. -- VALUE 123
  550. { 4, 14, 5, 18 }, -- VALUE1 123
  551. }, get_ranges())
  552. end)
  553. it('scopes injections appropriately', function()
  554. -- `injection.combined` are combined within a TSTree.
  555. -- Lua injections on lines 2-4 should be combined within their
  556. -- respective C injection trees, and lua injections on lines 0 and 6
  557. -- are separate from each other and other lua injections on lines 2-4.
  558. exec_lua(function()
  559. local lines = {
  560. [[func('int a = func("local a = [=[");')]],
  561. [[]],
  562. [[func('int a = func("local a = 6") + func("+ 3");')]],
  563. [[func('int a = func("local a = 6") + func("+ 3");')]],
  564. [[func('int a = func("local a = 6") + func("+ 3");')]],
  565. [[]],
  566. [[func('int a = func("]=]");')]],
  567. }
  568. vim.api.nvim_buf_set_lines(0, 0, -1, true, lines)
  569. _G.parser = vim.treesitter.get_parser(0, 'lua', {
  570. injections = {
  571. lua = [[
  572. ((function_call
  573. arguments: (arguments
  574. (string (string_content) @injection.content)))
  575. (#set! injection.language "c"))
  576. ]],
  577. c = [[
  578. ((call_expression
  579. arguments: (argument_list
  580. (string_literal (string_content) @injection.content)))
  581. (#set! injection.combined)
  582. (#set! injection.language "lua"))
  583. ]],
  584. },
  585. })
  586. function _G.langtree_regions(parser)
  587. local result_regions = {}
  588. local regions = parser:included_regions()
  589. for region_i, region in pairs(regions) do
  590. local result_region = {}
  591. for _, range in ipairs(region) do
  592. table.insert(result_region, {
  593. range[1],
  594. range[2],
  595. range[4],
  596. range[5],
  597. })
  598. end
  599. result_regions[region_i] = result_region
  600. end
  601. return result_regions
  602. end
  603. function _G.all_regions(parser)
  604. local this_regions = _G.langtree_regions(parser)
  605. local child_regions = {}
  606. for lang, child in pairs(parser:children()) do
  607. child_regions[lang] = _G.all_regions(child)
  608. end
  609. return { regions = this_regions, children = child_regions }
  610. end
  611. end)
  612. local expected_regions = {
  613. children = {}, -- nothing is parsed
  614. regions = {
  615. {}, -- root tree's regions is the entire buffer
  616. },
  617. }
  618. eq(expected_regions, exec_lua('return all_regions(_G.parser)'))
  619. exec_lua('_G.parser:parse({ 3, 0, 3, 45 })')
  620. expected_regions = {
  621. children = {
  622. c = {
  623. children = {
  624. lua = {
  625. children = {},
  626. regions = {
  627. { { 3, 20, 3, 31 }, { 3, 42, 3, 45 } },
  628. },
  629. },
  630. },
  631. regions = {
  632. { { 3, 6, 3, 48 } },
  633. },
  634. },
  635. },
  636. regions = {
  637. {},
  638. },
  639. }
  640. eq(expected_regions, exec_lua('return all_regions(_G.parser)'))
  641. exec_lua('_G.parser:parse(true)')
  642. expected_regions = {
  643. children = {
  644. c = {
  645. children = {
  646. lua = {
  647. children = {},
  648. regions = {
  649. { { 0, 20, 0, 33 } },
  650. { { 2, 20, 2, 31 }, { 2, 42, 2, 45 } },
  651. { { 3, 20, 3, 31 }, { 3, 42, 3, 45 } },
  652. { { 4, 20, 4, 31 }, { 4, 42, 4, 45 } },
  653. { { 6, 20, 6, 23 } },
  654. },
  655. },
  656. },
  657. regions = {
  658. { { 0, 6, 0, 36 } },
  659. { { 2, 6, 2, 48 } },
  660. { { 3, 6, 3, 48 } },
  661. { { 4, 6, 4, 48 } },
  662. { { 6, 6, 6, 26 } },
  663. },
  664. },
  665. },
  666. regions = {
  667. {},
  668. },
  669. }
  670. eq(expected_regions, exec_lua('return all_regions(_G.parser)'))
  671. end)
  672. end)
  673. describe('when using injection.self', function()
  674. it('should inject the source language', function()
  675. exec_lua(function()
  676. _G.parser = vim.treesitter.get_parser(0, 'c', {
  677. injections = {
  678. c = (
  679. '(preproc_def (preproc_arg) @injection.content (#set! injection.self)) '
  680. .. '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.self))'
  681. ),
  682. },
  683. })
  684. _G.parser:parse(true)
  685. end)
  686. eq('table', exec_lua('return type(parser:children().c)'))
  687. eq(5, exec_lua('return #parser:children().c:trees()'))
  688. eq({
  689. { 0, 0, 7, 0 }, -- root tree
  690. { 1, 26, 1, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
  691. { 2, 29, 2, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
  692. { 3, 14, 3, 17 }, -- VALUE 123
  693. { 4, 15, 4, 18 }, -- VALUE1 123
  694. { 5, 15, 5, 18 }, -- VALUE2 123
  695. }, get_ranges())
  696. n.feed('ggo<esc>')
  697. eq(5, exec_lua('return #parser:children().c:trees()'))
  698. eq({
  699. { 0, 0, 8, 0 }, -- root tree
  700. { 2, 26, 2, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
  701. { 3, 29, 3, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
  702. { 4, 14, 4, 17 }, -- VALUE 123
  703. { 5, 15, 5, 18 }, -- VALUE1 123
  704. { 6, 15, 6, 18 }, -- VALUE2 123
  705. }, get_ranges())
  706. end)
  707. end)
  708. describe('when using the offset directive', function()
  709. it('should shift the range by the directive amount', function()
  710. exec_lua(function()
  711. _G.parser = vim.treesitter.get_parser(0, 'c', {
  712. injections = {
  713. c = (
  714. '(preproc_def ((preproc_arg) @injection.content (#set! injection.language "c") (#offset! @injection.content 0 2 0 -1))) '
  715. .. '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c"))'
  716. ),
  717. },
  718. })
  719. _G.parser:parse(true)
  720. end)
  721. eq('table', exec_lua('return type(parser:children().c)'))
  722. eq({
  723. { 0, 0, 7, 0 }, -- root tree
  724. { 1, 26, 1, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
  725. { 2, 29, 2, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
  726. { 3, 16, 3, 16 }, -- VALUE 123
  727. { 4, 17, 4, 17 }, -- VALUE1 123
  728. { 5, 17, 5, 17 }, -- VALUE2 123
  729. }, get_ranges())
  730. end)
  731. it('should list all directives', function()
  732. local res_list = exec_lua(function()
  733. local query = vim.treesitter.query
  734. local list = query.list_directives()
  735. table.sort(list)
  736. return list
  737. end)
  738. eq({ 'gsub!', 'offset!', 'set!', 'trim!' }, res_list)
  739. end)
  740. end)
  741. end)
  742. it('properly clips nested injections #34098', function()
  743. insert([=[
  744. ```lua
  745. vim.cmd([[
  746. set noswapfile
  747. set noswapfile
  748. set noswapfile
  749. ]])
  750. ```
  751. ]=])
  752. local result = exec_lua(function()
  753. local parser = vim.treesitter.get_parser(0, 'markdown')
  754. parser:parse(true)
  755. return parser._children.lua._children.vim:included_regions()
  756. end)
  757. local expected = {
  758. {
  759. { 1, 10, 17, 2, 0, 18 },
  760. { 2, 0, 18, 3, 0, 33 },
  761. { 3, 0, 33, 4, 0, 48 },
  762. { 4, 0, 48, 5, 0, 63 },
  763. },
  764. }
  765. eq(expected, result)
  766. end)
  767. describe('when getting the language for a range', function()
  768. before_each(function()
  769. insert([[
  770. int x = INT_MAX;
  771. #define VALUE 123456789
  772. ]])
  773. end)
  774. it('should return the correct language tree', function()
  775. local result = exec_lua(function()
  776. local parser = vim.treesitter.get_parser(0, 'c', {
  777. injections = {
  778. c = '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c"))',
  779. },
  780. })
  781. parser:parse(true)
  782. local sub_tree = parser:language_for_range({ 1, 18, 1, 19 })
  783. return sub_tree == parser:children().c
  784. end)
  785. eq(true, result)
  786. end)
  787. end)
  788. describe('when setting the node for an injection', function()
  789. before_each(function()
  790. insert([[
  791. print()
  792. ]])
  793. end)
  794. it('ignores optional captures #23100', function()
  795. local result = exec_lua(function()
  796. local parser = vim.treesitter.get_parser(0, 'lua', {
  797. injections = {
  798. lua = (
  799. '(function_call '
  800. .. '(arguments '
  801. .. '(string)? @injection.content '
  802. .. '(number)? @injection.content '
  803. .. '(#offset! @injection.content 0 1 0 -1) '
  804. .. '(#set! injection.language "c")))'
  805. ),
  806. },
  807. })
  808. parser:parse(true)
  809. return parser:is_valid()
  810. end)
  811. eq(true, result)
  812. end)
  813. end)
  814. describe('when getting/setting match data', function()
  815. describe('when setting for the whole match', function()
  816. it('should set/get the data correctly', function()
  817. insert([[
  818. int x = 3;
  819. ]])
  820. local result = exec_lua(function()
  821. local query =
  822. vim.treesitter.query.parse('c', '((number_literal) @number (#set! "key" "value"))')
  823. local parser = vim.treesitter.get_parser(0, 'c')
  824. local _, _, metadata = query:iter_matches(parser:parse()[1]:root(), 0, 0, -1)()
  825. return metadata.key
  826. end)
  827. eq('value', result)
  828. end)
  829. describe('when setting a key on a capture', function()
  830. it('it should create the nested table', function()
  831. insert([[
  832. int x = 3;
  833. ]])
  834. local result = exec_lua(function()
  835. local query = vim.treesitter.query.parse(
  836. 'c',
  837. '((number_literal) @number (#set! @number "key" "value"))'
  838. )
  839. local parser = vim.treesitter.get_parser(0, 'c')
  840. local _, _, metadata = query:iter_matches(parser:parse()[1]:root(), 0, 0, -1)()
  841. local _, nested_tbl = next(metadata)
  842. return nested_tbl.key
  843. end)
  844. eq('value', result)
  845. end)
  846. it('it should not overwrite the nested table', function()
  847. insert([[
  848. int x = 3;
  849. ]])
  850. local result = exec_lua(function()
  851. local query = vim.treesitter.query.parse(
  852. 'c',
  853. '((number_literal) @number (#set! @number "key" "value") (#set! @number "key2" "value2"))'
  854. )
  855. local parser = vim.treesitter.get_parser(0, 'c')
  856. local _, _, metadata = query:iter_matches(parser:parse()[1]:root(), 0, 0, -1)()
  857. local _, nested_tbl = next(metadata)
  858. return nested_tbl
  859. end)
  860. local expected = {
  861. ['key'] = 'value',
  862. ['key2'] = 'value2',
  863. }
  864. eq(expected, result)
  865. end)
  866. end)
  867. end)
  868. end)
  869. describe('trim! directive', function()
  870. it('can trim all whitespace', function()
  871. exec_lua(function()
  872. local lines = {
  873. ' print([[',
  874. '',
  875. ' f',
  876. ' helllo',
  877. ' there',
  878. ' asdf',
  879. ' asdfassd ',
  880. '',
  881. '',
  882. '',
  883. ' ]])',
  884. ' print([[',
  885. ' ',
  886. ' ',
  887. ' ',
  888. ' ]])',
  889. '',
  890. ' print([[]])',
  891. '',
  892. ' print([[',
  893. ' ]])',
  894. '',
  895. ' print([[ hello 😃 ]])',
  896. }
  897. vim.api.nvim_buf_set_lines(0, 0, -1, true, lines)
  898. end)
  899. exec_lua(function()
  900. vim.treesitter.start(0, 'lua')
  901. end)
  902. local query_text = [[
  903. ; query
  904. ((string_content) @str)
  905. ]]
  906. eq({
  907. { 'str', { 0, 16, 10, 2 } },
  908. { 'str', { 11, 10, 15, 2 } },
  909. { 'str', { 17, 10, 17, 10 } },
  910. { 'str', { 19, 10, 20, 2 } },
  911. { 'str', { 22, 10, 22, 29 } },
  912. }, run_query('lua', query_text))
  913. local trim_query_text = [[
  914. ; query
  915. ((string_content) @str
  916. (#trim! @str 1 1 1 1))
  917. ]]
  918. eq({
  919. { 'str', { 2, 12, 6, 10 } },
  920. { 'str', { 11, 10, 11, 10 } },
  921. { 'str', { 17, 10, 17, 10 } },
  922. { 'str', { 19, 10, 19, 10 } },
  923. { 'str', { 22, 15, 22, 25 } },
  924. }, run_query('lua', trim_query_text))
  925. end)
  926. it('trims only empty lines by default (backwards compatible)', function()
  927. insert(dedent [[
  928. ## Heading
  929. With some text
  930. ## And another
  931. With some more here]])
  932. local query_text = [[
  933. ; query
  934. ((section) @fold
  935. (#trim! @fold))
  936. ]]
  937. exec_lua(function()
  938. vim.treesitter.start(0, 'markdown')
  939. end)
  940. eq({
  941. { 'fold', { 0, 0, 2, 14 } },
  942. { 'fold', { 4, 0, 6, 19 } },
  943. }, run_query('markdown', query_text))
  944. end)
  945. it('can trim lines', function()
  946. insert(dedent [[
  947. - Fold list
  948. - Fold list
  949. - Fold list
  950. - Fold list
  951. - Fold list
  952. - Fold list
  953. ]])
  954. local query_text = [[
  955. ; query
  956. ((list_item
  957. (list)) @fold
  958. (#trim! @fold 1 1 1 1))
  959. ]]
  960. exec_lua(function()
  961. vim.treesitter.start(0, 'markdown')
  962. end)
  963. eq({
  964. { 'fold', { 0, 0, 4, 13 } },
  965. { 'fold', { 1, 2, 3, 15 } },
  966. }, run_query('markdown', query_text))
  967. end)
  968. end)
  969. it('tracks the root range properly (#22911)', function()
  970. insert([[
  971. int main() {
  972. int x = 3;
  973. }]])
  974. local query0 = [[
  975. (declaration) @declaration
  976. (function_definition) @function
  977. ]]
  978. exec_lua(function()
  979. vim.treesitter.start(0, 'c')
  980. end)
  981. eq({
  982. { 'function', { 0, 0, 2, 1 } },
  983. { 'declaration', { 1, 2, 1, 12 } },
  984. }, run_query('c', query0))
  985. n.command 'normal ggO'
  986. insert('int a;')
  987. eq({
  988. { 'declaration', { 0, 0, 0, 6 } },
  989. { 'function', { 1, 0, 3, 1 } },
  990. { 'declaration', { 2, 2, 2, 12 } },
  991. }, run_query('c', query0))
  992. end)
  993. it('handles ranges when source is a multiline string (#20419)', function()
  994. local source = [==[
  995. vim.cmd[[
  996. set number
  997. set cmdheight=2
  998. set lastsatus=2
  999. ]]
  1000. set query = [[;; query
  1001. ((function_call
  1002. name: [
  1003. (identifier) @_cdef_identifier
  1004. (_ _ (identifier) @_cdef_identifier)
  1005. ]
  1006. arguments: (arguments (string content: _ @injection.content)))
  1007. (#set! injection.language "c")
  1008. (#eq? @_cdef_identifier "cdef"))
  1009. ]]
  1010. ]==]
  1011. local r = exec_lua(function()
  1012. local parser = vim.treesitter.get_string_parser(source, 'lua')
  1013. parser:parse(true)
  1014. local ranges = {}
  1015. parser:for_each_tree(function(tstree, tree)
  1016. ranges[tree:lang()] = { tstree:root():range(true) }
  1017. end)
  1018. return ranges
  1019. end)
  1020. eq({
  1021. lua = { 0, 6, 6, 16, 4, 438 },
  1022. query = { 6, 20, 113, 15, 6, 431 },
  1023. vim = { 1, 0, 16, 4, 6, 89 },
  1024. }, r)
  1025. -- The above ranges are provided directly from treesitter, however query directives may mutate
  1026. -- the ranges but only provide a Range4. Strip the byte entries from the ranges and make sure
  1027. -- add_bytes() produces the same result.
  1028. local rb = exec_lua(function()
  1029. local add_bytes = require('vim.treesitter._range').add_bytes
  1030. for lang, range in pairs(r) do
  1031. r[lang] = { range[1], range[2], range[4], range[5] }
  1032. r[lang] = add_bytes(source, r[lang])
  1033. end
  1034. return r
  1035. end)
  1036. eq(rb, r)
  1037. end)
  1038. it('does not produce empty injection ranges (#23409)', function()
  1039. insert [[
  1040. Examples: >lua
  1041. local a = {}
  1042. <
  1043. ]]
  1044. -- This is not a valid injection since (code) has children and include-children is not set
  1045. exec_lua(function()
  1046. _G.parser1 = require('vim.treesitter.languagetree').new(0, 'vimdoc', {
  1047. injections = {
  1048. vimdoc = '((codeblock (language) @injection.language (code) @injection.content))',
  1049. },
  1050. })
  1051. _G.parser1:parse(true)
  1052. end)
  1053. eq(0, exec_lua('return #vim.tbl_keys(parser1:children())'))
  1054. exec_lua(function()
  1055. _G.parser2 = require('vim.treesitter.languagetree').new(0, 'vimdoc', {
  1056. injections = {
  1057. vimdoc = '((codeblock (language) @injection.language (code) @injection.content) (#set! injection.include-children))',
  1058. },
  1059. })
  1060. _G.parser2:parse(true)
  1061. end)
  1062. eq(1, exec_lua('return #vim.tbl_keys(parser2:children())'))
  1063. eq({ { { 1, 0, 21, 2, 0, 42 } } }, exec_lua('return parser2:children().lua:included_regions()'))
  1064. end)
  1065. it('parsers injections incrementally', function()
  1066. insert(dedent [[
  1067. >lua
  1068. local a = {}
  1069. <
  1070. >lua
  1071. local b = {}
  1072. <
  1073. >lua
  1074. local c = {}
  1075. <
  1076. >lua
  1077. local d = {}
  1078. <
  1079. >lua
  1080. local e = {}
  1081. <
  1082. >lua
  1083. local f = {}
  1084. <
  1085. >lua
  1086. local g = {}
  1087. <
  1088. ]])
  1089. exec_lua(function()
  1090. _G.parser = require('vim.treesitter.languagetree').new(0, 'vimdoc', {
  1091. injections = {
  1092. vimdoc = '((codeblock (language) @injection.language (code) @injection.content) (#set! injection.include-children))',
  1093. },
  1094. })
  1095. end)
  1096. --- Do not parse injections by default
  1097. eq(
  1098. 0,
  1099. exec_lua(function()
  1100. _G.parser:parse()
  1101. return #vim.tbl_keys(_G.parser:children())
  1102. end)
  1103. )
  1104. --- Only parse injections between lines 0, 2
  1105. eq(
  1106. 1,
  1107. exec_lua(function()
  1108. _G.parser:parse({ 0, 2 })
  1109. return #_G.parser:children().lua:trees()
  1110. end)
  1111. )
  1112. eq(
  1113. 1,
  1114. exec_lua(function()
  1115. _G.parser:parse({ 2, 6 })
  1116. return #_G.parser:children().lua:trees()
  1117. end)
  1118. )
  1119. eq(
  1120. 7,
  1121. exec_lua(function()
  1122. _G.parser:parse(true)
  1123. return #_G.parser:children().lua:trees()
  1124. end)
  1125. )
  1126. end)
  1127. describe('languagetree is_valid()', function()
  1128. before_each(function()
  1129. insert(dedent [[
  1130. Treesitter integration *treesitter*
  1131. Nvim integrates the `tree-sitter` library for incremental parsing of buffers:
  1132. https://tree-sitter.github.io/tree-sitter/
  1133. ]])
  1134. feed(':set ft=help<cr>')
  1135. exec_lua(function()
  1136. vim.treesitter
  1137. .get_parser(0, 'vimdoc', {
  1138. injections = {
  1139. vimdoc = '((codeblock (language) @injection.language (code) @injection.content) (#set! injection.include-children))',
  1140. },
  1141. })
  1142. :parse()
  1143. end)
  1144. end)
  1145. it('is valid excluding, invalid including children initially', function()
  1146. eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
  1147. eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
  1148. end)
  1149. it('is fully valid after a full parse', function()
  1150. exec_lua('vim.treesitter.get_parser():parse(true)')
  1151. eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
  1152. eq(true, exec_lua('return vim.treesitter.get_parser():is_valid()'))
  1153. end)
  1154. it('is valid within a range on parsed tree after parsing it', function()
  1155. exec_lua('vim.treesitter.get_parser():parse({5, 7})')
  1156. eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
  1157. eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(nil, {5, 7})'))
  1158. end)
  1159. describe('when adding content with injections', function()
  1160. before_each(function()
  1161. feed('G')
  1162. insert(dedent [[
  1163. >lua
  1164. local a = {}
  1165. <
  1166. ]])
  1167. end)
  1168. it('is fully invalid after changes', function()
  1169. eq(false, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
  1170. eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
  1171. end)
  1172. it('is valid excluding, invalid including children after a rangeless parse', function()
  1173. exec_lua('vim.treesitter.get_parser():parse()')
  1174. eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
  1175. eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
  1176. end)
  1177. it('is valid within a range on parsed tree after parsing it', function()
  1178. exec_lua('vim.treesitter.get_parser():parse({5, 7})')
  1179. eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
  1180. eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(nil, {5, 7})'))
  1181. end)
  1182. it(
  1183. 'is valid excluding, invalid including children after a range parse that does not lead to parsing not parsed injections',
  1184. function()
  1185. exec_lua('vim.treesitter.get_parser():parse({2, 4})')
  1186. eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
  1187. eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
  1188. end
  1189. )
  1190. end)
  1191. describe('when removing content with injections', function()
  1192. before_each(function()
  1193. feed('G')
  1194. insert(dedent [[
  1195. >lua
  1196. local a = {}
  1197. <
  1198. >lua
  1199. local a = {}
  1200. <
  1201. ]])
  1202. exec_lua('vim.treesitter.get_parser():parse(true)')
  1203. feed('Gd3k')
  1204. end)
  1205. it('is fully invalid after changes', function()
  1206. eq(false, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
  1207. eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
  1208. end)
  1209. it('is valid excluding, invalid including children after a rangeless parse', function()
  1210. exec_lua('vim.treesitter.get_parser():parse()')
  1211. eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
  1212. eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
  1213. end)
  1214. it('is valid within a range parse that leads to parsing modified child tree', function()
  1215. exec_lua('vim.treesitter.get_parser():parse({5, 7})')
  1216. eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
  1217. eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(nil, {5, 7})'))
  1218. end)
  1219. it(
  1220. 'is valid excluding, invalid including children after a range parse that does not lead to parsing modified child tree',
  1221. function()
  1222. exec_lua('vim.treesitter.get_parser():parse({2, 4})')
  1223. eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
  1224. eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
  1225. end
  1226. )
  1227. end)
  1228. end)
  1229. end)