autocmd_spec.lua 44 KB

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