2023-09-27 03:51:40 -07:00
|
|
|
local helpers = require('test.functional.helpers')(after_each)
|
|
|
|
local clear = helpers.clear
|
|
|
|
local exec = helpers.exec
|
|
|
|
local command = helpers.command
|
|
|
|
local feed = helpers.feed
|
|
|
|
local eq = helpers.eq
|
2023-10-27 19:42:18 -07:00
|
|
|
local neq = helpers.neq
|
2023-09-27 03:51:40 -07:00
|
|
|
local eval = helpers.eval
|
|
|
|
local poke_eventloop = helpers.poke_eventloop
|
|
|
|
|
|
|
|
before_each(clear)
|
|
|
|
|
|
|
|
-- oldtest: Test_ChangedP()
|
|
|
|
it('TextChangedI and TextChangedP autocommands', function()
|
|
|
|
-- The oldtest uses feedkeys() with 'x' flag, which never triggers TextChanged.
|
|
|
|
-- So don't add TextChanged autocommand here.
|
|
|
|
exec([[
|
|
|
|
call setline(1, ['foo', 'bar', 'foobar'])
|
|
|
|
set complete=. completeopt=menuone
|
|
|
|
au! TextChangedI <buffer> let g:autocmd ..= 'I'
|
|
|
|
au! TextChangedP <buffer> let g:autocmd ..= 'P'
|
|
|
|
call cursor(3, 1)
|
|
|
|
]])
|
|
|
|
|
|
|
|
command([[let g:autocmd = '']])
|
|
|
|
feed('o')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('<esc>')
|
2023-10-15 02:14:18 -07:00
|
|
|
-- TextChangedI triggers only if text is actually changed in Insert mode
|
2023-10-27 19:42:18 -07:00
|
|
|
eq('I', eval('g:autocmd'))
|
2023-09-27 03:51:40 -07:00
|
|
|
|
|
|
|
command([[let g:autocmd = '']])
|
|
|
|
feed('S')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('f')
|
|
|
|
poke_eventloop()
|
2023-10-27 19:42:18 -07:00
|
|
|
eq('II', eval('g:autocmd'))
|
2023-09-27 03:51:40 -07:00
|
|
|
feed('<esc>')
|
|
|
|
|
|
|
|
command([[let g:autocmd = '']])
|
|
|
|
feed('S')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('f')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('<C-N>')
|
|
|
|
poke_eventloop()
|
2023-10-27 19:42:18 -07:00
|
|
|
eq('IIP', eval('g:autocmd'))
|
2023-09-27 03:51:40 -07:00
|
|
|
feed('<esc>')
|
|
|
|
|
|
|
|
command([[let g:autocmd = '']])
|
|
|
|
feed('S')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('f')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('<C-N>')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('<C-N>')
|
|
|
|
poke_eventloop()
|
2023-10-27 19:42:18 -07:00
|
|
|
eq('IIPP', eval('g:autocmd'))
|
2023-09-27 03:51:40 -07:00
|
|
|
feed('<esc>')
|
|
|
|
|
|
|
|
command([[let g:autocmd = '']])
|
|
|
|
feed('S')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('f')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('<C-N>')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('<C-N>')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('<C-N>')
|
|
|
|
poke_eventloop()
|
2023-10-27 19:42:18 -07:00
|
|
|
eq('IIPPP', eval('g:autocmd'))
|
2023-09-27 03:51:40 -07:00
|
|
|
feed('<esc>')
|
|
|
|
|
|
|
|
command([[let g:autocmd = '']])
|
|
|
|
feed('S')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('f')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('<C-N>')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('<C-N>')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('<C-N>')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('<C-N>')
|
2023-10-27 19:42:18 -07:00
|
|
|
eq('IIPPPP', eval('g:autocmd'))
|
2023-09-27 03:51:40 -07:00
|
|
|
feed('<esc>')
|
|
|
|
|
2024-01-02 18:09:18 -07:00
|
|
|
eq({ 'foo', 'bar', 'foobar', 'foo' }, eval('getline(1, "$")'))
|
2023-09-27 03:51:40 -07:00
|
|
|
end)
|
|
|
|
|
|
|
|
-- oldtest: Test_TextChangedI_with_setline()
|
|
|
|
it('TextChangedI with setline()', function()
|
|
|
|
exec([[
|
|
|
|
let g:setline_handled = v:false
|
|
|
|
func SetLineOne()
|
|
|
|
if !g:setline_handled
|
|
|
|
call setline(1, "(x)")
|
|
|
|
let g:setline_handled = v:true
|
|
|
|
endif
|
|
|
|
endfunc
|
|
|
|
autocmd TextChangedI <buffer> call SetLineOne()
|
|
|
|
]])
|
|
|
|
|
|
|
|
feed('i')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('(')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('<CR>')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('<Esc>')
|
|
|
|
eq('(', eval('getline(1)'))
|
|
|
|
eq('x)', eval('getline(2)'))
|
|
|
|
command('undo')
|
|
|
|
eq('', eval('getline(1)'))
|
|
|
|
eq('', eval('getline(2)'))
|
|
|
|
end)
|
|
|
|
|
|
|
|
-- oldtest: Test_Changed_ChangedI()
|
2023-10-15 02:14:18 -07:00
|
|
|
it('TextChangedI and TextChanged', function()
|
2023-09-27 03:51:40 -07:00
|
|
|
exec([[
|
|
|
|
let [g:autocmd_i, g:autocmd_n] = ['','']
|
|
|
|
|
|
|
|
func! TextChangedAutocmdI(char)
|
|
|
|
let g:autocmd_{tolower(a:char)} = a:char .. b:changedtick
|
|
|
|
endfunc
|
|
|
|
|
|
|
|
augroup Test_TextChanged
|
|
|
|
au!
|
|
|
|
au TextChanged <buffer> :call TextChangedAutocmdI('N')
|
|
|
|
au TextChangedI <buffer> :call TextChangedAutocmdI('I')
|
|
|
|
augroup END
|
|
|
|
]])
|
|
|
|
|
|
|
|
feed('i')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('f')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('o')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('o')
|
|
|
|
poke_eventloop()
|
|
|
|
feed('<esc>')
|
2023-10-15 02:14:18 -07:00
|
|
|
eq('', eval('g:autocmd_n'))
|
2023-09-27 03:51:40 -07:00
|
|
|
eq('I5', eval('g:autocmd_i'))
|
|
|
|
|
2023-10-27 19:42:18 -07:00
|
|
|
feed('yyp')
|
2023-09-27 03:51:40 -07:00
|
|
|
eq('N6', eval('g:autocmd_n'))
|
|
|
|
eq('I5', eval('g:autocmd_i'))
|
2023-10-15 02:14:18 -07:00
|
|
|
|
|
|
|
-- TextChangedI should only trigger if change was done in Insert mode
|
|
|
|
command([[let g:autocmd_i = '']])
|
2023-10-27 19:42:18 -07:00
|
|
|
feed('yypi<esc>')
|
2023-10-15 02:14:18 -07:00
|
|
|
eq('', eval('g:autocmd_i'))
|
|
|
|
|
|
|
|
command([[let g:autocmd_n = '']])
|
2023-10-27 19:42:18 -07:00
|
|
|
feed('ibar<esc>')
|
2024-03-31 14:39:52 -07:00
|
|
|
eq('N8', eval('g:autocmd_n'))
|
2023-10-27 19:42:18 -07:00
|
|
|
|
|
|
|
local function validate_mixed_textchangedi(keys)
|
|
|
|
feed('ifoo<esc>')
|
|
|
|
command([[let g:autocmd_i = '']])
|
|
|
|
command([[let g:autocmd_n = '']])
|
|
|
|
for _, s in ipairs(keys) do
|
|
|
|
feed(s)
|
|
|
|
poke_eventloop()
|
|
|
|
end
|
|
|
|
neq('', eval('g:autocmd_i'))
|
|
|
|
eq('', eval('g:autocmd_n'))
|
|
|
|
end
|
|
|
|
|
2024-01-02 18:09:18 -07:00
|
|
|
validate_mixed_textchangedi({ 'o', '<esc>' })
|
|
|
|
validate_mixed_textchangedi({ 'O', '<esc>' })
|
|
|
|
validate_mixed_textchangedi({ 'ciw', '<esc>' })
|
|
|
|
validate_mixed_textchangedi({ 'cc', '<esc>' })
|
|
|
|
validate_mixed_textchangedi({ 'C', '<esc>' })
|
|
|
|
validate_mixed_textchangedi({ 's', '<esc>' })
|
|
|
|
validate_mixed_textchangedi({ 'S', '<esc>' })
|
2023-09-27 03:51:40 -07:00
|
|
|
end)
|
2024-02-09 15:53:26 -07:00
|
|
|
|
|
|
|
-- oldtest: Test_TextChanged_with_norm()
|
|
|
|
it('TextChanged is triggered after :norm that enters Insert mode', function()
|
|
|
|
exec([[
|
|
|
|
let g:a = 0
|
|
|
|
au TextChanged * let g:a += 1
|
|
|
|
]])
|
|
|
|
eq(0, eval('g:a'))
|
|
|
|
feed(':norm! ia<CR>')
|
|
|
|
eq(1, eval('g:a'))
|
|
|
|
end)
|
2024-03-31 14:39:52 -07:00
|
|
|
|
|
|
|
-- oldtest: Test_Changed_ChangedI_2()
|
|
|
|
it('TextChanged is triggered after mapping that enters & exits Insert mode', function()
|
|
|
|
exec([[
|
2024-04-01 06:49:44 -07:00
|
|
|
let [g:autocmd_n, g:autocmd_i] = ['','']
|
2024-03-31 14:39:52 -07:00
|
|
|
|
2024-04-01 06:49:44 -07:00
|
|
|
func TextChangedAutocmd(char)
|
2024-03-31 14:39:52 -07:00
|
|
|
let g:autocmd_{tolower(a:char)} = a:char .. b:changedtick
|
|
|
|
endfunc
|
|
|
|
|
2024-04-01 06:49:44 -07:00
|
|
|
au TextChanged <buffer> :call TextChangedAutocmd('N')
|
|
|
|
au TextChangedI <buffer> :call TextChangedAutocmd('I')
|
2024-03-31 14:39:52 -07:00
|
|
|
|
|
|
|
nnoremap <CR> o<Esc>
|
|
|
|
]])
|
|
|
|
|
|
|
|
feed('<CR>')
|
|
|
|
eq('N3', eval('g:autocmd_n'))
|
|
|
|
eq('', eval('g:autocmd_i'))
|
|
|
|
end)
|