autocmd_spec.lua 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562
  1. local t = require('test.testutil')
  2. local n = require('test.functional.testnvim')()
  3. local clear = n.clear
  4. local command = n.command
  5. local eq = t.eq
  6. local neq = t.neq
  7. local exec_lua = n.exec_lua
  8. local matches = t.matches
  9. local api = n.api
  10. local source = n.source
  11. local pcall_err = t.pcall_err
  12. before_each(clear)
  13. describe('autocmd api', function()
  14. describe('nvim_create_autocmd', function()
  15. it('validation', function()
  16. eq(
  17. "Cannot use both 'callback' and 'command'",
  18. pcall_err(api.nvim_create_autocmd, 'BufReadPost', {
  19. pattern = '*.py,*.pyi',
  20. command = "echo 'Should Have Errored",
  21. callback = 'NotAllowed',
  22. })
  23. )
  24. eq(
  25. "Cannot use both 'pattern' and 'buffer' for the same autocmd",
  26. pcall_err(api.nvim_create_autocmd, 'FileType', {
  27. command = 'let g:called = g:called + 1',
  28. buffer = 0,
  29. pattern = '*.py',
  30. })
  31. )
  32. eq(
  33. "Required: 'event'",
  34. pcall_err(api.nvim_create_autocmd, {}, {
  35. command = 'ls',
  36. })
  37. )
  38. eq("Required: 'command' or 'callback'", pcall_err(api.nvim_create_autocmd, 'FileType', {}))
  39. eq(
  40. "Invalid 'desc': expected String, got Integer",
  41. pcall_err(api.nvim_create_autocmd, 'FileType', {
  42. command = 'ls',
  43. desc = 42,
  44. })
  45. )
  46. eq(
  47. "Invalid 'callback': expected Lua function or Vim function name, got Integer",
  48. pcall_err(api.nvim_create_autocmd, 'FileType', {
  49. callback = 0,
  50. })
  51. )
  52. eq(
  53. "Invalid 'event' item: expected String, got Array",
  54. pcall_err(api.nvim_create_autocmd, { 'FileType', {} }, {})
  55. )
  56. eq(
  57. "Invalid 'group': 0",
  58. pcall_err(api.nvim_create_autocmd, 'FileType', {
  59. group = 0,
  60. command = 'ls',
  61. })
  62. )
  63. eq("Invalid 'event': 'foo'", pcall_err(api.nvim_create_autocmd, 'foo', { command = '' }))
  64. eq(
  65. "Invalid 'event': 'VimEnter '",
  66. pcall_err(api.nvim_create_autocmd, 'VimEnter ', { command = '' })
  67. )
  68. eq(
  69. "Invalid 'event': 'VimEnter foo'",
  70. pcall_err(api.nvim_create_autocmd, 'VimEnter foo', { command = '' })
  71. )
  72. eq(
  73. "Invalid 'event': 'BufAdd,BufDelete'",
  74. pcall_err(api.nvim_create_autocmd, 'BufAdd,BufDelete', { command = '' })
  75. )
  76. end)
  77. it('doesnt leak when you use ++once', function()
  78. eq(
  79. 1,
  80. exec_lua(
  81. [[
  82. local count = 0
  83. vim.api.nvim_create_autocmd("FileType", {
  84. pattern = "*",
  85. callback = function() count = count + 1 end,
  86. once = true
  87. })
  88. vim.cmd "set filetype=txt"
  89. vim.cmd "set filetype=python"
  90. return count
  91. ]],
  92. {}
  93. )
  94. )
  95. end)
  96. it('allows passing buffer by key', function()
  97. api.nvim_set_var('called', 0)
  98. api.nvim_create_autocmd('FileType', {
  99. command = 'let g:called = g:called + 1',
  100. buffer = 0,
  101. })
  102. command 'set filetype=txt'
  103. eq(1, api.nvim_get_var('called'))
  104. -- switch to a new buffer
  105. command 'new'
  106. command 'set filetype=python'
  107. eq(1, api.nvim_get_var('called'))
  108. end)
  109. it('does not allow passing invalid buffers', function()
  110. local ok, msg = pcall(api.nvim_create_autocmd, 'FileType', {
  111. command = 'let g:called = g:called + 1',
  112. buffer = -1,
  113. })
  114. eq(false, ok)
  115. matches('Invalid buffer id', msg)
  116. end)
  117. it('errors on non-functions for cb', function()
  118. eq(
  119. false,
  120. pcall(
  121. exec_lua,
  122. [[
  123. vim.api.nvim_create_autocmd("BufReadPost", {
  124. pattern = "*.py,*.pyi",
  125. callback = 5,
  126. })
  127. ]]
  128. )
  129. )
  130. end)
  131. it('allow passing pattern and <buffer> in same pattern', function()
  132. local ok = pcall(api.nvim_create_autocmd, 'BufReadPost', {
  133. pattern = '*.py,<buffer>',
  134. command = "echo 'Should Not Error'",
  135. })
  136. eq(true, ok)
  137. end)
  138. it('should handle multiple values as comma separated list', function()
  139. api.nvim_create_autocmd('BufReadPost', {
  140. pattern = '*.py,*.pyi',
  141. command = "echo 'Should Not Have Errored'",
  142. })
  143. -- We should have one autocmd for *.py and one for *.pyi
  144. eq(2, #api.nvim_get_autocmds { event = 'BufReadPost' })
  145. end)
  146. it('should handle multiple values as array', function()
  147. api.nvim_create_autocmd('BufReadPost', {
  148. pattern = { '*.py', '*.pyi' },
  149. command = "echo 'Should Not Have Errored'",
  150. })
  151. -- We should have one autocmd for *.py and one for *.pyi
  152. eq(2, #api.nvim_get_autocmds { event = 'BufReadPost' })
  153. end)
  154. describe('desc', function()
  155. it('can add description to one autocmd', function()
  156. local cmd = "echo 'Should Not Have Errored'"
  157. local desc = 'Can show description'
  158. api.nvim_create_autocmd('BufReadPost', {
  159. pattern = '*.py',
  160. command = cmd,
  161. desc = desc,
  162. })
  163. eq(desc, api.nvim_get_autocmds { event = 'BufReadPost' }[1].desc)
  164. eq(cmd, api.nvim_get_autocmds { event = 'BufReadPost' }[1].command)
  165. end)
  166. it('can add description to one autocmd that uses a callback', function()
  167. local desc = 'Can show description'
  168. api.nvim_set_var('desc', desc)
  169. local result = exec_lua([[
  170. local callback = function() print 'Should Not Have Errored' end
  171. vim.api.nvim_create_autocmd("BufReadPost", {
  172. pattern = "*.py",
  173. callback = callback,
  174. desc = vim.g.desc,
  175. })
  176. local aus = vim.api.nvim_get_autocmds({ event = 'BufReadPost' })
  177. local first = aus[1]
  178. return {
  179. desc = first.desc,
  180. cbtype = type(first.callback)
  181. }
  182. ]])
  183. eq({ desc = desc, cbtype = 'function' }, result)
  184. end)
  185. it('will not add a description unless it was provided', function()
  186. exec_lua([[
  187. local callback = function() print 'Should Not Have Errored' end
  188. vim.api.nvim_create_autocmd("BufReadPost", {
  189. pattern = "*.py",
  190. callback = callback,
  191. })
  192. ]])
  193. eq(nil, api.nvim_get_autocmds({ event = 'BufReadPost' })[1].desc)
  194. end)
  195. it('can add description to multiple autocmd', function()
  196. api.nvim_create_autocmd('BufReadPost', {
  197. pattern = { '*.py', '*.pyi' },
  198. command = "echo 'Should Not Have Errored'",
  199. desc = 'Can show description',
  200. })
  201. local aus = api.nvim_get_autocmds { event = 'BufReadPost' }
  202. eq(2, #aus)
  203. eq('Can show description', aus[1].desc)
  204. eq('Can show description', aus[2].desc)
  205. end)
  206. end)
  207. pending('script and verbose settings', function()
  208. it('marks API client', function()
  209. api.nvim_create_autocmd('BufReadPost', {
  210. pattern = '*.py',
  211. command = "echo 'Should Not Have Errored'",
  212. desc = 'Can show description',
  213. })
  214. local aus = api.nvim_get_autocmds { event = 'BufReadPost' }
  215. eq(1, #aus, aus)
  216. end)
  217. end)
  218. it('removes an autocommand if the callback returns true', function()
  219. api.nvim_set_var('some_condition', false)
  220. exec_lua [[
  221. vim.api.nvim_create_autocmd("User", {
  222. pattern = "Test",
  223. desc = "A test autocommand",
  224. callback = function()
  225. return vim.g.some_condition
  226. end,
  227. })
  228. ]]
  229. api.nvim_exec_autocmds('User', { pattern = 'Test' })
  230. local aus = api.nvim_get_autocmds({ event = 'User', pattern = 'Test' })
  231. local first = aus[1]
  232. eq(true, first.id > 0)
  233. api.nvim_set_var('some_condition', true)
  234. api.nvim_exec_autocmds('User', { pattern = 'Test' })
  235. eq({}, api.nvim_get_autocmds({ event = 'User', pattern = 'Test' }))
  236. end)
  237. local function test_autocmd_args(event)
  238. local function get_amatch(pat)
  239. return event == 'User' and pat or vim.fs.normalize(n.fn.fnamemodify(pat, ':p'))
  240. end
  241. local group_id = api.nvim_create_augroup('TestGroup', {})
  242. -- Having an existing autocmd calling expand("<afile>") shouldn't change args #18964
  243. api.nvim_create_autocmd(event, {
  244. group = 'TestGroup',
  245. pattern = 'Te*',
  246. command = 'call expand("<afile>")',
  247. })
  248. local autocmd_id = exec_lua(([[
  249. return vim.api.nvim_create_autocmd(%q, {
  250. group = "TestGroup",
  251. pattern = "Te*",
  252. callback = function(args)
  253. vim.g.autocmd_args = args
  254. end,
  255. })
  256. ]]):format(event))
  257. local exec_pat = 'Test pattern'
  258. local amatch = get_amatch(exec_pat)
  259. api.nvim_exec_autocmds(event, { pattern = exec_pat })
  260. eq({
  261. id = autocmd_id,
  262. group = group_id,
  263. event = event,
  264. match = amatch,
  265. file = exec_pat,
  266. buf = 1,
  267. }, api.nvim_get_var('autocmd_args'))
  268. -- Test without a group
  269. autocmd_id = exec_lua(([[
  270. return vim.api.nvim_create_autocmd(%q, {
  271. pattern = "*",
  272. callback = function(args)
  273. vim.g.autocmd_args = args
  274. end,
  275. })
  276. ]]):format(event))
  277. exec_pat = 'some_pat'
  278. amatch = get_amatch(exec_pat)
  279. api.nvim_exec_autocmds(event, { pattern = exec_pat })
  280. eq({
  281. id = autocmd_id,
  282. group = nil,
  283. event = event,
  284. match = amatch,
  285. file = exec_pat,
  286. buf = 1,
  287. }, api.nvim_get_var('autocmd_args'))
  288. end
  289. describe('receives correct args table', function()
  290. it('for event that takes non-file pattern', function()
  291. test_autocmd_args('User')
  292. end)
  293. it('for event that takes file pattern', function()
  294. test_autocmd_args('BufEnter')
  295. end)
  296. end)
  297. it('can receive arbitrary data', function()
  298. local function test(data)
  299. eq(
  300. data,
  301. exec_lua(
  302. [[
  303. local input = ...
  304. local output
  305. vim.api.nvim_create_autocmd("User", {
  306. pattern = "Test",
  307. callback = function(args)
  308. output = args.data
  309. end,
  310. })
  311. vim.api.nvim_exec_autocmds("User", {
  312. pattern = "Test",
  313. data = input,
  314. })
  315. return output
  316. ]],
  317. data
  318. )
  319. )
  320. end
  321. test('Hello')
  322. test(42)
  323. test(true)
  324. test({ 'list' })
  325. test({ foo = 'bar' })
  326. end)
  327. it('function in arbitrary data is passed to all autocmds #28353', function()
  328. eq(
  329. 1303,
  330. exec_lua([[
  331. local res = 1
  332. local fun = function(m, x)
  333. res = res * m + x
  334. end
  335. local group = vim.api.nvim_create_augroup('MyTest', { clear = false })
  336. vim.api.nvim_create_autocmd('User', {
  337. group = group,
  338. callback = function(payload)
  339. payload.data.fun(10, payload.data.x)
  340. end,
  341. pattern = 'MyEvent',
  342. })
  343. vim.api.nvim_create_autocmd('User', {
  344. group = group,
  345. callback = function(payload)
  346. payload.data.fun(100, payload.data.x)
  347. end,
  348. pattern = 'MyEvent',
  349. })
  350. vim.api.nvim_exec_autocmds('User', {
  351. group = group,
  352. pattern = 'MyEvent',
  353. data = { x = 3, fun = fun },
  354. })
  355. return res
  356. ]])
  357. )
  358. end)
  359. end)
  360. describe('nvim_get_autocmds', function()
  361. it('validation', function()
  362. eq(
  363. "Invalid 'group': 9997999",
  364. pcall_err(api.nvim_get_autocmds, {
  365. group = 9997999,
  366. })
  367. )
  368. eq(
  369. "Invalid 'group': 'bogus'",
  370. pcall_err(api.nvim_get_autocmds, {
  371. group = 'bogus',
  372. })
  373. )
  374. eq(
  375. "Invalid 'group': 0",
  376. pcall_err(api.nvim_get_autocmds, {
  377. group = 0,
  378. })
  379. )
  380. eq(
  381. "Invalid 'group': expected String or Integer, got Array",
  382. pcall_err(api.nvim_get_autocmds, {
  383. group = {},
  384. })
  385. )
  386. eq(
  387. "Invalid 'buffer': expected Integer or Array, got Boolean",
  388. pcall_err(api.nvim_get_autocmds, {
  389. buffer = true,
  390. })
  391. )
  392. eq(
  393. "Invalid 'event': expected String or Array",
  394. pcall_err(api.nvim_get_autocmds, {
  395. event = true,
  396. })
  397. )
  398. eq(
  399. "Invalid 'pattern': expected String or Array, got Boolean",
  400. pcall_err(api.nvim_get_autocmds, {
  401. pattern = true,
  402. })
  403. )
  404. end)
  405. describe('events', function()
  406. it('returns one autocmd when there is only one for an event', function()
  407. command [[au! InsertEnter]]
  408. command [[au InsertEnter * :echo "1"]]
  409. local aus = api.nvim_get_autocmds { event = 'InsertEnter' }
  410. eq(1, #aus)
  411. end)
  412. it('returns two autocmds when there are two for an event', function()
  413. command [[au! InsertEnter]]
  414. command [[au InsertEnter * :echo "1"]]
  415. command [[au InsertEnter * :echo "2"]]
  416. local aus = api.nvim_get_autocmds { event = 'InsertEnter' }
  417. eq(2, #aus)
  418. end)
  419. it('returns the same thing if you use string or list', function()
  420. command [[au! InsertEnter]]
  421. command [[au InsertEnter * :echo "1"]]
  422. command [[au InsertEnter * :echo "2"]]
  423. local string_aus = api.nvim_get_autocmds { event = 'InsertEnter' }
  424. local array_aus = api.nvim_get_autocmds { event = { 'InsertEnter' } }
  425. eq(string_aus, array_aus)
  426. end)
  427. it('returns two autocmds when there are two for an event', function()
  428. command [[au! InsertEnter]]
  429. command [[au! InsertLeave]]
  430. command [[au InsertEnter * :echo "1"]]
  431. command [[au InsertEnter * :echo "2"]]
  432. local aus = api.nvim_get_autocmds { event = { 'InsertEnter', 'InsertLeave' } }
  433. eq(2, #aus)
  434. end)
  435. it('returns different IDs for different autocmds', function()
  436. command [[au! InsertEnter]]
  437. command [[au! InsertLeave]]
  438. command [[au InsertEnter * :echo "1"]]
  439. source [[
  440. call nvim_create_autocmd("InsertLeave", #{
  441. \ command: ":echo 2",
  442. \ })
  443. ]]
  444. local aus = api.nvim_get_autocmds { event = { 'InsertEnter', 'InsertLeave' } }
  445. local first = aus[1]
  446. eq(first.id, nil)
  447. -- TODO: Maybe don't have this number, just assert it's not nil
  448. local second = aus[2]
  449. neq(second.id, nil)
  450. api.nvim_del_autocmd(second.id)
  451. local new_aus = api.nvim_get_autocmds { event = { 'InsertEnter', 'InsertLeave' } }
  452. eq(1, #new_aus)
  453. eq(first, new_aus[1])
  454. end)
  455. it('returns event name', function()
  456. command [[au! InsertEnter]]
  457. command [[au InsertEnter * :echo "1"]]
  458. local aus = api.nvim_get_autocmds { event = 'InsertEnter' }
  459. eq({
  460. {
  461. buflocal = false,
  462. command = ':echo "1"',
  463. event = 'InsertEnter',
  464. once = false,
  465. pattern = '*',
  466. },
  467. }, aus)
  468. end)
  469. it('works with buffer numbers', function()
  470. command [[new]]
  471. command [[au! InsertEnter]]
  472. command [[au InsertEnter <buffer=1> :echo "1"]]
  473. command [[au InsertEnter <buffer=2> :echo "2"]]
  474. local aus = api.nvim_get_autocmds { event = 'InsertEnter', buffer = 0 }
  475. eq({
  476. {
  477. buffer = 2,
  478. buflocal = true,
  479. command = ':echo "2"',
  480. event = 'InsertEnter',
  481. once = false,
  482. pattern = '<buffer=2>',
  483. },
  484. }, aus)
  485. aus = api.nvim_get_autocmds { event = 'InsertEnter', buffer = 1 }
  486. eq({
  487. {
  488. buffer = 1,
  489. buflocal = true,
  490. command = ':echo "1"',
  491. event = 'InsertEnter',
  492. once = false,
  493. pattern = '<buffer=1>',
  494. },
  495. }, aus)
  496. aus = api.nvim_get_autocmds { event = 'InsertEnter', buffer = { 1, 2 } }
  497. eq({
  498. {
  499. buffer = 1,
  500. buflocal = true,
  501. command = ':echo "1"',
  502. event = 'InsertEnter',
  503. once = false,
  504. pattern = '<buffer=1>',
  505. },
  506. {
  507. buffer = 2,
  508. buflocal = true,
  509. command = ':echo "2"',
  510. event = 'InsertEnter',
  511. once = false,
  512. pattern = '<buffer=2>',
  513. },
  514. }, aus)
  515. eq(
  516. "Invalid 'buffer': expected Integer or Array, got String",
  517. pcall_err(api.nvim_get_autocmds, { event = 'InsertEnter', buffer = 'foo' })
  518. )
  519. eq(
  520. "Invalid 'buffer': expected Integer, got String",
  521. pcall_err(api.nvim_get_autocmds, { event = 'InsertEnter', buffer = { 'foo', 42 } })
  522. )
  523. eq(
  524. 'Invalid buffer id: 42',
  525. pcall_err(api.nvim_get_autocmds, { event = 'InsertEnter', buffer = { 42 } })
  526. )
  527. local bufs = {}
  528. for _ = 1, 257 do
  529. table.insert(bufs, api.nvim_create_buf(true, false))
  530. end
  531. eq(
  532. 'Too many buffers (maximum of 256)',
  533. pcall_err(api.nvim_get_autocmds, { event = 'InsertEnter', buffer = bufs })
  534. )
  535. end)
  536. it('returns autocmds when group is specified by id', function()
  537. local auid = api.nvim_create_augroup('nvim_test_augroup', { clear = true })
  538. api.nvim_create_autocmd('FileType', { group = auid, command = 'echo "1"' })
  539. api.nvim_create_autocmd('FileType', { group = auid, command = 'echo "2"' })
  540. local aus = api.nvim_get_autocmds { group = auid }
  541. eq(2, #aus)
  542. local aus2 = api.nvim_get_autocmds { group = auid, event = 'InsertEnter' }
  543. eq(0, #aus2)
  544. end)
  545. it('returns autocmds when group is specified by name', function()
  546. local auname = 'nvim_test_augroup'
  547. api.nvim_create_augroup(auname, { clear = true })
  548. api.nvim_create_autocmd('FileType', { group = auname, command = 'echo "1"' })
  549. api.nvim_create_autocmd('FileType', { group = auname, command = 'echo "2"' })
  550. local aus = api.nvim_get_autocmds { group = auname }
  551. eq(2, #aus)
  552. local aus2 = api.nvim_get_autocmds { group = auname, event = 'InsertEnter' }
  553. eq(0, #aus2)
  554. end)
  555. it('should respect nested', function()
  556. local bufs = exec_lua [[
  557. local count = 0
  558. vim.api.nvim_create_autocmd("BufNew", {
  559. once = false,
  560. nested = true,
  561. callback = function()
  562. count = count + 1
  563. if count > 5 then
  564. return true
  565. end
  566. vim.cmd(string.format("new README_%s.md", count))
  567. end
  568. })
  569. vim.cmd "new First.md"
  570. return vim.api.nvim_list_bufs()
  571. ]]
  572. -- 1 for the first buffer
  573. -- 2 for First.md
  574. -- 3-7 for the 5 we make in the autocmd
  575. eq({ 1, 2, 3, 4, 5, 6, 7 }, bufs)
  576. end)
  577. it('can retrieve a callback from an autocmd', function()
  578. local content = 'I Am A Callback'
  579. api.nvim_set_var('content', content)
  580. exec_lua([[
  581. local cb = function() return vim.g.content end
  582. vim.api.nvim_create_autocmd("User", {
  583. pattern = "TestTrigger",
  584. desc = "A test autocommand with a callback",
  585. callback = cb,
  586. })
  587. ]])
  588. local result = exec_lua([[
  589. local aus = vim.api.nvim_get_autocmds({ event = 'User', pattern = 'TestTrigger' })
  590. local first = aus[1]
  591. return {
  592. cb = {
  593. type = type(first.callback),
  594. can_retrieve = first.callback() == vim.g.content
  595. }
  596. }
  597. ]])
  598. eq({ cb = { type = 'function', can_retrieve = true } }, result)
  599. -- Also test with Vimscript
  600. source([[
  601. let s:aus = nvim_get_autocmds({'event': 'User', 'pattern': 'TestTrigger'})
  602. let g:result = s:aus[0].callback()
  603. ]])
  604. eq(content, api.nvim_get_var('result'))
  605. end)
  606. it(
  607. 'will return an empty string as the command for an autocmd that uses a callback',
  608. function()
  609. local result = exec_lua([[
  610. local callback = function() print 'I Am A Callback' end
  611. vim.api.nvim_create_autocmd("BufWritePost", {
  612. pattern = "*.py",
  613. callback = callback,
  614. })
  615. local aus = vim.api.nvim_get_autocmds({ event = 'BufWritePost' })
  616. local first = aus[1]
  617. return {
  618. command = first.command,
  619. cbtype = type(first.callback)
  620. }
  621. ]])
  622. eq({ command = '', cbtype = 'function' }, result)
  623. end
  624. )
  625. end)
  626. describe('groups', function()
  627. before_each(function()
  628. command [[au! InsertEnter]]
  629. command [[au InsertEnter * :echo "No Group"]]
  630. command [[augroup GroupOne]]
  631. command [[ au InsertEnter * :echo "GroupOne:1"]]
  632. command [[augroup END]]
  633. command [[augroup GroupTwo]]
  634. command [[ au InsertEnter * :echo "GroupTwo:2"]]
  635. command [[ au InsertEnter * :echo "GroupTwo:3"]]
  636. command [[augroup END]]
  637. end)
  638. it('returns all groups if no group is specified', function()
  639. local aus = api.nvim_get_autocmds { event = 'InsertEnter' }
  640. if #aus ~= 4 then
  641. eq({}, aus)
  642. end
  643. eq(4, #aus)
  644. end)
  645. it('returns only the group specified', function()
  646. local aus = api.nvim_get_autocmds {
  647. event = 'InsertEnter',
  648. group = 'GroupOne',
  649. }
  650. eq(1, #aus)
  651. eq([[:echo "GroupOne:1"]], aus[1].command)
  652. eq('GroupOne', aus[1].group_name)
  653. end)
  654. it('returns only the group specified, multiple values', function()
  655. local aus = api.nvim_get_autocmds {
  656. event = 'InsertEnter',
  657. group = 'GroupTwo',
  658. }
  659. eq(2, #aus)
  660. eq([[:echo "GroupTwo:2"]], aus[1].command)
  661. eq('GroupTwo', aus[1].group_name)
  662. eq([[:echo "GroupTwo:3"]], aus[2].command)
  663. eq('GroupTwo', aus[2].group_name)
  664. end)
  665. end)
  666. describe('groups: 2', function()
  667. it('raises error for undefined augroup name', function()
  668. local success, code = unpack(api.nvim_exec_lua(
  669. [[
  670. return {pcall(function()
  671. vim.api.nvim_create_autocmd("FileType", {
  672. pattern = "*",
  673. group = "NotDefined",
  674. command = "echo 'hello'",
  675. })
  676. end)}
  677. ]],
  678. {}
  679. ))
  680. eq(false, success)
  681. matches("Invalid 'group': 'NotDefined'", code)
  682. end)
  683. it('raises error for undefined augroup id', function()
  684. local success, code = unpack(api.nvim_exec_lua(
  685. [[
  686. return {pcall(function()
  687. -- Make sure the augroup is deleted
  688. vim.api.nvim_del_augroup_by_id(1)
  689. vim.api.nvim_create_autocmd("FileType", {
  690. pattern = "*",
  691. group = 1,
  692. command = "echo 'hello'",
  693. })
  694. end)}
  695. ]],
  696. {}
  697. ))
  698. eq(false, success)
  699. matches("Invalid 'group': 1", code)
  700. end)
  701. it('raises error for invalid group type', function()
  702. local success, code = unpack(api.nvim_exec_lua(
  703. [[
  704. return {pcall(function()
  705. vim.api.nvim_create_autocmd("FileType", {
  706. pattern = "*",
  707. group = true,
  708. command = "echo 'hello'",
  709. })
  710. end)}
  711. ]],
  712. {}
  713. ))
  714. eq(false, success)
  715. matches("Invalid 'group': expected String or Integer, got Boolean", code)
  716. end)
  717. it('raises error for invalid pattern array', function()
  718. local success, code = unpack(api.nvim_exec_lua(
  719. [[
  720. return {pcall(function()
  721. vim.api.nvim_create_autocmd("FileType", {
  722. pattern = {{}},
  723. command = "echo 'hello'",
  724. })
  725. end)}
  726. ]],
  727. {}
  728. ))
  729. eq(false, success)
  730. matches("Invalid 'pattern' item: expected String, got Array", code)
  731. end)
  732. end)
  733. describe('patterns', function()
  734. before_each(function()
  735. command [[au! InsertEnter]]
  736. command [[au InsertEnter * :echo "No Group"]]
  737. command [[au InsertEnter *.one :echo "GroupOne:1"]]
  738. command [[au InsertEnter *.two :echo "GroupTwo:2"]]
  739. command [[au InsertEnter *.two :echo "GroupTwo:3"]]
  740. command [[au InsertEnter <buffer> :echo "Buffer"]]
  741. end)
  742. it('returns for literal match', function()
  743. local aus = api.nvim_get_autocmds {
  744. event = 'InsertEnter',
  745. pattern = '*',
  746. }
  747. eq(1, #aus)
  748. eq([[:echo "No Group"]], aus[1].command)
  749. end)
  750. it('returns for multiple matches', function()
  751. -- vim.api.nvim_get_autocmds
  752. local aus = api.nvim_get_autocmds {
  753. event = 'InsertEnter',
  754. pattern = { '*.one', '*.two' },
  755. }
  756. eq(3, #aus)
  757. eq([[:echo "GroupOne:1"]], aus[1].command)
  758. eq([[:echo "GroupTwo:2"]], aus[2].command)
  759. eq([[:echo "GroupTwo:3"]], aus[3].command)
  760. end)
  761. it('should work for buffer autocmds', function()
  762. local normalized_aus = api.nvim_get_autocmds {
  763. event = 'InsertEnter',
  764. pattern = '<buffer=1>',
  765. }
  766. local raw_aus = api.nvim_get_autocmds {
  767. event = 'InsertEnter',
  768. pattern = '<buffer>',
  769. }
  770. local zero_aus = api.nvim_get_autocmds {
  771. event = 'InsertEnter',
  772. pattern = '<buffer=0>',
  773. }
  774. eq(normalized_aus, raw_aus)
  775. eq(normalized_aus, zero_aus)
  776. eq([[:echo "Buffer"]], normalized_aus[1].command)
  777. end)
  778. end)
  779. end)
  780. describe('nvim_exec_autocmds', function()
  781. it('validation', function()
  782. eq(
  783. "Invalid 'group': 9997999",
  784. pcall_err(api.nvim_exec_autocmds, 'FileType', {
  785. group = 9997999,
  786. })
  787. )
  788. eq(
  789. "Invalid 'group': 'bogus'",
  790. pcall_err(api.nvim_exec_autocmds, 'FileType', {
  791. group = 'bogus',
  792. })
  793. )
  794. eq(
  795. "Invalid 'group': expected String or Integer, got Array",
  796. pcall_err(api.nvim_exec_autocmds, 'FileType', {
  797. group = {},
  798. })
  799. )
  800. eq(
  801. "Invalid 'group': 0",
  802. pcall_err(api.nvim_exec_autocmds, 'FileType', {
  803. group = 0,
  804. })
  805. )
  806. eq(
  807. "Invalid 'buffer': expected Buffer, got Array",
  808. pcall_err(api.nvim_exec_autocmds, 'FileType', {
  809. buffer = {},
  810. })
  811. )
  812. eq(
  813. "Invalid 'event' item: expected String, got Array",
  814. pcall_err(api.nvim_exec_autocmds, { 'FileType', {} }, {})
  815. )
  816. end)
  817. it('can trigger builtin autocmds', function()
  818. api.nvim_set_var('autocmd_executed', false)
  819. api.nvim_create_autocmd('BufReadPost', {
  820. pattern = '*',
  821. command = 'let g:autocmd_executed = v:true',
  822. })
  823. eq(false, api.nvim_get_var('autocmd_executed'))
  824. api.nvim_exec_autocmds('BufReadPost', {})
  825. eq(true, api.nvim_get_var('autocmd_executed'))
  826. end)
  827. it('can trigger multiple patterns', function()
  828. api.nvim_set_var('autocmd_executed', 0)
  829. api.nvim_create_autocmd('BufReadPost', {
  830. pattern = '*',
  831. command = 'let g:autocmd_executed += 1',
  832. })
  833. api.nvim_exec_autocmds('BufReadPost', { pattern = { '*.lua', '*.vim' } })
  834. eq(2, api.nvim_get_var('autocmd_executed'))
  835. api.nvim_create_autocmd('BufReadPre', {
  836. pattern = { 'bar', 'foo' },
  837. command = 'let g:autocmd_executed += 10',
  838. })
  839. api.nvim_exec_autocmds('BufReadPre', { pattern = { 'foo', 'bar', 'baz', 'frederick' } })
  840. eq(22, api.nvim_get_var('autocmd_executed'))
  841. end)
  842. it('can pass the buffer', function()
  843. api.nvim_set_var('buffer_executed', -1)
  844. eq(-1, api.nvim_get_var('buffer_executed'))
  845. api.nvim_create_autocmd('BufLeave', {
  846. pattern = '*',
  847. command = 'let g:buffer_executed = +expand("<abuf>")',
  848. })
  849. -- Doesn't execute for other non-matching events
  850. api.nvim_exec_autocmds('CursorHold', { buffer = 1 })
  851. eq(-1, api.nvim_get_var('buffer_executed'))
  852. api.nvim_exec_autocmds('BufLeave', { buffer = 1 })
  853. eq(1, api.nvim_get_var('buffer_executed'))
  854. end)
  855. it('can pass the filename, pattern match', function()
  856. api.nvim_set_var('filename_executed', 'none')
  857. eq('none', api.nvim_get_var('filename_executed'))
  858. api.nvim_create_autocmd('BufEnter', {
  859. pattern = '*.py',
  860. command = 'let g:filename_executed = expand("<afile>")',
  861. })
  862. -- Doesn't execute for other non-matching events
  863. api.nvim_exec_autocmds('CursorHold', { buffer = 1 })
  864. eq('none', api.nvim_get_var('filename_executed'))
  865. command('edit __init__.py')
  866. eq('__init__.py', api.nvim_get_var('filename_executed'))
  867. end)
  868. it('cannot pass buf and fname', function()
  869. local ok = pcall(
  870. api.nvim_exec_autocmds,
  871. 'BufReadPre',
  872. { pattern = 'literally_cannot_error.rs', buffer = 1 }
  873. )
  874. eq(false, ok)
  875. end)
  876. it('can pass the filename, exact match', function()
  877. api.nvim_set_var('filename_executed', 'none')
  878. eq('none', api.nvim_get_var('filename_executed'))
  879. command('edit other_file.txt')
  880. command('edit __init__.py')
  881. eq('none', api.nvim_get_var('filename_executed'))
  882. api.nvim_create_autocmd('CursorHoldI', {
  883. pattern = '__init__.py',
  884. command = 'let g:filename_executed = expand("<afile>")',
  885. })
  886. -- Doesn't execute for other non-matching events
  887. api.nvim_exec_autocmds('CursorHoldI', { buffer = 1 })
  888. eq('none', api.nvim_get_var('filename_executed'))
  889. api.nvim_exec_autocmds('CursorHoldI', { buffer = api.nvim_get_current_buf() })
  890. eq('__init__.py', api.nvim_get_var('filename_executed'))
  891. -- Reset filename
  892. api.nvim_set_var('filename_executed', 'none')
  893. api.nvim_exec_autocmds('CursorHoldI', { pattern = '__init__.py' })
  894. eq('__init__.py', api.nvim_get_var('filename_executed'))
  895. end)
  896. it('works with user autocmds', function()
  897. api.nvim_set_var('matched', 'none')
  898. api.nvim_create_autocmd('User', {
  899. pattern = 'TestCommand',
  900. command = 'let g:matched = "matched"',
  901. })
  902. api.nvim_exec_autocmds('User', { pattern = 'OtherCommand' })
  903. eq('none', api.nvim_get_var('matched'))
  904. api.nvim_exec_autocmds('User', { pattern = 'TestCommand' })
  905. eq('matched', api.nvim_get_var('matched'))
  906. end)
  907. it('can pass group by id', function()
  908. api.nvim_set_var('group_executed', false)
  909. local auid = api.nvim_create_augroup('nvim_test_augroup', { clear = true })
  910. api.nvim_create_autocmd('FileType', {
  911. group = auid,
  912. command = 'let g:group_executed = v:true',
  913. })
  914. eq(false, api.nvim_get_var('group_executed'))
  915. api.nvim_exec_autocmds('FileType', { group = auid })
  916. eq(true, api.nvim_get_var('group_executed'))
  917. end)
  918. it('can pass group by name', function()
  919. api.nvim_set_var('group_executed', false)
  920. local auname = 'nvim_test_augroup'
  921. api.nvim_create_augroup(auname, { clear = true })
  922. api.nvim_create_autocmd('FileType', {
  923. group = auname,
  924. command = 'let g:group_executed = v:true',
  925. })
  926. eq(false, api.nvim_get_var('group_executed'))
  927. api.nvim_exec_autocmds('FileType', { group = auname })
  928. eq(true, api.nvim_get_var('group_executed'))
  929. end)
  930. end)
  931. describe('nvim_create_augroup', function()
  932. before_each(function()
  933. clear()
  934. api.nvim_set_var('executed', 0)
  935. end)
  936. local make_counting_autocmd = function(opts)
  937. opts = opts or {}
  938. local resulting = {
  939. pattern = '*',
  940. command = 'let g:executed = g:executed + 1',
  941. }
  942. resulting.group = opts.group
  943. resulting.once = opts.once
  944. api.nvim_create_autocmd('FileType', resulting)
  945. end
  946. local set_ft = function(ft)
  947. ft = ft or 'txt'
  948. source(string.format('set filetype=%s', ft))
  949. end
  950. local get_executed_count = function()
  951. return api.nvim_get_var('executed')
  952. end
  953. it('can be added in a group', function()
  954. local augroup = 'TestGroup'
  955. api.nvim_create_augroup(augroup, { clear = true })
  956. make_counting_autocmd { group = augroup }
  957. set_ft('txt')
  958. set_ft('python')
  959. eq(2, get_executed_count())
  960. end)
  961. it('works getting called multiple times', function()
  962. make_counting_autocmd()
  963. set_ft()
  964. set_ft()
  965. set_ft()
  966. eq(3, get_executed_count())
  967. end)
  968. it('handles ++once', function()
  969. make_counting_autocmd { once = true }
  970. set_ft('txt')
  971. set_ft('help')
  972. set_ft('txt')
  973. set_ft('help')
  974. eq(1, get_executed_count())
  975. end)
  976. it('errors on unexpected keys', function()
  977. local success, code = pcall(api.nvim_create_autocmd, 'FileType', {
  978. pattern = '*',
  979. not_a_valid_key = 'NotDefined',
  980. })
  981. eq(false, success)
  982. matches('not_a_valid_key', code)
  983. end)
  984. it('can execute simple callback', function()
  985. exec_lua(
  986. [[
  987. vim.g.executed = false
  988. vim.api.nvim_create_autocmd("FileType", {
  989. pattern = "*",
  990. callback = function() vim.g.executed = true end,
  991. })
  992. ]],
  993. {}
  994. )
  995. eq(
  996. true,
  997. exec_lua(
  998. [[
  999. vim.cmd "set filetype=txt"
  1000. return vim.g.executed
  1001. ]],
  1002. {}
  1003. )
  1004. )
  1005. end)
  1006. it('calls multiple lua callbacks for the same autocmd execution', function()
  1007. eq(
  1008. 4,
  1009. exec_lua(
  1010. [[
  1011. local count = 0
  1012. local counter = function()
  1013. count = count + 1
  1014. end
  1015. vim.api.nvim_create_autocmd("FileType", {
  1016. pattern = "*",
  1017. callback = counter,
  1018. })
  1019. vim.api.nvim_create_autocmd("FileType", {
  1020. pattern = "*",
  1021. callback = counter,
  1022. })
  1023. vim.cmd "set filetype=txt"
  1024. vim.cmd "set filetype=txt"
  1025. return count
  1026. ]],
  1027. {}
  1028. )
  1029. )
  1030. end)
  1031. it('properly releases functions with ++once', function()
  1032. exec_lua([[
  1033. WeakTable = setmetatable({}, { __mode = "k" })
  1034. OnceCount = 0
  1035. MyVal = {}
  1036. WeakTable[MyVal] = true
  1037. vim.api.nvim_create_autocmd("FileType", {
  1038. pattern = "*",
  1039. callback = function()
  1040. OnceCount = OnceCount + 1
  1041. MyVal = {}
  1042. end,
  1043. once = true
  1044. })
  1045. ]])
  1046. command [[set filetype=txt]]
  1047. eq(1, exec_lua([[return OnceCount]], {}))
  1048. exec_lua([[collectgarbage()]], {})
  1049. command [[set filetype=txt]]
  1050. eq(1, exec_lua([[return OnceCount]], {}))
  1051. eq(
  1052. 0,
  1053. exec_lua([[
  1054. local count = 0
  1055. for _ in pairs(WeakTable) do
  1056. count = count + 1
  1057. end
  1058. return count
  1059. ]]),
  1060. 'Should have no keys remaining'
  1061. )
  1062. end)
  1063. it('groups can be cleared', function()
  1064. local augroup = 'TestGroup'
  1065. api.nvim_create_augroup(augroup, { clear = true })
  1066. api.nvim_create_autocmd('FileType', {
  1067. group = augroup,
  1068. command = 'let g:executed = g:executed + 1',
  1069. })
  1070. set_ft('txt')
  1071. set_ft('txt')
  1072. eq(2, get_executed_count(), 'should only count twice')
  1073. api.nvim_create_augroup(augroup, { clear = true })
  1074. eq({}, api.nvim_get_autocmds { group = augroup })
  1075. set_ft('txt')
  1076. set_ft('txt')
  1077. eq(2, get_executed_count(), 'No additional counts')
  1078. end)
  1079. it('can delete non-existent groups with pcall', function()
  1080. eq(false, exec_lua [[return pcall(vim.api.nvim_del_augroup_by_name, 'noexist')]])
  1081. eq('Vim:E367: No such group: "noexist"', pcall_err(api.nvim_del_augroup_by_name, 'noexist'))
  1082. eq(false, exec_lua [[return pcall(vim.api.nvim_del_augroup_by_id, -12342)]])
  1083. eq('Vim:E367: No such group: "--Deleted--"', pcall_err(api.nvim_del_augroup_by_id, -12312))
  1084. eq(false, exec_lua [[return pcall(vim.api.nvim_del_augroup_by_id, 0)]])
  1085. eq('Vim:E367: No such group: "[NULL]"', pcall_err(api.nvim_del_augroup_by_id, 0))
  1086. eq(false, exec_lua [[return pcall(vim.api.nvim_del_augroup_by_id, 12342)]])
  1087. eq('Vim:E367: No such group: "[NULL]"', pcall_err(api.nvim_del_augroup_by_id, 12312))
  1088. end)
  1089. it('groups work with once', function()
  1090. local augroup = 'TestGroup'
  1091. api.nvim_create_augroup(augroup, { clear = true })
  1092. make_counting_autocmd { group = augroup, once = true }
  1093. set_ft('txt')
  1094. set_ft('python')
  1095. eq(1, get_executed_count())
  1096. end)
  1097. it('autocmds can be registered multiple times.', function()
  1098. local augroup = 'TestGroup'
  1099. api.nvim_create_augroup(augroup, { clear = true })
  1100. make_counting_autocmd { group = augroup, once = false }
  1101. make_counting_autocmd { group = augroup, once = false }
  1102. make_counting_autocmd { group = augroup, once = false }
  1103. set_ft('txt')
  1104. set_ft('python')
  1105. eq(3 * 2, get_executed_count())
  1106. end)
  1107. it('can be deleted', function()
  1108. local augroup = 'WillBeDeleted'
  1109. api.nvim_create_augroup(augroup, { clear = true })
  1110. api.nvim_create_autocmd({ 'FileType' }, {
  1111. pattern = '*',
  1112. command = "echo 'does not matter'",
  1113. })
  1114. -- Clears the augroup from before, which erases the autocmd
  1115. api.nvim_create_augroup(augroup, { clear = true })
  1116. local result = #api.nvim_get_autocmds { group = augroup }
  1117. eq(0, result)
  1118. end)
  1119. it('can be used for buffer local autocmds', function()
  1120. local augroup = 'WillBeDeleted'
  1121. api.nvim_set_var('value_set', false)
  1122. api.nvim_create_augroup(augroup, { clear = true })
  1123. api.nvim_create_autocmd('FileType', {
  1124. pattern = '<buffer>',
  1125. command = 'let g:value_set = v:true',
  1126. })
  1127. command 'new'
  1128. command 'set filetype=python'
  1129. eq(false, api.nvim_get_var('value_set'))
  1130. end)
  1131. it('can accept vimscript functions', function()
  1132. source [[
  1133. let g:vimscript_executed = 0
  1134. function! MyVimscriptFunction() abort
  1135. let g:vimscript_executed = g:vimscript_executed + 1
  1136. endfunction
  1137. call nvim_create_autocmd("FileType", #{
  1138. \ pattern: ["python", "javascript"],
  1139. \ callback: "MyVimscriptFunction",
  1140. \ })
  1141. set filetype=txt
  1142. set filetype=python
  1143. set filetype=txt
  1144. set filetype=javascript
  1145. set filetype=txt
  1146. ]]
  1147. eq(2, api.nvim_get_var('vimscript_executed'))
  1148. end)
  1149. end)
  1150. describe('augroup!', function()
  1151. it('legacy: should clear and not return any autocmds for delete groups', function()
  1152. command('augroup TEMP_A')
  1153. command(' autocmd! BufReadPost *.py :echo "Hello"')
  1154. command('augroup END')
  1155. command('augroup! TEMP_A')
  1156. eq(false, pcall(api.nvim_get_autocmds, { group = 'TEMP_A' }))
  1157. -- For some reason, augroup! doesn't clear the autocmds themselves, which is just wild
  1158. -- but we managed to keep this behavior.
  1159. eq(1, #api.nvim_get_autocmds { event = 'BufReadPost' })
  1160. end)
  1161. it('legacy: remove augroups that have no autocmds', function()
  1162. command('augroup TEMP_AB')
  1163. command('augroup END')
  1164. command('augroup! TEMP_AB')
  1165. eq(false, pcall(api.nvim_get_autocmds, { group = 'TEMP_AB' }))
  1166. eq(0, #api.nvim_get_autocmds { event = 'BufReadPost' })
  1167. end)
  1168. it('legacy: multiple remove and add augroup', function()
  1169. command('augroup TEMP_ABC')
  1170. command(' au!')
  1171. command(' autocmd BufReadPost *.py echo "Hello"')
  1172. command('augroup END')
  1173. command('augroup! TEMP_ABC')
  1174. -- Should still have one autocmd :'(
  1175. local aus = api.nvim_get_autocmds { event = 'BufReadPost' }
  1176. eq(1, #aus, aus)
  1177. command('augroup TEMP_ABC')
  1178. command(' au!')
  1179. command(' autocmd BufReadPost *.py echo "Hello"')
  1180. command('augroup END')
  1181. -- Should now have two autocmds :'(
  1182. aus = api.nvim_get_autocmds { event = 'BufReadPost' }
  1183. eq(2, #aus, aus)
  1184. command('augroup! TEMP_ABC')
  1185. eq(false, pcall(api.nvim_get_autocmds, { group = 'TEMP_ABC' }))
  1186. eq(2, #api.nvim_get_autocmds { event = 'BufReadPost' })
  1187. end)
  1188. it('api: should clear and not return any autocmds for delete groups by id', function()
  1189. command('augroup TEMP_ABCD')
  1190. command('autocmd! BufReadPost *.py :echo "Hello"')
  1191. command('augroup END')
  1192. local augroup_id = api.nvim_create_augroup('TEMP_ABCD', { clear = false })
  1193. api.nvim_del_augroup_by_id(augroup_id)
  1194. -- For good reason, we kill all the autocmds from del_augroup,
  1195. -- so now this works as expected
  1196. eq(false, pcall(api.nvim_get_autocmds, { group = 'TEMP_ABCD' }))
  1197. eq(0, #api.nvim_get_autocmds { event = 'BufReadPost' })
  1198. end)
  1199. it('api: should clear and not return any autocmds for delete groups by name', function()
  1200. command('augroup TEMP_ABCDE')
  1201. command('autocmd! BufReadPost *.py :echo "Hello"')
  1202. command('augroup END')
  1203. api.nvim_del_augroup_by_name('TEMP_ABCDE')
  1204. -- For good reason, we kill all the autocmds from del_augroup,
  1205. -- so now this works as expected
  1206. eq(false, pcall(api.nvim_get_autocmds, { group = 'TEMP_ABCDE' }))
  1207. eq(0, #api.nvim_get_autocmds { event = 'BufReadPost' })
  1208. end)
  1209. end)
  1210. describe('nvim_clear_autocmds', function()
  1211. it('validation', function()
  1212. eq(
  1213. "Cannot use both 'pattern' and 'buffer'",
  1214. pcall_err(api.nvim_clear_autocmds, {
  1215. pattern = '*',
  1216. buffer = 42,
  1217. })
  1218. )
  1219. eq(
  1220. "Invalid 'event' item: expected String, got Array",
  1221. pcall_err(api.nvim_clear_autocmds, {
  1222. event = { 'FileType', {} },
  1223. })
  1224. )
  1225. eq("Invalid 'group': 0", pcall_err(api.nvim_clear_autocmds, { group = 0 }))
  1226. end)
  1227. it('should clear based on event + pattern', function()
  1228. command('autocmd InsertEnter *.py :echo "Python can be cool sometimes"')
  1229. command('autocmd InsertEnter *.txt :echo "Text Files Are Cool"')
  1230. local search = { event = 'InsertEnter', pattern = '*.txt' }
  1231. local before_delete = api.nvim_get_autocmds(search)
  1232. eq(1, #before_delete)
  1233. local before_delete_all = api.nvim_get_autocmds { event = search.event }
  1234. eq(2, #before_delete_all)
  1235. api.nvim_clear_autocmds(search)
  1236. local after_delete = api.nvim_get_autocmds(search)
  1237. eq(0, #after_delete)
  1238. local after_delete_all = api.nvim_get_autocmds { event = search.event }
  1239. eq(1, #after_delete_all)
  1240. end)
  1241. it('should clear based on event', function()
  1242. command('autocmd InsertEnter *.py :echo "Python can be cool sometimes"')
  1243. command('autocmd InsertEnter *.txt :echo "Text Files Are Cool"')
  1244. local search = { event = 'InsertEnter' }
  1245. local before_delete = api.nvim_get_autocmds(search)
  1246. eq(2, #before_delete)
  1247. api.nvim_clear_autocmds(search)
  1248. local after_delete = api.nvim_get_autocmds(search)
  1249. eq(0, #after_delete)
  1250. end)
  1251. it('should clear based on pattern', function()
  1252. command('autocmd InsertEnter *.TestPat1 :echo "Enter 1"')
  1253. command('autocmd InsertLeave *.TestPat1 :echo "Leave 1"')
  1254. command('autocmd InsertEnter *.TestPat2 :echo "Enter 2"')
  1255. command('autocmd InsertLeave *.TestPat2 :echo "Leave 2"')
  1256. local search = { pattern = '*.TestPat1' }
  1257. local before_delete = api.nvim_get_autocmds(search)
  1258. eq(2, #before_delete)
  1259. local before_delete_events =
  1260. api.nvim_get_autocmds { event = { 'InsertEnter', 'InsertLeave' } }
  1261. eq(4, #before_delete_events)
  1262. api.nvim_clear_autocmds(search)
  1263. local after_delete = api.nvim_get_autocmds(search)
  1264. eq(0, #after_delete)
  1265. local after_delete_events = api.nvim_get_autocmds { event = { 'InsertEnter', 'InsertLeave' } }
  1266. eq(2, #after_delete_events)
  1267. end)
  1268. it('should allow clearing by buffer', function()
  1269. command('autocmd! InsertEnter')
  1270. command('autocmd InsertEnter <buffer> :echo "Enter Buffer"')
  1271. command('autocmd InsertEnter *.TestPat1 :echo "Enter Pattern"')
  1272. local search = { event = 'InsertEnter' }
  1273. local before_delete = api.nvim_get_autocmds(search)
  1274. eq(2, #before_delete)
  1275. api.nvim_clear_autocmds { buffer = 0 }
  1276. local after_delete = api.nvim_get_autocmds(search)
  1277. eq(1, #after_delete)
  1278. eq('*.TestPat1', after_delete[1].pattern)
  1279. end)
  1280. it('should allow clearing by buffer and group', function()
  1281. command('augroup TestNvimClearAutocmds')
  1282. command(' au!')
  1283. command(' autocmd InsertEnter <buffer> :echo "Enter Buffer"')
  1284. command(' autocmd InsertEnter *.TestPat1 :echo "Enter Pattern"')
  1285. command('augroup END')
  1286. local search = { event = 'InsertEnter', group = 'TestNvimClearAutocmds' }
  1287. local before_delete = api.nvim_get_autocmds(search)
  1288. eq(2, #before_delete)
  1289. -- Doesn't clear without passing group.
  1290. api.nvim_clear_autocmds { buffer = 0 }
  1291. local without_group = api.nvim_get_autocmds(search)
  1292. eq(2, #without_group)
  1293. -- Doesn't clear with passing group.
  1294. api.nvim_clear_autocmds { buffer = 0, group = search.group }
  1295. local with_group = api.nvim_get_autocmds(search)
  1296. eq(1, #with_group)
  1297. end)
  1298. end)
  1299. end)