12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544 |
- local t = require('test.testutil')
- local n = require('test.functional.testnvim')()
- local clear = n.clear
- local command = n.command
- local eq = t.eq
- local neq = t.neq
- local exec_lua = n.exec_lua
- local matches = t.matches
- local api = n.api
- local source = n.source
- local pcall_err = t.pcall_err
- before_each(clear)
- describe('autocmd api', function()
- describe('nvim_create_autocmd', function()
- it('validation', function()
- eq(
- "Cannot use both 'callback' and 'command'",
- pcall_err(api.nvim_create_autocmd, 'BufReadPost', {
- pattern = '*.py,*.pyi',
- command = "echo 'Should Have Errored",
- callback = 'NotAllowed',
- })
- )
- eq(
- "Cannot use both 'pattern' and 'buffer' for the same autocmd",
- pcall_err(api.nvim_create_autocmd, 'FileType', {
- command = 'let g:called = g:called + 1',
- buffer = 0,
- pattern = '*.py',
- })
- )
- eq(
- "Required: 'event'",
- pcall_err(api.nvim_create_autocmd, {}, {
- command = 'ls',
- })
- )
- eq("Required: 'command' or 'callback'", pcall_err(api.nvim_create_autocmd, 'FileType', {}))
- eq(
- "Invalid 'desc': expected String, got Integer",
- pcall_err(api.nvim_create_autocmd, 'FileType', {
- command = 'ls',
- desc = 42,
- })
- )
- eq(
- "Invalid 'callback': expected Lua function or Vim function name, got Integer",
- pcall_err(api.nvim_create_autocmd, 'FileType', {
- callback = 0,
- })
- )
- eq(
- "Invalid 'event' item: expected String, got Array",
- pcall_err(api.nvim_create_autocmd, { 'FileType', {} }, {})
- )
- eq(
- "Invalid 'group': 0",
- pcall_err(api.nvim_create_autocmd, 'FileType', {
- group = 0,
- command = 'ls',
- })
- )
- eq("Invalid 'event': 'foo'", pcall_err(api.nvim_create_autocmd, 'foo', { command = '' }))
- eq(
- "Invalid 'event': 'VimEnter '",
- pcall_err(api.nvim_create_autocmd, 'VimEnter ', { command = '' })
- )
- eq(
- "Invalid 'event': 'VimEnter foo'",
- pcall_err(api.nvim_create_autocmd, 'VimEnter foo', { command = '' })
- )
- eq(
- "Invalid 'event': 'BufAdd,BufDelete'",
- pcall_err(api.nvim_create_autocmd, 'BufAdd,BufDelete', { command = '' })
- )
- end)
- it('doesnt leak when you use ++once', function()
- eq(
- 1,
- exec_lua(
- [[
- local count = 0
- vim.api.nvim_create_autocmd("FileType", {
- pattern = "*",
- callback = function() count = count + 1 end,
- once = true
- })
- vim.cmd "set filetype=txt"
- vim.cmd "set filetype=python"
- return count
- ]],
- {}
- )
- )
- end)
- it('allows passing buffer by key', function()
- api.nvim_set_var('called', 0)
- api.nvim_create_autocmd('FileType', {
- command = 'let g:called = g:called + 1',
- buffer = 0,
- })
- command 'set filetype=txt'
- eq(1, api.nvim_get_var('called'))
- -- switch to a new buffer
- command 'new'
- command 'set filetype=python'
- eq(1, api.nvim_get_var('called'))
- end)
- it('does not allow passing invalid buffers', function()
- local ok, msg = pcall(api.nvim_create_autocmd, 'FileType', {
- command = 'let g:called = g:called + 1',
- buffer = -1,
- })
- eq(false, ok)
- matches('Invalid buffer id', msg)
- end)
- it('errors on non-functions for cb', function()
- eq(
- false,
- pcall(
- exec_lua,
- [[
- vim.api.nvim_create_autocmd("BufReadPost", {
- pattern = "*.py,*.pyi",
- callback = 5,
- })
- ]]
- )
- )
- end)
- it('allow passing pattern and <buffer> in same pattern', function()
- local ok = pcall(api.nvim_create_autocmd, 'BufReadPost', {
- pattern = '*.py,<buffer>',
- command = "echo 'Should Not Error'",
- })
- eq(true, ok)
- end)
- it('should handle multiple values as comma separated list', function()
- api.nvim_create_autocmd('BufReadPost', {
- pattern = '*.py,*.pyi',
- command = "echo 'Should Not Have Errored'",
- })
- -- We should have one autocmd for *.py and one for *.pyi
- eq(2, #api.nvim_get_autocmds { event = 'BufReadPost' })
- end)
- it('should handle multiple values as array', function()
- api.nvim_create_autocmd('BufReadPost', {
- pattern = { '*.py', '*.pyi' },
- command = "echo 'Should Not Have Errored'",
- })
- -- We should have one autocmd for *.py and one for *.pyi
- eq(2, #api.nvim_get_autocmds { event = 'BufReadPost' })
- end)
- describe('desc', function()
- it('can add description to one autocmd', function()
- local cmd = "echo 'Should Not Have Errored'"
- local desc = 'Can show description'
- api.nvim_create_autocmd('BufReadPost', {
- pattern = '*.py',
- command = cmd,
- desc = desc,
- })
- eq(desc, api.nvim_get_autocmds { event = 'BufReadPost' }[1].desc)
- eq(cmd, api.nvim_get_autocmds { event = 'BufReadPost' }[1].command)
- end)
- it('can add description to one autocmd that uses a callback', function()
- local desc = 'Can show description'
- api.nvim_set_var('desc', desc)
- local result = exec_lua([[
- local callback = function() print 'Should Not Have Errored' end
- vim.api.nvim_create_autocmd("BufReadPost", {
- pattern = "*.py",
- callback = callback,
- desc = vim.g.desc,
- })
- local aus = vim.api.nvim_get_autocmds({ event = 'BufReadPost' })
- local first = aus[1]
- return {
- desc = first.desc,
- cbtype = type(first.callback)
- }
- ]])
- eq({ desc = desc, cbtype = 'function' }, result)
- end)
- it('will not add a description unless it was provided', function()
- exec_lua([[
- local callback = function() print 'Should Not Have Errored' end
- vim.api.nvim_create_autocmd("BufReadPost", {
- pattern = "*.py",
- callback = callback,
- })
- ]])
- eq(nil, api.nvim_get_autocmds({ event = 'BufReadPost' })[1].desc)
- end)
- it('can add description to multiple autocmd', function()
- api.nvim_create_autocmd('BufReadPost', {
- pattern = { '*.py', '*.pyi' },
- command = "echo 'Should Not Have Errored'",
- desc = 'Can show description',
- })
- local aus = api.nvim_get_autocmds { event = 'BufReadPost' }
- eq(2, #aus)
- eq('Can show description', aus[1].desc)
- eq('Can show description', aus[2].desc)
- end)
- end)
- pending('script and verbose settings', function()
- it('marks API client', function()
- api.nvim_create_autocmd('BufReadPost', {
- pattern = '*.py',
- command = "echo 'Should Not Have Errored'",
- desc = 'Can show description',
- })
- local aus = api.nvim_get_autocmds { event = 'BufReadPost' }
- eq(1, #aus, aus)
- end)
- end)
- it('removes an autocommand if the callback returns true', function()
- api.nvim_set_var('some_condition', false)
- exec_lua [[
- vim.api.nvim_create_autocmd("User", {
- pattern = "Test",
- desc = "A test autocommand",
- callback = function()
- return vim.g.some_condition
- end,
- })
- ]]
- api.nvim_exec_autocmds('User', { pattern = 'Test' })
- local aus = api.nvim_get_autocmds({ event = 'User', pattern = 'Test' })
- local first = aus[1]
- eq(true, first.id > 0)
- api.nvim_set_var('some_condition', true)
- api.nvim_exec_autocmds('User', { pattern = 'Test' })
- eq({}, api.nvim_get_autocmds({ event = 'User', pattern = 'Test' }))
- end)
- it('receives an args table', function()
- local group_id = api.nvim_create_augroup('TestGroup', {})
- -- Having an existing autocmd calling expand("<afile>") shouldn't change args #18964
- api.nvim_create_autocmd('User', {
- group = 'TestGroup',
- pattern = 'Te*',
- command = 'call expand("<afile>")',
- })
- local autocmd_id = exec_lua [[
- return vim.api.nvim_create_autocmd("User", {
- group = "TestGroup",
- pattern = "Te*",
- callback = function(args)
- vim.g.autocmd_args = args
- end,
- })
- ]]
- api.nvim_exec_autocmds('User', { pattern = 'Test pattern' })
- eq({
- id = autocmd_id,
- group = group_id,
- event = 'User',
- match = 'Test pattern',
- file = 'Test pattern',
- buf = 1,
- }, api.nvim_get_var('autocmd_args'))
- -- Test without a group
- autocmd_id = exec_lua [[
- return vim.api.nvim_create_autocmd("User", {
- pattern = "*",
- callback = function(args)
- vim.g.autocmd_args = args
- end,
- })
- ]]
- api.nvim_exec_autocmds('User', { pattern = 'some_pat' })
- eq({
- id = autocmd_id,
- group = nil,
- event = 'User',
- match = 'some_pat',
- file = 'some_pat',
- buf = 1,
- }, api.nvim_get_var('autocmd_args'))
- end)
- it('can receive arbitrary data', function()
- local function test(data)
- eq(
- data,
- exec_lua(
- [[
- local input = ...
- local output
- vim.api.nvim_create_autocmd("User", {
- pattern = "Test",
- callback = function(args)
- output = args.data
- end,
- })
- vim.api.nvim_exec_autocmds("User", {
- pattern = "Test",
- data = input,
- })
- return output
- ]],
- data
- )
- )
- end
- test('Hello')
- test(42)
- test(true)
- test({ 'list' })
- test({ foo = 'bar' })
- end)
- it('function in arbitrary data is passed to all autocmds #28353', function()
- eq(
- 1303,
- exec_lua([[
- local res = 1
- local fun = function(m, x)
- res = res * m + x
- end
- local group = vim.api.nvim_create_augroup('MyTest', { clear = false })
- vim.api.nvim_create_autocmd('User', {
- group = group,
- callback = function(payload)
- payload.data.fun(10, payload.data.x)
- end,
- pattern = 'MyEvent',
- })
- vim.api.nvim_create_autocmd('User', {
- group = group,
- callback = function(payload)
- payload.data.fun(100, payload.data.x)
- end,
- pattern = 'MyEvent',
- })
- vim.api.nvim_exec_autocmds('User', {
- group = group,
- pattern = 'MyEvent',
- data = { x = 3, fun = fun },
- })
- return res
- ]])
- )
- end)
- end)
- describe('nvim_get_autocmds', function()
- it('validation', function()
- eq(
- "Invalid 'group': 9997999",
- pcall_err(api.nvim_get_autocmds, {
- group = 9997999,
- })
- )
- eq(
- "Invalid 'group': 'bogus'",
- pcall_err(api.nvim_get_autocmds, {
- group = 'bogus',
- })
- )
- eq(
- "Invalid 'group': 0",
- pcall_err(api.nvim_get_autocmds, {
- group = 0,
- })
- )
- eq(
- "Invalid 'group': expected String or Integer, got Array",
- pcall_err(api.nvim_get_autocmds, {
- group = {},
- })
- )
- eq(
- "Invalid 'buffer': expected Integer or Array, got Boolean",
- pcall_err(api.nvim_get_autocmds, {
- buffer = true,
- })
- )
- eq(
- "Invalid 'event': expected String or Array",
- pcall_err(api.nvim_get_autocmds, {
- event = true,
- })
- )
- eq(
- "Invalid 'pattern': expected String or Array, got Boolean",
- pcall_err(api.nvim_get_autocmds, {
- pattern = true,
- })
- )
- end)
- describe('events', function()
- it('returns one autocmd when there is only one for an event', function()
- command [[au! InsertEnter]]
- command [[au InsertEnter * :echo "1"]]
- local aus = api.nvim_get_autocmds { event = 'InsertEnter' }
- eq(1, #aus)
- end)
- it('returns two autocmds when there are two for an event', function()
- command [[au! InsertEnter]]
- command [[au InsertEnter * :echo "1"]]
- command [[au InsertEnter * :echo "2"]]
- local aus = api.nvim_get_autocmds { event = 'InsertEnter' }
- eq(2, #aus)
- end)
- it('returns the same thing if you use string or list', function()
- command [[au! InsertEnter]]
- command [[au InsertEnter * :echo "1"]]
- command [[au InsertEnter * :echo "2"]]
- local string_aus = api.nvim_get_autocmds { event = 'InsertEnter' }
- local array_aus = api.nvim_get_autocmds { event = { 'InsertEnter' } }
- eq(string_aus, array_aus)
- end)
- it('returns two autocmds when there are two for an event', function()
- command [[au! InsertEnter]]
- command [[au! InsertLeave]]
- command [[au InsertEnter * :echo "1"]]
- command [[au InsertEnter * :echo "2"]]
- local aus = api.nvim_get_autocmds { event = { 'InsertEnter', 'InsertLeave' } }
- eq(2, #aus)
- end)
- it('returns different IDs for different autocmds', function()
- command [[au! InsertEnter]]
- command [[au! InsertLeave]]
- command [[au InsertEnter * :echo "1"]]
- source [[
- call nvim_create_autocmd("InsertLeave", #{
- \ command: ":echo 2",
- \ })
- ]]
- local aus = api.nvim_get_autocmds { event = { 'InsertEnter', 'InsertLeave' } }
- local first = aus[1]
- eq(first.id, nil)
- -- TODO: Maybe don't have this number, just assert it's not nil
- local second = aus[2]
- neq(second.id, nil)
- api.nvim_del_autocmd(second.id)
- local new_aus = api.nvim_get_autocmds { event = { 'InsertEnter', 'InsertLeave' } }
- eq(1, #new_aus)
- eq(first, new_aus[1])
- end)
- it('returns event name', function()
- command [[au! InsertEnter]]
- command [[au InsertEnter * :echo "1"]]
- local aus = api.nvim_get_autocmds { event = 'InsertEnter' }
- eq({
- {
- buflocal = false,
- command = ':echo "1"',
- event = 'InsertEnter',
- once = false,
- pattern = '*',
- },
- }, aus)
- end)
- it('works with buffer numbers', function()
- command [[new]]
- command [[au! InsertEnter]]
- command [[au InsertEnter <buffer=1> :echo "1"]]
- command [[au InsertEnter <buffer=2> :echo "2"]]
- local aus = api.nvim_get_autocmds { event = 'InsertEnter', buffer = 0 }
- eq({
- {
- buffer = 2,
- buflocal = true,
- command = ':echo "2"',
- event = 'InsertEnter',
- once = false,
- pattern = '<buffer=2>',
- },
- }, aus)
- aus = api.nvim_get_autocmds { event = 'InsertEnter', buffer = 1 }
- eq({
- {
- buffer = 1,
- buflocal = true,
- command = ':echo "1"',
- event = 'InsertEnter',
- once = false,
- pattern = '<buffer=1>',
- },
- }, aus)
- aus = api.nvim_get_autocmds { event = 'InsertEnter', buffer = { 1, 2 } }
- eq({
- {
- buffer = 1,
- buflocal = true,
- command = ':echo "1"',
- event = 'InsertEnter',
- once = false,
- pattern = '<buffer=1>',
- },
- {
- buffer = 2,
- buflocal = true,
- command = ':echo "2"',
- event = 'InsertEnter',
- once = false,
- pattern = '<buffer=2>',
- },
- }, aus)
- eq(
- "Invalid 'buffer': expected Integer or Array, got String",
- pcall_err(api.nvim_get_autocmds, { event = 'InsertEnter', buffer = 'foo' })
- )
- eq(
- "Invalid 'buffer': expected Integer, got String",
- pcall_err(api.nvim_get_autocmds, { event = 'InsertEnter', buffer = { 'foo', 42 } })
- )
- eq(
- 'Invalid buffer id: 42',
- pcall_err(api.nvim_get_autocmds, { event = 'InsertEnter', buffer = { 42 } })
- )
- local bufs = {}
- for _ = 1, 257 do
- table.insert(bufs, api.nvim_create_buf(true, false))
- end
- eq(
- 'Too many buffers (maximum of 256)',
- pcall_err(api.nvim_get_autocmds, { event = 'InsertEnter', buffer = bufs })
- )
- end)
- it('returns autocmds when group is specified by id', function()
- local auid = api.nvim_create_augroup('nvim_test_augroup', { clear = true })
- api.nvim_create_autocmd('FileType', { group = auid, command = 'echo "1"' })
- api.nvim_create_autocmd('FileType', { group = auid, command = 'echo "2"' })
- local aus = api.nvim_get_autocmds { group = auid }
- eq(2, #aus)
- local aus2 = api.nvim_get_autocmds { group = auid, event = 'InsertEnter' }
- eq(0, #aus2)
- end)
- it('returns autocmds when group is specified by name', function()
- local auname = 'nvim_test_augroup'
- api.nvim_create_augroup(auname, { clear = true })
- api.nvim_create_autocmd('FileType', { group = auname, command = 'echo "1"' })
- api.nvim_create_autocmd('FileType', { group = auname, command = 'echo "2"' })
- local aus = api.nvim_get_autocmds { group = auname }
- eq(2, #aus)
- local aus2 = api.nvim_get_autocmds { group = auname, event = 'InsertEnter' }
- eq(0, #aus2)
- end)
- it('should respect nested', function()
- local bufs = exec_lua [[
- local count = 0
- vim.api.nvim_create_autocmd("BufNew", {
- once = false,
- nested = true,
- callback = function()
- count = count + 1
- if count > 5 then
- return true
- end
- vim.cmd(string.format("new README_%s.md", count))
- end
- })
- vim.cmd "new First.md"
- return vim.api.nvim_list_bufs()
- ]]
- -- 1 for the first buffer
- -- 2 for First.md
- -- 3-7 for the 5 we make in the autocmd
- eq({ 1, 2, 3, 4, 5, 6, 7 }, bufs)
- end)
- it('can retrieve a callback from an autocmd', function()
- local content = 'I Am A Callback'
- api.nvim_set_var('content', content)
- exec_lua([[
- local cb = function() return vim.g.content end
- vim.api.nvim_create_autocmd("User", {
- pattern = "TestTrigger",
- desc = "A test autocommand with a callback",
- callback = cb,
- })
- ]])
- local result = exec_lua([[
- local aus = vim.api.nvim_get_autocmds({ event = 'User', pattern = 'TestTrigger' })
- local first = aus[1]
- return {
- cb = {
- type = type(first.callback),
- can_retrieve = first.callback() == vim.g.content
- }
- }
- ]])
- eq({ cb = { type = 'function', can_retrieve = true } }, result)
- -- Also test with Vimscript
- source([[
- let s:aus = nvim_get_autocmds({'event': 'User', 'pattern': 'TestTrigger'})
- let g:result = s:aus[0].callback()
- ]])
- eq(content, api.nvim_get_var('result'))
- end)
- it(
- 'will return an empty string as the command for an autocmd that uses a callback',
- function()
- local result = exec_lua([[
- local callback = function() print 'I Am A Callback' end
- vim.api.nvim_create_autocmd("BufWritePost", {
- pattern = "*.py",
- callback = callback,
- })
- local aus = vim.api.nvim_get_autocmds({ event = 'BufWritePost' })
- local first = aus[1]
- return {
- command = first.command,
- cbtype = type(first.callback)
- }
- ]])
- eq({ command = '', cbtype = 'function' }, result)
- end
- )
- end)
- describe('groups', function()
- before_each(function()
- command [[au! InsertEnter]]
- command [[au InsertEnter * :echo "No Group"]]
- command [[augroup GroupOne]]
- command [[ au InsertEnter * :echo "GroupOne:1"]]
- command [[augroup END]]
- command [[augroup GroupTwo]]
- command [[ au InsertEnter * :echo "GroupTwo:2"]]
- command [[ au InsertEnter * :echo "GroupTwo:3"]]
- command [[augroup END]]
- end)
- it('returns all groups if no group is specified', function()
- local aus = api.nvim_get_autocmds { event = 'InsertEnter' }
- if #aus ~= 4 then
- eq({}, aus)
- end
- eq(4, #aus)
- end)
- it('returns only the group specified', function()
- local aus = api.nvim_get_autocmds {
- event = 'InsertEnter',
- group = 'GroupOne',
- }
- eq(1, #aus)
- eq([[:echo "GroupOne:1"]], aus[1].command)
- eq('GroupOne', aus[1].group_name)
- end)
- it('returns only the group specified, multiple values', function()
- local aus = api.nvim_get_autocmds {
- event = 'InsertEnter',
- group = 'GroupTwo',
- }
- eq(2, #aus)
- eq([[:echo "GroupTwo:2"]], aus[1].command)
- eq('GroupTwo', aus[1].group_name)
- eq([[:echo "GroupTwo:3"]], aus[2].command)
- eq('GroupTwo', aus[2].group_name)
- end)
- end)
- describe('groups: 2', function()
- it('raises error for undefined augroup name', function()
- local success, code = unpack(api.nvim_exec_lua(
- [[
- return {pcall(function()
- vim.api.nvim_create_autocmd("FileType", {
- pattern = "*",
- group = "NotDefined",
- command = "echo 'hello'",
- })
- end)}
- ]],
- {}
- ))
- eq(false, success)
- matches("Invalid 'group': 'NotDefined'", code)
- end)
- it('raises error for undefined augroup id', function()
- local success, code = unpack(api.nvim_exec_lua(
- [[
- return {pcall(function()
- -- Make sure the augroup is deleted
- vim.api.nvim_del_augroup_by_id(1)
- vim.api.nvim_create_autocmd("FileType", {
- pattern = "*",
- group = 1,
- command = "echo 'hello'",
- })
- end)}
- ]],
- {}
- ))
- eq(false, success)
- matches("Invalid 'group': 1", code)
- end)
- it('raises error for invalid group type', function()
- local success, code = unpack(api.nvim_exec_lua(
- [[
- return {pcall(function()
- vim.api.nvim_create_autocmd("FileType", {
- pattern = "*",
- group = true,
- command = "echo 'hello'",
- })
- end)}
- ]],
- {}
- ))
- eq(false, success)
- matches("Invalid 'group': expected String or Integer, got Boolean", code)
- end)
- it('raises error for invalid pattern array', function()
- local success, code = unpack(api.nvim_exec_lua(
- [[
- return {pcall(function()
- vim.api.nvim_create_autocmd("FileType", {
- pattern = {{}},
- command = "echo 'hello'",
- })
- end)}
- ]],
- {}
- ))
- eq(false, success)
- matches("Invalid 'pattern' item: expected String, got Array", code)
- end)
- end)
- describe('patterns', function()
- before_each(function()
- command [[au! InsertEnter]]
- command [[au InsertEnter * :echo "No Group"]]
- command [[au InsertEnter *.one :echo "GroupOne:1"]]
- command [[au InsertEnter *.two :echo "GroupTwo:2"]]
- command [[au InsertEnter *.two :echo "GroupTwo:3"]]
- command [[au InsertEnter <buffer> :echo "Buffer"]]
- end)
- it('returns for literal match', function()
- local aus = api.nvim_get_autocmds {
- event = 'InsertEnter',
- pattern = '*',
- }
- eq(1, #aus)
- eq([[:echo "No Group"]], aus[1].command)
- end)
- it('returns for multiple matches', function()
- -- vim.api.nvim_get_autocmds
- local aus = api.nvim_get_autocmds {
- event = 'InsertEnter',
- pattern = { '*.one', '*.two' },
- }
- eq(3, #aus)
- eq([[:echo "GroupOne:1"]], aus[1].command)
- eq([[:echo "GroupTwo:2"]], aus[2].command)
- eq([[:echo "GroupTwo:3"]], aus[3].command)
- end)
- it('should work for buffer autocmds', function()
- local normalized_aus = api.nvim_get_autocmds {
- event = 'InsertEnter',
- pattern = '<buffer=1>',
- }
- local raw_aus = api.nvim_get_autocmds {
- event = 'InsertEnter',
- pattern = '<buffer>',
- }
- local zero_aus = api.nvim_get_autocmds {
- event = 'InsertEnter',
- pattern = '<buffer=0>',
- }
- eq(normalized_aus, raw_aus)
- eq(normalized_aus, zero_aus)
- eq([[:echo "Buffer"]], normalized_aus[1].command)
- end)
- end)
- end)
- describe('nvim_exec_autocmds', function()
- it('validation', function()
- eq(
- "Invalid 'group': 9997999",
- pcall_err(api.nvim_exec_autocmds, 'FileType', {
- group = 9997999,
- })
- )
- eq(
- "Invalid 'group': 'bogus'",
- pcall_err(api.nvim_exec_autocmds, 'FileType', {
- group = 'bogus',
- })
- )
- eq(
- "Invalid 'group': expected String or Integer, got Array",
- pcall_err(api.nvim_exec_autocmds, 'FileType', {
- group = {},
- })
- )
- eq(
- "Invalid 'group': 0",
- pcall_err(api.nvim_exec_autocmds, 'FileType', {
- group = 0,
- })
- )
- eq(
- "Invalid 'buffer': expected Buffer, got Array",
- pcall_err(api.nvim_exec_autocmds, 'FileType', {
- buffer = {},
- })
- )
- eq(
- "Invalid 'event' item: expected String, got Array",
- pcall_err(api.nvim_exec_autocmds, { 'FileType', {} }, {})
- )
- end)
- it('can trigger builtin autocmds', function()
- api.nvim_set_var('autocmd_executed', false)
- api.nvim_create_autocmd('BufReadPost', {
- pattern = '*',
- command = 'let g:autocmd_executed = v:true',
- })
- eq(false, api.nvim_get_var('autocmd_executed'))
- api.nvim_exec_autocmds('BufReadPost', {})
- eq(true, api.nvim_get_var('autocmd_executed'))
- end)
- it('can trigger multiple patterns', function()
- api.nvim_set_var('autocmd_executed', 0)
- api.nvim_create_autocmd('BufReadPost', {
- pattern = '*',
- command = 'let g:autocmd_executed += 1',
- })
- api.nvim_exec_autocmds('BufReadPost', { pattern = { '*.lua', '*.vim' } })
- eq(2, api.nvim_get_var('autocmd_executed'))
- api.nvim_create_autocmd('BufReadPre', {
- pattern = { 'bar', 'foo' },
- command = 'let g:autocmd_executed += 10',
- })
- api.nvim_exec_autocmds('BufReadPre', { pattern = { 'foo', 'bar', 'baz', 'frederick' } })
- eq(22, api.nvim_get_var('autocmd_executed'))
- end)
- it('can pass the buffer', function()
- api.nvim_set_var('buffer_executed', -1)
- eq(-1, api.nvim_get_var('buffer_executed'))
- api.nvim_create_autocmd('BufLeave', {
- pattern = '*',
- command = 'let g:buffer_executed = +expand("<abuf>")',
- })
- -- Doesn't execute for other non-matching events
- api.nvim_exec_autocmds('CursorHold', { buffer = 1 })
- eq(-1, api.nvim_get_var('buffer_executed'))
- api.nvim_exec_autocmds('BufLeave', { buffer = 1 })
- eq(1, api.nvim_get_var('buffer_executed'))
- end)
- it('can pass the filename, pattern match', function()
- api.nvim_set_var('filename_executed', 'none')
- eq('none', api.nvim_get_var('filename_executed'))
- api.nvim_create_autocmd('BufEnter', {
- pattern = '*.py',
- command = 'let g:filename_executed = expand("<afile>")',
- })
- -- Doesn't execute for other non-matching events
- api.nvim_exec_autocmds('CursorHold', { buffer = 1 })
- eq('none', api.nvim_get_var('filename_executed'))
- command('edit __init__.py')
- eq('__init__.py', api.nvim_get_var('filename_executed'))
- end)
- it('cannot pass buf and fname', function()
- local ok = pcall(
- api.nvim_exec_autocmds,
- 'BufReadPre',
- { pattern = 'literally_cannot_error.rs', buffer = 1 }
- )
- eq(false, ok)
- end)
- it('can pass the filename, exact match', function()
- api.nvim_set_var('filename_executed', 'none')
- eq('none', api.nvim_get_var('filename_executed'))
- command('edit other_file.txt')
- command('edit __init__.py')
- eq('none', api.nvim_get_var('filename_executed'))
- api.nvim_create_autocmd('CursorHoldI', {
- pattern = '__init__.py',
- command = 'let g:filename_executed = expand("<afile>")',
- })
- -- Doesn't execute for other non-matching events
- api.nvim_exec_autocmds('CursorHoldI', { buffer = 1 })
- eq('none', api.nvim_get_var('filename_executed'))
- api.nvim_exec_autocmds('CursorHoldI', { buffer = api.nvim_get_current_buf() })
- eq('__init__.py', api.nvim_get_var('filename_executed'))
- -- Reset filename
- api.nvim_set_var('filename_executed', 'none')
- api.nvim_exec_autocmds('CursorHoldI', { pattern = '__init__.py' })
- eq('__init__.py', api.nvim_get_var('filename_executed'))
- end)
- it('works with user autocmds', function()
- api.nvim_set_var('matched', 'none')
- api.nvim_create_autocmd('User', {
- pattern = 'TestCommand',
- command = 'let g:matched = "matched"',
- })
- api.nvim_exec_autocmds('User', { pattern = 'OtherCommand' })
- eq('none', api.nvim_get_var('matched'))
- api.nvim_exec_autocmds('User', { pattern = 'TestCommand' })
- eq('matched', api.nvim_get_var('matched'))
- end)
- it('can pass group by id', function()
- api.nvim_set_var('group_executed', false)
- local auid = api.nvim_create_augroup('nvim_test_augroup', { clear = true })
- api.nvim_create_autocmd('FileType', {
- group = auid,
- command = 'let g:group_executed = v:true',
- })
- eq(false, api.nvim_get_var('group_executed'))
- api.nvim_exec_autocmds('FileType', { group = auid })
- eq(true, api.nvim_get_var('group_executed'))
- end)
- it('can pass group by name', function()
- api.nvim_set_var('group_executed', false)
- local auname = 'nvim_test_augroup'
- api.nvim_create_augroup(auname, { clear = true })
- api.nvim_create_autocmd('FileType', {
- group = auname,
- command = 'let g:group_executed = v:true',
- })
- eq(false, api.nvim_get_var('group_executed'))
- api.nvim_exec_autocmds('FileType', { group = auname })
- eq(true, api.nvim_get_var('group_executed'))
- end)
- end)
- describe('nvim_create_augroup', function()
- before_each(function()
- clear()
- api.nvim_set_var('executed', 0)
- end)
- local make_counting_autocmd = function(opts)
- opts = opts or {}
- local resulting = {
- pattern = '*',
- command = 'let g:executed = g:executed + 1',
- }
- resulting.group = opts.group
- resulting.once = opts.once
- api.nvim_create_autocmd('FileType', resulting)
- end
- local set_ft = function(ft)
- ft = ft or 'txt'
- source(string.format('set filetype=%s', ft))
- end
- local get_executed_count = function()
- return api.nvim_get_var('executed')
- end
- it('can be added in a group', function()
- local augroup = 'TestGroup'
- api.nvim_create_augroup(augroup, { clear = true })
- make_counting_autocmd { group = augroup }
- set_ft('txt')
- set_ft('python')
- eq(2, get_executed_count())
- end)
- it('works getting called multiple times', function()
- make_counting_autocmd()
- set_ft()
- set_ft()
- set_ft()
- eq(3, get_executed_count())
- end)
- it('handles ++once', function()
- make_counting_autocmd { once = true }
- set_ft('txt')
- set_ft('help')
- set_ft('txt')
- set_ft('help')
- eq(1, get_executed_count())
- end)
- it('errors on unexpected keys', function()
- local success, code = pcall(api.nvim_create_autocmd, 'FileType', {
- pattern = '*',
- not_a_valid_key = 'NotDefined',
- })
- eq(false, success)
- matches('not_a_valid_key', code)
- end)
- it('can execute simple callback', function()
- exec_lua(
- [[
- vim.g.executed = false
- vim.api.nvim_create_autocmd("FileType", {
- pattern = "*",
- callback = function() vim.g.executed = true end,
- })
- ]],
- {}
- )
- eq(
- true,
- exec_lua(
- [[
- vim.cmd "set filetype=txt"
- return vim.g.executed
- ]],
- {}
- )
- )
- end)
- it('calls multiple lua callbacks for the same autocmd execution', function()
- eq(
- 4,
- exec_lua(
- [[
- local count = 0
- local counter = function()
- count = count + 1
- end
- vim.api.nvim_create_autocmd("FileType", {
- pattern = "*",
- callback = counter,
- })
- vim.api.nvim_create_autocmd("FileType", {
- pattern = "*",
- callback = counter,
- })
- vim.cmd "set filetype=txt"
- vim.cmd "set filetype=txt"
- return count
- ]],
- {}
- )
- )
- end)
- it('properly releases functions with ++once', function()
- exec_lua([[
- WeakTable = setmetatable({}, { __mode = "k" })
- OnceCount = 0
- MyVal = {}
- WeakTable[MyVal] = true
- vim.api.nvim_create_autocmd("FileType", {
- pattern = "*",
- callback = function()
- OnceCount = OnceCount + 1
- MyVal = {}
- end,
- once = true
- })
- ]])
- command [[set filetype=txt]]
- eq(1, exec_lua([[return OnceCount]], {}))
- exec_lua([[collectgarbage()]], {})
- command [[set filetype=txt]]
- eq(1, exec_lua([[return OnceCount]], {}))
- eq(
- 0,
- exec_lua([[
- local count = 0
- for _ in pairs(WeakTable) do
- count = count + 1
- end
- return count
- ]]),
- 'Should have no keys remaining'
- )
- end)
- it('groups can be cleared', function()
- local augroup = 'TestGroup'
- api.nvim_create_augroup(augroup, { clear = true })
- api.nvim_create_autocmd('FileType', {
- group = augroup,
- command = 'let g:executed = g:executed + 1',
- })
- set_ft('txt')
- set_ft('txt')
- eq(2, get_executed_count(), 'should only count twice')
- api.nvim_create_augroup(augroup, { clear = true })
- eq({}, api.nvim_get_autocmds { group = augroup })
- set_ft('txt')
- set_ft('txt')
- eq(2, get_executed_count(), 'No additional counts')
- end)
- it('can delete non-existent groups with pcall', function()
- eq(false, exec_lua [[return pcall(vim.api.nvim_del_augroup_by_name, 'noexist')]])
- eq('Vim:E367: No such group: "noexist"', pcall_err(api.nvim_del_augroup_by_name, 'noexist'))
- eq(false, exec_lua [[return pcall(vim.api.nvim_del_augroup_by_id, -12342)]])
- eq('Vim:E367: No such group: "--Deleted--"', pcall_err(api.nvim_del_augroup_by_id, -12312))
- eq(false, exec_lua [[return pcall(vim.api.nvim_del_augroup_by_id, 0)]])
- eq('Vim:E367: No such group: "[NULL]"', pcall_err(api.nvim_del_augroup_by_id, 0))
- eq(false, exec_lua [[return pcall(vim.api.nvim_del_augroup_by_id, 12342)]])
- eq('Vim:E367: No such group: "[NULL]"', pcall_err(api.nvim_del_augroup_by_id, 12312))
- end)
- it('groups work with once', function()
- local augroup = 'TestGroup'
- api.nvim_create_augroup(augroup, { clear = true })
- make_counting_autocmd { group = augroup, once = true }
- set_ft('txt')
- set_ft('python')
- eq(1, get_executed_count())
- end)
- it('autocmds can be registered multiple times.', function()
- local augroup = 'TestGroup'
- api.nvim_create_augroup(augroup, { clear = true })
- make_counting_autocmd { group = augroup, once = false }
- make_counting_autocmd { group = augroup, once = false }
- make_counting_autocmd { group = augroup, once = false }
- set_ft('txt')
- set_ft('python')
- eq(3 * 2, get_executed_count())
- end)
- it('can be deleted', function()
- local augroup = 'WillBeDeleted'
- api.nvim_create_augroup(augroup, { clear = true })
- api.nvim_create_autocmd({ 'FileType' }, {
- pattern = '*',
- command = "echo 'does not matter'",
- })
- -- Clears the augroup from before, which erases the autocmd
- api.nvim_create_augroup(augroup, { clear = true })
- local result = #api.nvim_get_autocmds { group = augroup }
- eq(0, result)
- end)
- it('can be used for buffer local autocmds', function()
- local augroup = 'WillBeDeleted'
- api.nvim_set_var('value_set', false)
- api.nvim_create_augroup(augroup, { clear = true })
- api.nvim_create_autocmd('FileType', {
- pattern = '<buffer>',
- command = 'let g:value_set = v:true',
- })
- command 'new'
- command 'set filetype=python'
- eq(false, api.nvim_get_var('value_set'))
- end)
- it('can accept vimscript functions', function()
- source [[
- let g:vimscript_executed = 0
- function! MyVimscriptFunction() abort
- let g:vimscript_executed = g:vimscript_executed + 1
- endfunction
- call nvim_create_autocmd("FileType", #{
- \ pattern: ["python", "javascript"],
- \ callback: "MyVimscriptFunction",
- \ })
- set filetype=txt
- set filetype=python
- set filetype=txt
- set filetype=javascript
- set filetype=txt
- ]]
- eq(2, api.nvim_get_var('vimscript_executed'))
- end)
- end)
- describe('augroup!', function()
- it('legacy: should clear and not return any autocmds for delete groups', function()
- command('augroup TEMP_A')
- command(' autocmd! BufReadPost *.py :echo "Hello"')
- command('augroup END')
- command('augroup! TEMP_A')
- eq(false, pcall(api.nvim_get_autocmds, { group = 'TEMP_A' }))
- -- For some reason, augroup! doesn't clear the autocmds themselves, which is just wild
- -- but we managed to keep this behavior.
- eq(1, #api.nvim_get_autocmds { event = 'BufReadPost' })
- end)
- it('legacy: remove augroups that have no autocmds', function()
- command('augroup TEMP_AB')
- command('augroup END')
- command('augroup! TEMP_AB')
- eq(false, pcall(api.nvim_get_autocmds, { group = 'TEMP_AB' }))
- eq(0, #api.nvim_get_autocmds { event = 'BufReadPost' })
- end)
- it('legacy: multiple remove and add augroup', function()
- command('augroup TEMP_ABC')
- command(' au!')
- command(' autocmd BufReadPost *.py echo "Hello"')
- command('augroup END')
- command('augroup! TEMP_ABC')
- -- Should still have one autocmd :'(
- local aus = api.nvim_get_autocmds { event = 'BufReadPost' }
- eq(1, #aus, aus)
- command('augroup TEMP_ABC')
- command(' au!')
- command(' autocmd BufReadPost *.py echo "Hello"')
- command('augroup END')
- -- Should now have two autocmds :'(
- aus = api.nvim_get_autocmds { event = 'BufReadPost' }
- eq(2, #aus, aus)
- command('augroup! TEMP_ABC')
- eq(false, pcall(api.nvim_get_autocmds, { group = 'TEMP_ABC' }))
- eq(2, #api.nvim_get_autocmds { event = 'BufReadPost' })
- end)
- it('api: should clear and not return any autocmds for delete groups by id', function()
- command('augroup TEMP_ABCD')
- command('autocmd! BufReadPost *.py :echo "Hello"')
- command('augroup END')
- local augroup_id = api.nvim_create_augroup('TEMP_ABCD', { clear = false })
- api.nvim_del_augroup_by_id(augroup_id)
- -- For good reason, we kill all the autocmds from del_augroup,
- -- so now this works as expected
- eq(false, pcall(api.nvim_get_autocmds, { group = 'TEMP_ABCD' }))
- eq(0, #api.nvim_get_autocmds { event = 'BufReadPost' })
- end)
- it('api: should clear and not return any autocmds for delete groups by name', function()
- command('augroup TEMP_ABCDE')
- command('autocmd! BufReadPost *.py :echo "Hello"')
- command('augroup END')
- api.nvim_del_augroup_by_name('TEMP_ABCDE')
- -- For good reason, we kill all the autocmds from del_augroup,
- -- so now this works as expected
- eq(false, pcall(api.nvim_get_autocmds, { group = 'TEMP_ABCDE' }))
- eq(0, #api.nvim_get_autocmds { event = 'BufReadPost' })
- end)
- end)
- describe('nvim_clear_autocmds', function()
- it('validation', function()
- eq(
- "Cannot use both 'pattern' and 'buffer'",
- pcall_err(api.nvim_clear_autocmds, {
- pattern = '*',
- buffer = 42,
- })
- )
- eq(
- "Invalid 'event' item: expected String, got Array",
- pcall_err(api.nvim_clear_autocmds, {
- event = { 'FileType', {} },
- })
- )
- eq("Invalid 'group': 0", pcall_err(api.nvim_clear_autocmds, { group = 0 }))
- end)
- it('should clear based on event + pattern', function()
- command('autocmd InsertEnter *.py :echo "Python can be cool sometimes"')
- command('autocmd InsertEnter *.txt :echo "Text Files Are Cool"')
- local search = { event = 'InsertEnter', pattern = '*.txt' }
- local before_delete = api.nvim_get_autocmds(search)
- eq(1, #before_delete)
- local before_delete_all = api.nvim_get_autocmds { event = search.event }
- eq(2, #before_delete_all)
- api.nvim_clear_autocmds(search)
- local after_delete = api.nvim_get_autocmds(search)
- eq(0, #after_delete)
- local after_delete_all = api.nvim_get_autocmds { event = search.event }
- eq(1, #after_delete_all)
- end)
- it('should clear based on event', function()
- command('autocmd InsertEnter *.py :echo "Python can be cool sometimes"')
- command('autocmd InsertEnter *.txt :echo "Text Files Are Cool"')
- local search = { event = 'InsertEnter' }
- local before_delete = api.nvim_get_autocmds(search)
- eq(2, #before_delete)
- api.nvim_clear_autocmds(search)
- local after_delete = api.nvim_get_autocmds(search)
- eq(0, #after_delete)
- end)
- it('should clear based on pattern', function()
- command('autocmd InsertEnter *.TestPat1 :echo "Enter 1"')
- command('autocmd InsertLeave *.TestPat1 :echo "Leave 1"')
- command('autocmd InsertEnter *.TestPat2 :echo "Enter 2"')
- command('autocmd InsertLeave *.TestPat2 :echo "Leave 2"')
- local search = { pattern = '*.TestPat1' }
- local before_delete = api.nvim_get_autocmds(search)
- eq(2, #before_delete)
- local before_delete_events =
- api.nvim_get_autocmds { event = { 'InsertEnter', 'InsertLeave' } }
- eq(4, #before_delete_events)
- api.nvim_clear_autocmds(search)
- local after_delete = api.nvim_get_autocmds(search)
- eq(0, #after_delete)
- local after_delete_events = api.nvim_get_autocmds { event = { 'InsertEnter', 'InsertLeave' } }
- eq(2, #after_delete_events)
- end)
- it('should allow clearing by buffer', function()
- command('autocmd! InsertEnter')
- command('autocmd InsertEnter <buffer> :echo "Enter Buffer"')
- command('autocmd InsertEnter *.TestPat1 :echo "Enter Pattern"')
- local search = { event = 'InsertEnter' }
- local before_delete = api.nvim_get_autocmds(search)
- eq(2, #before_delete)
- api.nvim_clear_autocmds { buffer = 0 }
- local after_delete = api.nvim_get_autocmds(search)
- eq(1, #after_delete)
- eq('*.TestPat1', after_delete[1].pattern)
- end)
- it('should allow clearing by buffer and group', function()
- command('augroup TestNvimClearAutocmds')
- command(' au!')
- command(' autocmd InsertEnter <buffer> :echo "Enter Buffer"')
- command(' autocmd InsertEnter *.TestPat1 :echo "Enter Pattern"')
- command('augroup END')
- local search = { event = 'InsertEnter', group = 'TestNvimClearAutocmds' }
- local before_delete = api.nvim_get_autocmds(search)
- eq(2, #before_delete)
- -- Doesn't clear without passing group.
- api.nvim_clear_autocmds { buffer = 0 }
- local without_group = api.nvim_get_autocmds(search)
- eq(2, #without_group)
- -- Doesn't clear with passing group.
- api.nvim_clear_autocmds { buffer = 0, group = search.group }
- local with_group = api.nvim_get_autocmds(search)
- eq(1, #with_group)
- end)
- end)
- end)
|