blob: 43605f7e1111a1b7fa44a2936d6f8b72ba409e61 [file] [log] [blame]
Bram Moolenaar14735512016-03-26 21:00:08 +01001" Tests for autocommands
2
Christian Brabandteb380b92025-07-07 20:53:55 +02003source util/screendump.vim
4import './util/vim9.vim' as v9
Bram Moolenaar8c64a362018-03-23 22:39:31 +01005
Bram Moolenaar1e115362019-01-09 23:01:02 +01006func s:cleanup_buffers() abort
Bram Moolenaarb3435b02016-09-29 20:54:59 +02007 for bnr in range(1, bufnr('$'))
8 if bufloaded(bnr) && bufnr('%') != bnr
9 execute 'bd! ' . bnr
10 endif
11 endfor
Bram Moolenaar04f62f82017-07-19 18:18:39 +020012endfunc
Bram Moolenaarb3435b02016-09-29 20:54:59 +020013
Christian Brabandtfb3f9692024-08-11 20:09:17 +020014func CleanUpTestAuGroup()
15 augroup testing
16 au!
17 augroup END
18 augroup! testing
19endfunc
20
Bram Moolenaar14735512016-03-26 21:00:08 +010021func Test_vim_did_enter()
22 call assert_false(v:vim_did_enter)
23
24 " This script will never reach the main loop, can't check if v:vim_did_enter
25 " becomes one.
26endfunc
Bram Moolenaar40b1b542016-04-20 20:18:23 +020027
Bram Moolenaar75911162020-07-21 19:44:47 +020028" Test for the CursorHold autocmd
29func Test_CursorHold_autocmd()
30 CheckRunVimInTerminal
Bram Moolenaare1f3ab72022-09-04 21:29:08 +010031 call writefile(['one', 'two', 'three'], 'XoneTwoThree', 'D')
Bram Moolenaar75911162020-07-21 19:44:47 +020032 let before =<< trim END
33 set updatetime=10
Bram Moolenaare7cda972022-08-29 11:02:59 +010034 au CursorHold * call writefile([line('.')], 'XCHoutput', 'a')
Bram Moolenaar75911162020-07-21 19:44:47 +020035 END
Bram Moolenaare1f3ab72022-09-04 21:29:08 +010036 call writefile(before, 'XCHinit', 'D')
Bram Moolenaare7cda972022-08-29 11:02:59 +010037 let buf = RunVimInTerminal('-S XCHinit XoneTwoThree', {})
Bram Moolenaar17f67542020-08-20 18:29:13 +020038 call term_sendkeys(buf, "G")
Bram Moolenaar62cd26a2020-10-11 20:08:44 +020039 call term_wait(buf, 50)
Bram Moolenaar75911162020-07-21 19:44:47 +020040 call term_sendkeys(buf, "gg")
41 call term_wait(buf)
Bram Moolenaare7cda972022-08-29 11:02:59 +010042 call WaitForAssert({-> assert_equal(['1'], readfile('XCHoutput')[-1:-1])})
Bram Moolenaar75911162020-07-21 19:44:47 +020043 call term_sendkeys(buf, "j")
44 call term_wait(buf)
Bram Moolenaare7cda972022-08-29 11:02:59 +010045 call WaitForAssert({-> assert_equal(['1', '2'], readfile('XCHoutput')[-2:-1])})
Bram Moolenaar75911162020-07-21 19:44:47 +020046 call term_sendkeys(buf, "j")
47 call term_wait(buf)
Bram Moolenaare7cda972022-08-29 11:02:59 +010048 call WaitForAssert({-> assert_equal(['1', '2', '3'], readfile('XCHoutput')[-3:-1])})
Bram Moolenaar75911162020-07-21 19:44:47 +020049 call StopVimInTerminal(buf)
50
Bram Moolenaare7cda972022-08-29 11:02:59 +010051 call delete('XCHoutput')
Bram Moolenaar75911162020-07-21 19:44:47 +020052endfunc
53
Bram Moolenaarc67e8922016-05-24 16:07:40 +020054if has('timers')
Bram Moolenaar97b00752019-05-12 13:07:14 +020055
Bram Moolenaarc67e8922016-05-24 16:07:40 +020056 func ExitInsertMode(id)
57 call feedkeys("\<Esc>")
58 endfunc
59
60 func Test_cursorhold_insert()
zeertzjq657b31f2023-04-15 21:28:02 +010061 " depends on timing
62 let g:test_is_flaky = 1
63
Bram Moolenaarf18c4db2016-09-08 22:10:06 +020064 " Need to move the cursor.
65 call feedkeys("ggG", "xt")
66
Bram Moolenaarc67e8922016-05-24 16:07:40 +020067 let g:triggered = 0
68 au CursorHoldI * let g:triggered += 1
69 set updatetime=20
Bram Moolenaar92bb83e2021-02-03 23:04:46 +010070 call timer_start(200, 'ExitInsertMode')
Bram Moolenaarc67e8922016-05-24 16:07:40 +020071 call feedkeys('a', 'x!')
Bram Moolenaar3b014be2022-11-13 17:53:46 +000072 sleep 30m
Bram Moolenaarc67e8922016-05-24 16:07:40 +020073 call assert_equal(1, g:triggered)
Bram Moolenaar26d98212019-01-27 22:32:55 +010074 unlet g:triggered
75 au! CursorHoldI
76 set updatetime&
77 endfunc
78
79 func Test_cursorhold_insert_with_timer_interrupt()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +020080 CheckFeature job
Bram Moolenaar26d98212019-01-27 22:32:55 +010081 " Need to move the cursor.
82 call feedkeys("ggG", "xt")
83
84 " Confirm the timer invoked in exit_cb of the job doesn't disturb
85 " CursorHoldI event.
86 let g:triggered = 0
87 au CursorHoldI * let g:triggered += 1
Bram Moolenaar62cd26a2020-10-11 20:08:44 +020088 set updatetime=100
Milly4f5681d2024-10-20 11:06:00 +020089 call job_start(has('win32') ? 'cmd /D /c echo:' : 'echo',
Bram Moolenaar62cd26a2020-10-11 20:08:44 +020090 \ {'exit_cb': {-> timer_start(200, 'ExitInsertMode')}})
Bram Moolenaar26d98212019-01-27 22:32:55 +010091 call feedkeys('a', 'x!')
92 call assert_equal(1, g:triggered)
93 unlet g:triggered
Bram Moolenaare99e8442016-07-26 20:43:40 +020094 au! CursorHoldI
Bram Moolenaaraeac9002016-09-06 22:15:08 +020095 set updatetime&
Bram Moolenaarc67e8922016-05-24 16:07:40 +020096 endfunc
97
98 func Test_cursorhold_insert_ctrl_x()
99 let g:triggered = 0
100 au CursorHoldI * let g:triggered += 1
101 set updatetime=20
102 call timer_start(100, 'ExitInsertMode')
103 " CursorHoldI does not trigger after CTRL-X
104 call feedkeys("a\<C-X>", 'x!')
105 call assert_equal(0, g:triggered)
Bram Moolenaar26d98212019-01-27 22:32:55 +0100106 unlet g:triggered
Bram Moolenaare99e8442016-07-26 20:43:40 +0200107 au! CursorHoldI
Bram Moolenaaraeac9002016-09-06 22:15:08 +0200108 set updatetime&
Bram Moolenaarc67e8922016-05-24 16:07:40 +0200109 endfunc
Bram Moolenaar97b00752019-05-12 13:07:14 +0200110
Bram Moolenaar5a9357d2021-10-03 16:22:05 +0100111 func Test_cursorhold_insert_ctrl_g_U()
112 au CursorHoldI * :
113 set updatetime=20
114 new
115 call timer_start(100, { -> feedkeys("\<Left>foo\<Esc>", 't') })
116 call feedkeys("i()\<C-g>U", 'tx!')
117 sleep 200m
118 call assert_equal('(foo)', getline(1))
119 undo
120 call assert_equal('', getline(1))
121
122 bwipe!
123 au! CursorHoldI
124 set updatetime&
125 endfunc
126
Bram Moolenaar97b00752019-05-12 13:07:14 +0200127 func Test_OptionSet_modeline()
128 call test_override('starting', 1)
129 au! OptionSet
130 augroup set_tabstop
131 au OptionSet tabstop call timer_start(1, {-> execute("echo 'Handler called'", "")})
132 augroup END
Bram Moolenaare1f3ab72022-09-04 21:29:08 +0100133 call writefile(['vim: set ts=7 sw=5 :', 'something'], 'XoptionsetModeline', 'D')
Bram Moolenaar97b00752019-05-12 13:07:14 +0200134 set modeline
135 let v:errmsg = ''
136 call assert_fails('split XoptionsetModeline', 'E12:')
137 call assert_equal(7, &ts)
138 call assert_equal('', v:errmsg)
139
140 augroup set_tabstop
141 au!
142 augroup END
143 bwipe!
144 set ts&
Bram Moolenaar97b00752019-05-12 13:07:14 +0200145 call test_override('starting', 0)
146 endfunc
147
148endif "has('timers')
Bram Moolenaar40b1b542016-04-20 20:18:23 +0200149
Bram Moolenaar04f62f82017-07-19 18:18:39 +0200150func Test_bufunload()
Bram Moolenaarc67e8922016-05-24 16:07:40 +0200151 augroup test_bufunload_group
152 autocmd!
153 autocmd BufUnload * call add(s:li, "bufunload")
154 autocmd BufDelete * call add(s:li, "bufdelete")
155 autocmd BufWipeout * call add(s:li, "bufwipeout")
156 augroup END
Bram Moolenaar40b1b542016-04-20 20:18:23 +0200157
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +0100158 let s:li = []
Bram Moolenaarc67e8922016-05-24 16:07:40 +0200159 new
160 setlocal bufhidden=
161 bunload
162 call assert_equal(["bufunload", "bufdelete"], s:li)
Bram Moolenaar40b1b542016-04-20 20:18:23 +0200163
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +0100164 let s:li = []
Bram Moolenaarc67e8922016-05-24 16:07:40 +0200165 new
166 setlocal bufhidden=delete
167 bunload
168 call assert_equal(["bufunload", "bufdelete"], s:li)
169
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +0100170 let s:li = []
Bram Moolenaarc67e8922016-05-24 16:07:40 +0200171 new
172 setlocal bufhidden=unload
173 bwipeout
174 call assert_equal(["bufunload", "bufdelete", "bufwipeout"], s:li)
175
Bram Moolenaare99e8442016-07-26 20:43:40 +0200176 au! test_bufunload_group
Bram Moolenaarc67e8922016-05-24 16:07:40 +0200177 augroup! test_bufunload_group
Bram Moolenaar40b1b542016-04-20 20:18:23 +0200178endfunc
Bram Moolenaar30445cb2016-07-09 15:21:02 +0200179
180" SEGV occurs in older versions. (At least 7.4.2005 or older)
Bram Moolenaar04f62f82017-07-19 18:18:39 +0200181func Test_autocmd_bufunload_with_tabnext()
Bram Moolenaar30445cb2016-07-09 15:21:02 +0200182 tabedit
183 tabfirst
184
185 augroup test_autocmd_bufunload_with_tabnext_group
186 autocmd!
187 autocmd BufUnload <buffer> tabnext
188 augroup END
189
190 quit
191 call assert_equal(2, tabpagenr('$'))
192
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200193 autocmd! test_autocmd_bufunload_with_tabnext_group
Bram Moolenaar30445cb2016-07-09 15:21:02 +0200194 augroup! test_autocmd_bufunload_with_tabnext_group
195 tablast
196 quit
197endfunc
Bram Moolenaarc917da42016-07-19 22:31:36 +0200198
Bram Moolenaar5ed58c72021-01-28 14:24:55 +0100199func Test_argdelete_in_next()
200 au BufNew,BufEnter,BufLeave,BufWinEnter * argdel
201 call assert_fails('next a b', 'E1156:')
202 au! BufNew,BufEnter,BufLeave,BufWinEnter *
203endfunc
204
Bram Moolenaar04f62f82017-07-19 18:18:39 +0200205func Test_autocmd_bufwinleave_with_tabfirst()
Bram Moolenaarf9e687e2016-09-04 21:33:09 +0200206 tabedit
207 augroup sample
208 autocmd!
209 autocmd BufWinLeave <buffer> tabfirst
210 augroup END
211 call setline(1, ['a', 'b', 'c'])
212 edit! a.txt
Bram Moolenaarf18c4db2016-09-08 22:10:06 +0200213 tabclose
Bram Moolenaarf9e687e2016-09-04 21:33:09 +0200214endfunc
215
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200216" SEGV occurs in older versions. (At least 7.4.2321 or older)
Bram Moolenaar04f62f82017-07-19 18:18:39 +0200217func Test_autocmd_bufunload_avoiding_SEGV_01()
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200218 split aa.txt
219 let lastbuf = bufnr('$')
220
221 augroup test_autocmd_bufunload
222 autocmd!
223 exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!'
224 augroup END
225
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100226 call assert_fails('edit bb.txt', 'E937:')
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200227
228 autocmd! test_autocmd_bufunload
229 augroup! test_autocmd_bufunload
230 bwipe! aa.txt
231 bwipe! bb.txt
232endfunc
233
234" SEGV occurs in older versions. (At least 7.4.2321 or older)
Bram Moolenaar04f62f82017-07-19 18:18:39 +0200235func Test_autocmd_bufunload_avoiding_SEGV_02()
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200236 setlocal buftype=nowrite
237 let lastbuf = bufnr('$')
238
239 augroup test_autocmd_bufunload
240 autocmd!
241 exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!'
242 augroup END
243
244 normal! i1
245 call assert_fails('edit a.txt', 'E517:')
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200246
247 autocmd! test_autocmd_bufunload
248 augroup! test_autocmd_bufunload
249 bwipe! a.txt
250endfunc
251
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +0100252func Test_autocmd_dummy_wipeout()
253 " prepare files
Bram Moolenaare1f3ab72022-09-04 21:29:08 +0100254 call writefile([''], 'Xdummywipetest1.txt', 'D')
255 call writefile([''], 'Xdummywipetest2.txt', 'D')
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +0100256 augroup test_bufunload_group
257 autocmd!
258 autocmd BufUnload * call add(s:li, "bufunload")
259 autocmd BufDelete * call add(s:li, "bufdelete")
260 autocmd BufWipeout * call add(s:li, "bufwipeout")
261 augroup END
262
263 let s:li = []
264 split Xdummywipetest1.txt
265 silent! vimgrep /notmatched/ Xdummywipetest*
266 call assert_equal(["bufunload", "bufwipeout"], s:li)
267
268 bwipeout
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +0100269 au! test_bufunload_group
270 augroup! test_bufunload_group
271endfunc
272
Bram Moolenaarc917da42016-07-19 22:31:36 +0200273func Test_win_tab_autocmd()
274 let g:record = []
275
Christian Brabandtfb3f9692024-08-11 20:09:17 +0200276 defer CleanUpTestAuGroup()
Bram Moolenaarc917da42016-07-19 22:31:36 +0200277 augroup testing
Sergey Vlasov1f47db72024-01-25 23:07:00 +0100278 au WinNewPre * call add(g:record, 'WinNewPre')
Bram Moolenaarc917da42016-07-19 22:31:36 +0200279 au WinNew * call add(g:record, 'WinNew')
naohiro ono23beefe2021-11-13 12:38:49 +0000280 au WinClosed * call add(g:record, 'WinClosed')
Bram Moolenaar94722c52023-01-28 19:19:03 +0000281 au WinEnter * call add(g:record, 'WinEnter')
282 au WinLeave * call add(g:record, 'WinLeave')
Bram Moolenaarc917da42016-07-19 22:31:36 +0200283 au TabNew * call add(g:record, 'TabNew')
Bram Moolenaar12c11d52016-07-19 23:13:03 +0200284 au TabClosed * call add(g:record, 'TabClosed')
Bram Moolenaarc917da42016-07-19 22:31:36 +0200285 au TabEnter * call add(g:record, 'TabEnter')
286 au TabLeave * call add(g:record, 'TabLeave')
287 augroup END
288
289 split
290 tabnew
291 close
292 close
293
294 call assert_equal([
Sergey Vlasov1f47db72024-01-25 23:07:00 +0100295 \ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter',
Christian Brabandtfb3f9692024-08-11 20:09:17 +0200296 \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
naohiro ono23beefe2021-11-13 12:38:49 +0000297 \ 'WinLeave', 'TabLeave', 'WinClosed', 'TabClosed', 'WinEnter', 'TabEnter',
298 \ 'WinLeave', 'WinClosed', 'WinEnter'
Bram Moolenaarc917da42016-07-19 22:31:36 +0200299 \ ], g:record)
300
Bram Moolenaar12c11d52016-07-19 23:13:03 +0200301 let g:record = []
302 tabnew somefile
303 tabnext
304 bwipe somefile
305
306 call assert_equal([
Christian Brabandtfb3f9692024-08-11 20:09:17 +0200307 \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
Bram Moolenaar12c11d52016-07-19 23:13:03 +0200308 \ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter',
naohiro ono23beefe2021-11-13 12:38:49 +0000309 \ 'WinClosed', 'TabClosed'
Bram Moolenaar12c11d52016-07-19 23:13:03 +0200310 \ ], g:record)
311
Sergey Vlasov1f47db72024-01-25 23:07:00 +0100312 let g:record = []
313 copen
314 help
315 tabnext
316 vnew
317
318 call assert_equal([
319 \ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter',
320 \ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter',
321 \ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter'
322 \ ], g:record)
323
Bram Moolenaarc917da42016-07-19 22:31:36 +0200324 unlet g:record
325endfunc
Bram Moolenaare99e8442016-07-26 20:43:40 +0200326
Sergey Vlasov1f47db72024-01-25 23:07:00 +0100327func Test_WinNewPre()
328 " Test that the old window layout can be accessed before a new window is created.
329 let g:layouts_pre = []
330 let g:layouts_post = []
331 augroup testing
332 au WinNewPre * call add(g:layouts_pre, winlayout())
333 au WinNew * call add(g:layouts_post, winlayout())
334 augroup END
Christian Brabandtfb3f9692024-08-11 20:09:17 +0200335 defer CleanUpTestAuGroup()
Sergey Vlasov1f47db72024-01-25 23:07:00 +0100336 split
337 call assert_notequal(g:layouts_pre[0], g:layouts_post[0])
338 split
339 call assert_equal(g:layouts_pre[1], g:layouts_post[0])
340 call assert_notequal(g:layouts_pre[1], g:layouts_post[1])
Christian Brabandtfb3f9692024-08-11 20:09:17 +0200341 " not triggered for tabnew
Sergey Vlasov1f47db72024-01-25 23:07:00 +0100342 tabnew
Christian Brabandtfb3f9692024-08-11 20:09:17 +0200343 call assert_equal(2, len(g:layouts_pre))
Sergey Vlasov1f47db72024-01-25 23:07:00 +0100344 unlet g:layouts_pre
345 unlet g:layouts_post
346
347 " Test modifying window layout during WinNewPre throws.
348 let g:caught = 0
349 augroup testing
350 au!
351 au WinNewPre * split
352 augroup END
353 try
354 vnew
355 catch
356 let g:caught += 1
357 endtry
358 augroup testing
359 au!
360 au WinNewPre * tabnew
361 augroup END
362 try
363 vnew
364 catch
365 let g:caught += 1
366 endtry
367 augroup testing
368 au!
369 au WinNewPre * close
370 augroup END
371 try
372 vnew
373 catch
374 let g:caught += 1
375 endtry
376 augroup testing
377 au!
378 au WinNewPre * tabclose
379 augroup END
380 try
381 vnew
382 catch
383 let g:caught += 1
384 endtry
385 call assert_equal(4, g:caught)
Sergey Vlasov1f47db72024-01-25 23:07:00 +0100386 unlet g:caught
387endfunc
388
Bram Moolenaar35fc61c2022-11-22 12:40:50 +0000389func Test_WinResized()
390 CheckRunVimInTerminal
391
392 let lines =<< trim END
393 set scrolloff=0
394 call setline(1, ['111', '222'])
395 vnew
396 call setline(1, ['aaa', 'bbb'])
397 new
398 call setline(1, ['foo', 'bar'])
399
400 let g:resized = 0
401 au WinResized * let g:resized += 1
402
403 func WriteResizedEvent()
404 call writefile([json_encode(v:event)], 'XresizeEvent')
405 endfunc
406 au WinResized * call WriteResizedEvent()
407 END
408 call writefile(lines, 'Xtest_winresized', 'D')
409 let buf = RunVimInTerminal('-S Xtest_winresized', {'rows': 10})
410
411 " redraw now to avoid a redraw after the :echo command
412 call term_sendkeys(buf, ":redraw!\<CR>")
413 call TermWait(buf)
414
415 call term_sendkeys(buf, ":echo g:resized\<CR>")
416 call WaitForAssert({-> assert_match('^0$', term_getline(buf, 10))}, 1000)
417
418 " increase window height, two windows will be reported
419 call term_sendkeys(buf, "\<C-W>+")
420 call TermWait(buf)
421 call term_sendkeys(buf, ":echo g:resized\<CR>")
422 call WaitForAssert({-> assert_match('^1$', term_getline(buf, 10))}, 1000)
423
424 let event = readfile('XresizeEvent')[0]->json_decode()
425 call assert_equal({
426 \ 'windows': [1002, 1001],
427 \ }, event)
428
429 " increase window width, three windows will be reported
430 call term_sendkeys(buf, "\<C-W>>")
431 call TermWait(buf)
432 call term_sendkeys(buf, ":echo g:resized\<CR>")
433 call WaitForAssert({-> assert_match('^2$', term_getline(buf, 10))}, 1000)
434
435 let event = readfile('XresizeEvent')[0]->json_decode()
436 call assert_equal({
437 \ 'windows': [1002, 1001, 1000],
438 \ }, event)
439
440 call delete('XresizeEvent')
441 call StopVimInTerminal(buf)
442endfunc
443
LemonBoy09371822022-04-08 15:18:45 +0100444func Test_WinScrolled()
445 CheckRunVimInTerminal
446
447 let lines =<< trim END
zeertzjqd58862d2022-04-12 11:32:48 +0100448 set nowrap scrolloff=0
449 for ii in range(1, 18)
450 call setline(ii, repeat(nr2char(96 + ii), ii * 2))
451 endfor
452 let win_id = win_getid()
453 let g:matched = v:false
Bram Moolenaar35fc61c2022-11-22 12:40:50 +0000454 func WriteScrollEvent()
455 call writefile([json_encode(v:event)], 'XscrollEvent')
456 endfunc
zeertzjqd58862d2022-04-12 11:32:48 +0100457 execute 'au WinScrolled' win_id 'let g:matched = v:true'
458 let g:scrolled = 0
459 au WinScrolled * let g:scrolled += 1
460 au WinScrolled * let g:amatch = str2nr(expand('<amatch>'))
461 au WinScrolled * let g:afile = str2nr(expand('<afile>'))
Bram Moolenaar35fc61c2022-11-22 12:40:50 +0000462 au WinScrolled * call WriteScrollEvent()
LemonBoy09371822022-04-08 15:18:45 +0100463 END
Bram Moolenaare1f3ab72022-09-04 21:29:08 +0100464 call writefile(lines, 'Xtest_winscrolled', 'D')
LemonBoy09371822022-04-08 15:18:45 +0100465 let buf = RunVimInTerminal('-S Xtest_winscrolled', {'rows': 6})
466
467 call term_sendkeys(buf, ":echo g:scrolled\<CR>")
468 call WaitForAssert({-> assert_match('^0 ', term_getline(buf, 6))}, 1000)
469
470 " Scroll left/right in Normal mode.
471 call term_sendkeys(buf, "zlzh:echo g:scrolled\<CR>")
472 call WaitForAssert({-> assert_match('^2 ', term_getline(buf, 6))}, 1000)
473
Bram Moolenaar35fc61c2022-11-22 12:40:50 +0000474 let event = readfile('XscrollEvent')[0]->json_decode()
475 call assert_equal({
zeertzjq3fc84dc2022-12-07 09:17:59 +0000476 \ 'all': {'leftcol': 1, 'topline': 0, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
477 \ '1000': {'leftcol': -1, 'topline': 0, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}
Bram Moolenaar35fc61c2022-11-22 12:40:50 +0000478 \ }, event)
479
LemonBoy09371822022-04-08 15:18:45 +0100480 " Scroll up/down in Normal mode.
481 call term_sendkeys(buf, "\<c-e>\<c-y>:echo g:scrolled\<CR>")
482 call WaitForAssert({-> assert_match('^4 ', term_getline(buf, 6))}, 1000)
483
Bram Moolenaar35fc61c2022-11-22 12:40:50 +0000484 let event = readfile('XscrollEvent')[0]->json_decode()
485 call assert_equal({
zeertzjq3fc84dc2022-12-07 09:17:59 +0000486 \ 'all': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
487 \ '1000': {'leftcol': 0, 'topline': -1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}
Bram Moolenaar35fc61c2022-11-22 12:40:50 +0000488 \ }, event)
489
LemonBoy09371822022-04-08 15:18:45 +0100490 " Scroll up/down in Insert mode.
491 call term_sendkeys(buf, "Mi\<c-x>\<c-e>\<Esc>i\<c-x>\<c-y>\<Esc>")
492 call term_sendkeys(buf, ":echo g:scrolled\<CR>")
493 call WaitForAssert({-> assert_match('^6 ', term_getline(buf, 6))}, 1000)
494
Bram Moolenaar35fc61c2022-11-22 12:40:50 +0000495 let event = readfile('XscrollEvent')[0]->json_decode()
496 call assert_equal({
zeertzjq3fc84dc2022-12-07 09:17:59 +0000497 \ 'all': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
498 \ '1000': {'leftcol': 0, 'topline': -1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}
Bram Moolenaar35fc61c2022-11-22 12:40:50 +0000499 \ }, event)
500
LemonBoy09371822022-04-08 15:18:45 +0100501 " Scroll the window horizontally to focus the last letter of the third line
502 " containing only six characters. Moving to the previous and shorter lines
503 " should trigger another autocommand as Vim has to make them visible.
504 call term_sendkeys(buf, "5zl2k")
505 call term_sendkeys(buf, ":echo g:scrolled\<CR>")
506 call WaitForAssert({-> assert_match('^8 ', term_getline(buf, 6))}, 1000)
507
Bram Moolenaar35fc61c2022-11-22 12:40:50 +0000508 let event = readfile('XscrollEvent')[0]->json_decode()
509 call assert_equal({
zeertzjq3fc84dc2022-12-07 09:17:59 +0000510 \ 'all': {'leftcol': 5, 'topline': 0, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
511 \ '1000': {'leftcol': -5, 'topline': 0, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}
Bram Moolenaar35fc61c2022-11-22 12:40:50 +0000512 \ }, event)
513
LemonBoy09371822022-04-08 15:18:45 +0100514 " Ensure the command was triggered for the specified window ID.
515 call term_sendkeys(buf, ":echo g:matched\<CR>")
516 call WaitForAssert({-> assert_match('^v:true ', term_getline(buf, 6))}, 1000)
517
518 " Ensure the expansion of <amatch> and <afile> matches the window ID.
519 call term_sendkeys(buf, ":echo g:amatch == win_id && g:afile == win_id\<CR>")
520 call WaitForAssert({-> assert_match('^v:true ', term_getline(buf, 6))}, 1000)
521
Bram Moolenaar35fc61c2022-11-22 12:40:50 +0000522 call delete('XscrollEvent')
LemonBoy09371822022-04-08 15:18:45 +0100523 call StopVimInTerminal(buf)
LemonBoy09371822022-04-08 15:18:45 +0100524endfunc
525
LemonBoy66e13ae2022-04-21 22:52:11 +0100526func Test_WinScrolled_mouse()
527 CheckRunVimInTerminal
528
529 let lines =<< trim END
530 set nowrap scrolloff=0
531 set mouse=a term=xterm ttymouse=sgr mousetime=200 clipboard=
532 call setline(1, ['foo']->repeat(32))
533 split
534 let g:scrolled = 0
535 au WinScrolled * let g:scrolled += 1
536 END
Bram Moolenaare1f3ab72022-09-04 21:29:08 +0100537 call writefile(lines, 'Xtest_winscrolled_mouse', 'D')
LemonBoy66e13ae2022-04-21 22:52:11 +0100538 let buf = RunVimInTerminal('-S Xtest_winscrolled_mouse', {'rows': 10})
539
540 " With the upper split focused, send a scroll-down event to the unfocused one.
541 call test_setmouse(7, 1)
542 call term_sendkeys(buf, "\<ScrollWheelDown>")
543 call TermWait(buf)
544 call term_sendkeys(buf, ":echo g:scrolled\<CR>")
545 call WaitForAssert({-> assert_match('^1', term_getline(buf, 10))}, 1000)
546
547 " Again, but this time while we're in insert mode.
548 call term_sendkeys(buf, "i\<ScrollWheelDown>\<Esc>")
549 call TermWait(buf)
550 call term_sendkeys(buf, ":echo g:scrolled\<CR>")
551 call WaitForAssert({-> assert_match('^2', term_getline(buf, 10))}, 1000)
552
553 call StopVimInTerminal(buf)
LemonBoy66e13ae2022-04-21 22:52:11 +0100554endfunc
555
zeertzjqd58862d2022-04-12 11:32:48 +0100556func Test_WinScrolled_close_curwin()
557 CheckRunVimInTerminal
558
559 let lines =<< trim END
560 set nowrap scrolloff=0
561 call setline(1, ['aaa', 'bbb'])
562 vsplit
563 au WinScrolled * close
564 au VimLeave * call writefile(['123456'], 'Xtestout')
565 END
Bram Moolenaare1f3ab72022-09-04 21:29:08 +0100566 call writefile(lines, 'Xtest_winscrolled_close_curwin', 'D')
zeertzjqd58862d2022-04-12 11:32:48 +0100567 let buf = RunVimInTerminal('-S Xtest_winscrolled_close_curwin', {'rows': 6})
568
569 " This was using freed memory
570 call term_sendkeys(buf, "\<C-E>")
571 call TermWait(buf)
572 call StopVimInTerminal(buf)
573
Bram Moolenaar0a60f792022-11-19 21:18:11 +0000574 " check the startup script finished to the end
zeertzjqd58862d2022-04-12 11:32:48 +0100575 call assert_equal(['123456'], readfile('Xtestout'))
zeertzjqd58862d2022-04-12 11:32:48 +0100576 call delete('Xtestout')
577endfunc
578
Bram Moolenaar0a60f792022-11-19 21:18:11 +0000579func Test_WinScrolled_once_only()
Drew Vogelea67ba72025-05-07 22:05:17 +0200580 CheckScreendump
Bram Moolenaar0a60f792022-11-19 21:18:11 +0000581 CheckRunVimInTerminal
582
583 let lines =<< trim END
584 set cmdheight=2
585 call setline(1, ['aaa', 'bbb'])
586 let trigger_count = 0
587 func ShowInfo(id)
588 echo g:trigger_count g:winid winlayout()
589 endfunc
590
591 vsplit
592 split
593 " use a timer to show the info after a redraw
594 au WinScrolled * let trigger_count += 1 | let winid = expand('<amatch>') | call timer_start(100, 'ShowInfo')
595 wincmd j
596 wincmd l
597 END
598 call writefile(lines, 'Xtest_winscrolled_once', 'D')
599 let buf = RunVimInTerminal('-S Xtest_winscrolled_once', #{rows: 10, cols: 60, statusoff: 2})
600
601 call term_sendkeys(buf, "\<C-E>")
602 call VerifyScreenDump(buf, 'Test_winscrolled_once_only_1', {})
603
604 call StopVimInTerminal(buf)
605endfunc
606
Bram Moolenaar29967732022-11-20 12:11:45 +0000607" Check that WinScrolled is not triggered immediately when defined and there
608" are split windows.
609func Test_WinScrolled_not_when_defined()
Drew Vogelea67ba72025-05-07 22:05:17 +0200610 CheckScreendump
Bram Moolenaar29967732022-11-20 12:11:45 +0000611 CheckRunVimInTerminal
612
613 let lines =<< trim END
614 call setline(1, ['aaa', 'bbb'])
615 echo 'nothing happened'
616 func ShowTriggered(id)
617 echo 'triggered'
618 endfunc
619 END
620 call writefile(lines, 'Xtest_winscrolled_not', 'D')
621 let buf = RunVimInTerminal('-S Xtest_winscrolled_not', #{rows: 10, cols: 60, statusoff: 2})
622 call term_sendkeys(buf, ":split\<CR>")
623 call TermWait(buf)
624 " use a timer to show the message after redrawing
625 call term_sendkeys(buf, ":au WinScrolled * call timer_start(100, 'ShowTriggered')\<CR>")
626 call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_1', {})
627
628 call term_sendkeys(buf, "\<C-E>")
629 call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_2', {})
630
631 call StopVimInTerminal(buf)
632endfunc
633
zeertzjq670ab032022-08-28 19:16:15 +0100634func Test_WinScrolled_long_wrapped()
635 CheckRunVimInTerminal
636
637 let lines =<< trim END
638 set scrolloff=0
639 let height = winheight(0)
640 let width = winwidth(0)
641 let g:scrolled = 0
642 au WinScrolled * let g:scrolled += 1
643 call setline(1, repeat('foo', height * width))
644 call cursor(1, height * width)
645 END
Bram Moolenaare1f3ab72022-09-04 21:29:08 +0100646 call writefile(lines, 'Xtest_winscrolled_long_wrapped', 'D')
zeertzjq670ab032022-08-28 19:16:15 +0100647 let buf = RunVimInTerminal('-S Xtest_winscrolled_long_wrapped', {'rows': 6})
648
649 call term_sendkeys(buf, ":echo g:scrolled\<CR>")
650 call WaitForAssert({-> assert_match('^0 ', term_getline(buf, 6))}, 1000)
651
652 call term_sendkeys(buf, 'gj')
653 call term_sendkeys(buf, ":echo g:scrolled\<CR>")
654 call WaitForAssert({-> assert_match('^1 ', term_getline(buf, 6))}, 1000)
655
656 call term_sendkeys(buf, '0')
657 call term_sendkeys(buf, ":echo g:scrolled\<CR>")
658 call WaitForAssert({-> assert_match('^2 ', term_getline(buf, 6))}, 1000)
659
660 call term_sendkeys(buf, '$')
661 call term_sendkeys(buf, ":echo g:scrolled\<CR>")
662 call WaitForAssert({-> assert_match('^3 ', term_getline(buf, 6))}, 1000)
Bram Moolenaar23526d22022-12-05 15:50:41 +0000663
664 call StopVimInTerminal(buf)
zeertzjq670ab032022-08-28 19:16:15 +0100665endfunc
666
zeertzjq3fc84dc2022-12-07 09:17:59 +0000667func Test_WinScrolled_diff()
668 CheckRunVimInTerminal
669
670 let lines =<< trim END
671 set diffopt+=foldcolumn:0
672 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
673 vnew
674 call setline(1, ['d', 'e', 'f', 'g', 'h', 'i'])
675 windo diffthis
676 func WriteScrollEvent()
677 call writefile([json_encode(v:event)], 'XscrollEvent')
678 endfunc
679 au WinScrolled * call WriteScrollEvent()
680 END
681 call writefile(lines, 'Xtest_winscrolled_diff', 'D')
682 let buf = RunVimInTerminal('-S Xtest_winscrolled_diff', {'rows': 8})
683
684 call term_sendkeys(buf, "\<C-E>")
685 call WaitForAssert({-> assert_match('^d', term_getline(buf, 3))}, 1000)
686
687 let event = readfile('XscrollEvent')[0]->json_decode()
688 call assert_equal({
689 \ 'all': {'leftcol': 0, 'topline': 1, 'topfill': 1, 'width': 0, 'height': 0, 'skipcol': 0},
690 \ '1000': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
691 \ '1001': {'leftcol': 0, 'topline': 0, 'topfill': -1, 'width': 0, 'height': 0, 'skipcol': 0}
692 \ }, event)
693
694 call term_sendkeys(buf, "2\<C-E>")
695 call WaitForAssert({-> assert_match('^f', term_getline(buf, 3))}, 1000)
696
697 let event = readfile('XscrollEvent')[0]->json_decode()
698 call assert_equal({
699 \ 'all': {'leftcol': 0, 'topline': 2, 'topfill': 2, 'width': 0, 'height': 0, 'skipcol': 0},
700 \ '1000': {'leftcol': 0, 'topline': 2, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
701 \ '1001': {'leftcol': 0, 'topline': 0, 'topfill': -2, 'width': 0, 'height': 0, 'skipcol': 0}
702 \ }, event)
703
704 call term_sendkeys(buf, "\<C-E>")
705 call WaitForAssert({-> assert_match('^g', term_getline(buf, 3))}, 1000)
706
707 let event = readfile('XscrollEvent')[0]->json_decode()
708 call assert_equal({
709 \ 'all': {'leftcol': 0, 'topline': 2, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
710 \ '1000': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
711 \ '1001': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}
712 \ }, event)
713
714 call term_sendkeys(buf, "2\<C-Y>")
715 call WaitForAssert({-> assert_match('^e', term_getline(buf, 3))}, 1000)
716
717 let event = readfile('XscrollEvent')[0]->json_decode()
718 call assert_equal({
719 \ 'all': {'leftcol': 0, 'topline': 3, 'topfill': 1, 'width': 0, 'height': 0, 'skipcol': 0},
720 \ '1000': {'leftcol': 0, 'topline': -2, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
721 \ '1001': {'leftcol': 0, 'topline': -1, 'topfill': 1, 'width': 0, 'height': 0, 'skipcol': 0}
722 \ }, event)
723
724 call StopVimInTerminal(buf)
Dominique Pelle541c87c2023-01-17 21:20:44 +0000725 call delete('XscrollEvent')
zeertzjq3fc84dc2022-12-07 09:17:59 +0000726endfunc
727
naohiro ono23beefe2021-11-13 12:38:49 +0000728func Test_WinClosed()
729 " Test that the pattern is matched against the closed window's ID, and both
730 " <amatch> and <afile> are set to it.
731 new
732 let winid = win_getid()
733 let g:matched = v:false
734 augroup test-WinClosed
735 autocmd!
736 execute 'autocmd WinClosed' winid 'let g:matched = v:true'
737 autocmd WinClosed * let g:amatch = str2nr(expand('<amatch>'))
738 autocmd WinClosed * let g:afile = str2nr(expand('<afile>'))
739 augroup END
740 close
741 call assert_true(g:matched)
742 call assert_equal(winid, g:amatch)
743 call assert_equal(winid, g:afile)
744
745 " Test that WinClosed is non-recursive.
746 new
747 new
748 call assert_equal(3, winnr('$'))
749 let g:triggered = 0
750 augroup test-WinClosed
751 autocmd!
752 autocmd WinClosed * let g:triggered += 1
753 autocmd WinClosed * 2 wincmd c
754 augroup END
755 close
756 call assert_equal(1, winnr('$'))
757 call assert_equal(1, g:triggered)
758
759 autocmd! test-WinClosed
760 augroup! test-WinClosed
761 unlet g:matched
762 unlet g:amatch
763 unlet g:afile
764 unlet g:triggered
765endfunc
766
Bram Moolenaarc947b9a2022-04-06 17:59:21 +0100767func Test_WinClosed_throws()
768 vnew
769 let bnr = bufnr()
770 call assert_equal(1, bufloaded(bnr))
771 augroup test-WinClosed
772 autocmd WinClosed * throw 'foo'
773 augroup END
774 try
775 close
776 catch /.*/
777 endtry
778 call assert_equal(0, bufloaded(bnr))
779
780 autocmd! test-WinClosed
781 augroup! test-WinClosed
782endfunc
783
zeertzjq6a069402022-04-07 14:08:29 +0100784func Test_WinClosed_throws_with_tabs()
785 tabnew
786 let bnr = bufnr()
787 call assert_equal(1, bufloaded(bnr))
788 augroup test-WinClosed
789 autocmd WinClosed * throw 'foo'
790 augroup END
791 try
792 close
793 catch /.*/
794 endtry
795 call assert_equal(0, bufloaded(bnr))
796
797 autocmd! test-WinClosed
798 augroup! test-WinClosed
799endfunc
800
zeertzjq62de54b2022-09-22 18:08:37 +0100801" This used to trigger WinClosed twice for the same window, and the window's
802" buffer was NULL in the second autocommand.
803func Test_WinClosed_switch_tab()
804 edit Xa
805 split Xb
806 split Xc
807 tab split
808 new
809 augroup test-WinClosed
810 autocmd WinClosed * tabprev | bwipe!
811 augroup END
812 close
813 " Check that the tabline has been fully removed
814 call assert_equal([1, 1], win_screenpos(0))
815
816 autocmd! test-WinClosed
817 augroup! test-WinClosed
818 %bwipe!
819endfunc
820
zeertzjqb2ec0da2024-03-09 15:39:27 +0100821" This used to trigger WinClosed twice for the same window, and the window's
822" buffer was NULL in the second autocommand.
823func Test_WinClosed_BufUnload_close_other()
824 tabnew
825 let g:tab = tabpagenr()
826 let g:buf = bufnr()
827 new
828 setlocal bufhidden=wipe
829 augroup test-WinClosed
830 autocmd BufUnload * ++once exe g:buf .. 'bwipe!'
831 autocmd WinClosed * call tabpagebuflist(g:tab)
832 augroup END
833 close
834
835 unlet g:tab
836 unlet g:buf
837 autocmd! test-WinClosed
838 augroup! test-WinClosed
839 %bwipe!
840endfunc
841
Bram Moolenaare99e8442016-07-26 20:43:40 +0200842func s:AddAnAutocmd()
843 augroup vimBarTest
844 au BufReadCmd * echo 'hello'
845 augroup END
846 call assert_equal(3, len(split(execute('au vimBarTest'), "\n")))
847endfunc
848
849func Test_early_bar()
850 " test that a bar is recognized before the {event}
851 call s:AddAnAutocmd()
Bram Moolenaarb8e642f2021-11-20 10:38:25 +0000852 augroup vimBarTest | au! | let done = 77 | augroup END
Bram Moolenaare99e8442016-07-26 20:43:40 +0200853 call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
Bram Moolenaarb8e642f2021-11-20 10:38:25 +0000854 call assert_equal(77, done)
Bram Moolenaare99e8442016-07-26 20:43:40 +0200855
856 call s:AddAnAutocmd()
Bram Moolenaarb8e642f2021-11-20 10:38:25 +0000857 augroup vimBarTest| au!| let done = 88 | augroup END
Bram Moolenaare99e8442016-07-26 20:43:40 +0200858 call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
Bram Moolenaarb8e642f2021-11-20 10:38:25 +0000859 call assert_equal(88, done)
Bram Moolenaare99e8442016-07-26 20:43:40 +0200860
861 " test that a bar is recognized after the {event}
862 call s:AddAnAutocmd()
Bram Moolenaarb8e642f2021-11-20 10:38:25 +0000863 augroup vimBarTest| au!BufReadCmd| let done = 99 | augroup END
Bram Moolenaare99e8442016-07-26 20:43:40 +0200864 call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
Bram Moolenaarb8e642f2021-11-20 10:38:25 +0000865 call assert_equal(99, done)
Bram Moolenaare99e8442016-07-26 20:43:40 +0200866
867 " test that a bar is recognized after the {group}
868 call s:AddAnAutocmd()
869 au! vimBarTest|echo 'hello'
870 call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
871endfunc
Bram Moolenaarf2c4c392016-07-29 20:50:24 +0200872
Bram Moolenaar5c809082016-09-01 16:21:48 +0200873func RemoveGroup()
874 autocmd! StartOK
875 augroup! StartOK
876endfunc
877
Bram Moolenaarf2c4c392016-07-29 20:50:24 +0200878func Test_augroup_warning()
879 augroup TheWarning
880 au VimEnter * echo 'entering'
881 augroup END
Bram Moolenaar5dc4e2f2020-11-25 14:15:12 +0100882 call assert_match("TheWarning.*VimEnter", execute('au VimEnter'))
Bram Moolenaarf2c4c392016-07-29 20:50:24 +0200883 redir => res
884 augroup! TheWarning
885 redir END
Bram Moolenaar5dc4e2f2020-11-25 14:15:12 +0100886 call assert_match("W19:", res)
887 call assert_match("-Deleted-.*VimEnter", execute('au VimEnter'))
Bram Moolenaarf2c4c392016-07-29 20:50:24 +0200888
889 " check "Another" does not take the pace of the deleted entry
890 augroup Another
891 augroup END
Bram Moolenaar5dc4e2f2020-11-25 14:15:12 +0100892 call assert_match("-Deleted-.*VimEnter", execute('au VimEnter'))
Bram Moolenaaraeac9002016-09-06 22:15:08 +0200893 augroup! Another
Bram Moolenaar5c809082016-09-01 16:21:48 +0200894
895 " no warning for postpone aucmd delete
896 augroup StartOK
897 au VimEnter * call RemoveGroup()
898 augroup END
Bram Moolenaar5dc4e2f2020-11-25 14:15:12 +0100899 call assert_match("StartOK.*VimEnter", execute('au VimEnter'))
Bram Moolenaar5c809082016-09-01 16:21:48 +0200900 redir => res
901 doautocmd VimEnter
902 redir END
Bram Moolenaar5dc4e2f2020-11-25 14:15:12 +0100903 call assert_notmatch("W19:", res)
Bram Moolenaarde653f02016-09-03 16:59:06 +0200904 au! VimEnter
Bram Moolenaarad48e6c2020-04-21 22:19:45 +0200905
906 call assert_fails('augroup!', 'E471:')
Bram Moolenaarf2c4c392016-07-29 20:50:24 +0200907endfunc
Bram Moolenaarb62cc362016-09-03 16:43:53 +0200908
Bram Moolenaar8d84ff12017-10-26 16:42:16 +0200909func Test_BufReadCmdHelp()
910 " This used to cause access to free memory
911 au BufReadCmd * e +h
912 help
913
Bram Moolenaar8d84ff12017-10-26 16:42:16 +0200914 au! BufReadCmd
915endfunc
916
917func Test_BufReadCmdHelpJump()
918 " This used to cause access to free memory
919 au BufReadCmd * e +h{
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200920 " } to fix highlighting
921 call assert_fails('help', 'E434:')
Bram Moolenaar8d84ff12017-10-26 16:42:16 +0200922
Bram Moolenaar8d84ff12017-10-26 16:42:16 +0200923 au! BufReadCmd
924endfunc
925
zeertzjq93f72cc2022-08-26 15:34:52 +0100926" BufReadCmd is triggered for a "nofile" buffer. Check all values.
Bram Moolenaarb1d2c812022-08-26 11:55:01 +0100927func Test_BufReadCmdNofile()
zeertzjq93f72cc2022-08-26 15:34:52 +0100928 for val in ['nofile',
929 \ 'nowrite',
930 \ 'acwrite',
931 \ 'quickfix',
932 \ 'help',
933 \ 'terminal',
934 \ 'prompt',
935 \ 'popup',
936 \ ]
937 new somefile
938 exe 'set buftype=' .. val
939 au BufReadCmd somefile call setline(1, 'triggered')
940 edit
941 call assert_equal('triggered', getline(1))
Bram Moolenaarb1d2c812022-08-26 11:55:01 +0100942
zeertzjq93f72cc2022-08-26 15:34:52 +0100943 au! BufReadCmd
944 bwipe!
945 endfor
Bram Moolenaarb1d2c812022-08-26 11:55:01 +0100946endfunc
947
Bram Moolenaarb62cc362016-09-03 16:43:53 +0200948func Test_augroup_deleted()
Bram Moolenaarde653f02016-09-03 16:59:06 +0200949 " This caused a crash before E936 was introduced
Bram Moolenaarb62cc362016-09-03 16:43:53 +0200950 augroup x
Bram Moolenaarde653f02016-09-03 16:59:06 +0200951 call assert_fails('augroup! x', 'E936:')
952 au VimEnter * echo
953 augroup end
Bram Moolenaarb62cc362016-09-03 16:43:53 +0200954 augroup! x
Bram Moolenaar5dc4e2f2020-11-25 14:15:12 +0100955 call assert_match("-Deleted-.*VimEnter", execute('au VimEnter'))
Bram Moolenaarde653f02016-09-03 16:59:06 +0200956 au! VimEnter
Bram Moolenaarb62cc362016-09-03 16:43:53 +0200957endfunc
958
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200959" Tests for autocommands on :close command.
960" This used to be in test13.
961func Test_three_windows()
Bram Moolenaarb3435b02016-09-29 20:54:59 +0200962 " Clean up buffers, because in some cases this function fails.
963 call s:cleanup_buffers()
964
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200965 " Write three files and open them, each in a window.
966 " Then go to next window, with autocommand that deletes the previous one.
967 " Do this twice, writing the file.
968 e! Xtestje1
969 call setline(1, 'testje1')
970 w
971 sp Xtestje2
972 call setline(1, 'testje2')
973 w
974 sp Xtestje3
975 call setline(1, 'testje3')
976 w
977 wincmd w
978 au WinLeave Xtestje2 bwipe
979 wincmd w
980 call assert_equal('Xtestje1', expand('%'))
981
982 au WinLeave Xtestje1 bwipe Xtestje3
983 close
984 call assert_equal('Xtestje1', expand('%'))
985
986 " Test deleting the buffer on a Unload event. If this goes wrong there
987 " will be the ATTENTION prompt.
988 e Xtestje1
989 au!
990 au! BufUnload Xtestje1 bwipe
991 call assert_fails('e Xtestje3', 'E937:')
992 call assert_equal('Xtestje3', expand('%'))
993
994 e Xtestje2
995 sp Xtestje1
996 call assert_fails('e', 'E937:')
Bram Moolenaara997b452018-04-17 23:24:06 +0200997 call assert_equal('Xtestje1', expand('%'))
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200998
999 " Test changing buffers in a BufWipeout autocommand. If this goes wrong
1000 " there are ml_line errors and/or a Crash.
1001 au!
1002 only
1003 e Xanother
1004 e Xtestje1
1005 bwipe Xtestje2
1006 bwipe Xtestje3
1007 au BufWipeout Xtestje1 buf Xtestje1
1008 bwipe
1009 call assert_equal('Xanother', expand('%'))
1010
1011 only
1012 help
1013 wincmd w
1014 1quit
1015 call assert_equal('Xanother', expand('%'))
1016
1017 au!
Bram Moolenaar4520d442017-03-19 16:09:46 +01001018 enew
Bram Moolenaare0ab94e2016-09-04 19:50:54 +02001019 call delete('Xtestje1')
1020 call delete('Xtestje2')
1021 call delete('Xtestje3')
1022endfunc
Bram Moolenaare13b9af2017-01-13 22:01:02 +01001023
1024func Test_BufEnter()
1025 au! BufEnter
1026 au Bufenter * let val = val . '+'
1027 let g:val = ''
1028 split NewFile
1029 call assert_equal('+', g:val)
1030 bwipe!
1031 call assert_equal('++', g:val)
1032
1033 " Also get BufEnter when editing a directory
Bram Moolenaar6f14da12022-09-07 21:30:44 +01001034 call mkdir('Xbufenterdir', 'D')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01001035 split Xbufenterdir
Bram Moolenaare13b9af2017-01-13 22:01:02 +01001036 call assert_equal('+++', g:val)
Bram Moolenaare94260f2017-03-21 15:50:12 +01001037
1038 " On MS-Windows we can't edit the directory, make sure we wipe the right
1039 " buffer.
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01001040 bwipe! Xbufenterdir
Bram Moolenaare13b9af2017-01-13 22:01:02 +01001041 au! BufEnter
Bram Moolenaara9b5b852022-08-26 13:16:20 +01001042
1043 " Editing a "nofile" buffer doesn't read the file but does trigger BufEnter
zeertzjq93f72cc2022-08-26 15:34:52 +01001044 " for historic reasons. Also test other 'buftype' values.
1045 for val in ['nofile',
1046 \ 'nowrite',
1047 \ 'acwrite',
1048 \ 'quickfix',
1049 \ 'help',
1050 \ 'terminal',
1051 \ 'prompt',
1052 \ 'popup',
1053 \ ]
1054 new somefile
1055 exe 'set buftype=' .. val
1056 au BufEnter somefile call setline(1, 'some text')
1057 edit
1058 call assert_equal('some text', getline(1))
1059 bwipe!
1060 au! BufEnter
1061 endfor
Bram Moolenaar9fda8152022-11-19 13:14:10 +00001062
1063 new
1064 new
1065 autocmd BufEnter * ++once close
1066 call assert_fails('close', 'E1312:')
1067
1068 au! BufEnter
1069 only
Bram Moolenaare13b9af2017-01-13 22:01:02 +01001070endfunc
Bram Moolenaar8c752bd2017-03-19 17:09:56 +01001071
1072" Closing a window might cause an endless loop
1073" E814 for older Vims
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001074func Test_autocmd_bufwipe_in_SessLoadPost()
Bram Moolenaar1d68d9b2017-10-13 22:33:32 +02001075 edit Xtest
Bram Moolenaar8c752bd2017-03-19 17:09:56 +01001076 tabnew
Bram Moolenaar1d68d9b2017-10-13 22:33:32 +02001077 file Xsomething
Bram Moolenaar8c752bd2017-03-19 17:09:56 +01001078 set noswapfile
Bram Moolenaar8c752bd2017-03-19 17:09:56 +01001079 mksession!
1080
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001081 let content =<< trim [CODE]
Bram Moolenaar62cd26a2020-10-11 20:08:44 +02001082 call test_override('ui_delay', 10)
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001083 set nocp noswapfile
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001084 let v:swapchoice = "e"
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001085 augroup test_autocmd_sessionload
1086 autocmd!
1087 autocmd SessionLoadPost * exe bufnr("Xsomething") . "bw!"
1088 augroup END
1089
1090 func WriteErrors()
Bram Moolenaarbe9fc5b2022-09-09 17:09:35 +01001091 call writefile([execute("messages")], "XerrorsBwipe")
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001092 endfunc
1093 au VimLeave * call WriteErrors()
1094 [CODE]
1095
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01001096 call writefile(content, 'Xvimrc', 'D')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001097 call system(GetVimCommand('Xvimrc') .. ' --not-a-term --noplugins -S Session.vim -c cq')
Bram Moolenaarae04a602022-09-09 15:08:10 +01001098 sleep 100m
Bram Moolenaarbe9fc5b2022-09-09 17:09:35 +01001099 let errors = join(readfile('XerrorsBwipe'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02001100 call assert_match('E814:', errors)
Bram Moolenaar8c752bd2017-03-19 17:09:56 +01001101
Bram Moolenaar8c752bd2017-03-19 17:09:56 +01001102 set swapfile
Bram Moolenaarbe9fc5b2022-09-09 17:09:35 +01001103 for file in ['Session.vim', 'XerrorsBwipe']
Bram Moolenaar8c752bd2017-03-19 17:09:56 +01001104 call delete(file)
1105 endfor
1106endfunc
1107
Bram Moolenaar797e63b2021-01-15 16:22:52 +01001108" Using :blast and :ball for many events caused a crash, because b_nwindows was
1109" not incremented correctly.
1110func Test_autocmd_blast_badd()
1111 let content =<< trim [CODE]
1112 au BufNew,BufAdd,BufWinEnter,BufEnter,BufLeave,BufWinLeave,BufUnload,VimEnter foo* blast
1113 edit foo1
1114 au BufNew,BufAdd,BufWinEnter,BufEnter,BufLeave,BufWinLeave,BufUnload,VimEnter foo* ball
1115 edit foo2
Bram Moolenaarbe9fc5b2022-09-09 17:09:35 +01001116 call writefile(['OK'], 'XerrorsBlast')
Bram Moolenaar797e63b2021-01-15 16:22:52 +01001117 qall
1118 [CODE]
1119
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01001120 call writefile(content, 'XblastBall', 'D')
Bram Moolenaar797e63b2021-01-15 16:22:52 +01001121 call system(GetVimCommand() .. ' --clean -S XblastBall')
Bram Moolenaarae04a602022-09-09 15:08:10 +01001122 sleep 100m
Bram Moolenaarbe9fc5b2022-09-09 17:09:35 +01001123 call assert_match('OK', readfile('XerrorsBlast')->join())
Bram Moolenaar797e63b2021-01-15 16:22:52 +01001124
Bram Moolenaarbe9fc5b2022-09-09 17:09:35 +01001125 call delete('XerrorsBlast')
Bram Moolenaar797e63b2021-01-15 16:22:52 +01001126endfunc
1127
Bram Moolenaar8c752bd2017-03-19 17:09:56 +01001128" SEGV occurs in older versions.
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001129func Test_autocmd_bufwipe_in_SessLoadPost2()
Bram Moolenaar8c752bd2017-03-19 17:09:56 +01001130 tabnew
1131 set noswapfile
Bram Moolenaar8c752bd2017-03-19 17:09:56 +01001132 mksession!
1133
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001134 let content =<< trim [CODE]
1135 set nocp noswapfile
1136 function! DeleteInactiveBufs()
1137 tabfirst
1138 let tabblist = []
1139 for i in range(1, tabpagenr(''$''))
1140 call extend(tabblist, tabpagebuflist(i))
1141 endfor
1142 for b in range(1, bufnr(''$''))
1143 if bufexists(b) && buflisted(b) && (index(tabblist, b) == -1 || bufname(b) =~# ''^$'')
1144 exec ''bwipeout '' . b
1145 endif
1146 endfor
1147 echomsg "SessionLoadPost DONE"
1148 endfunction
1149 au SessionLoadPost * call DeleteInactiveBufs()
1150
1151 func WriteErrors()
Bram Moolenaarbe9fc5b2022-09-09 17:09:35 +01001152 call writefile([execute("messages")], "XerrorsPost")
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001153 endfunc
1154 au VimLeave * call WriteErrors()
1155 [CODE]
1156
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01001157 call writefile(content, 'Xvimrc', 'D')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001158 call system(GetVimCommand('Xvimrc') .. ' --not-a-term --noplugins -S Session.vim -c cq')
Bram Moolenaarae04a602022-09-09 15:08:10 +01001159 sleep 100m
Bram Moolenaarbe9fc5b2022-09-09 17:09:35 +01001160 let errors = join(readfile('XerrorsPost'))
Bram Moolenaare94260f2017-03-21 15:50:12 +01001161 " This probably only ever matches on unix.
1162 call assert_notmatch('Caught deadly signal SEGV', errors)
1163 call assert_match('SessionLoadPost DONE', errors)
Bram Moolenaar8c752bd2017-03-19 17:09:56 +01001164
Bram Moolenaar8c752bd2017-03-19 17:09:56 +01001165 set swapfile
Bram Moolenaarbe9fc5b2022-09-09 17:09:35 +01001166 for file in ['Session.vim', 'XerrorsPost']
Bram Moolenaar8c752bd2017-03-19 17:09:56 +01001167 call delete(file)
1168 endfor
1169endfunc
Bram Moolenaarfaf29d72017-07-09 11:07:16 +02001170
1171func Test_empty_doau()
1172 doau \|
1173endfunc
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001174
1175func s:AutoCommandOptionSet(match)
Bram Moolenaard7c96872019-06-15 17:12:48 +02001176 let template = "Option: <%s>, OldVal: <%s>, OldValLocal: <%s>, OldValGlobal: <%s>, NewVal: <%s>, Scope: <%s>, Command: <%s>\n"
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001177 let item = remove(g:options, 0)
Bram Moolenaard7c96872019-06-15 17:12:48 +02001178 let expected = printf(template, item[0], item[1], item[2], item[3], item[4], item[5], item[6])
1179 let actual = printf(template, a:match, v:option_old, v:option_oldlocal, v:option_oldglobal, v:option_new, v:option_type, v:option_command)
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001180 let g:opt = [expected, actual]
1181 "call assert_equal(expected, actual)
1182endfunc
1183
1184func Test_OptionSet()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001185 CheckOption autochdir
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001186
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +02001187 badd test_autocmd.vim
1188
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001189 call test_override('starting', 1)
1190 set nocp
1191 au OptionSet * :call s:AutoCommandOptionSet(expand("<amatch>"))
1192
1193 " 1: Setting number option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001194 let g:options = [['number', 0, 0, 0, 1, 'global', 'set']]
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001195 set nu
1196 call assert_equal([], g:options)
1197 call assert_equal(g:opt[0], g:opt[1])
1198
1199 " 2: Setting local number option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001200 let g:options = [['number', 1, 1, '', 0, 'local', 'setlocal']]
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001201 setlocal nonu
1202 call assert_equal([], g:options)
1203 call assert_equal(g:opt[0], g:opt[1])
1204
1205 " 3: Setting global number option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001206 let g:options = [['number', 1, '', 1, 0, 'global', 'setglobal']]
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001207 setglobal nonu
1208 call assert_equal([], g:options)
1209 call assert_equal(g:opt[0], g:opt[1])
1210
1211 " 4: Setting local autoindent option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001212 let g:options = [['autoindent', 0, 0, '', 1, 'local', 'setlocal']]
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001213 setlocal ai
1214 call assert_equal([], g:options)
1215 call assert_equal(g:opt[0], g:opt[1])
1216
1217 " 5: Setting global autoindent option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001218 let g:options = [['autoindent', 0, '', 0, 1, 'global', 'setglobal']]
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001219 setglobal ai
1220 call assert_equal([], g:options)
1221 call assert_equal(g:opt[0], g:opt[1])
1222
1223 " 6: Setting global autoindent option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001224 let g:options = [['autoindent', 1, 1, 1, 0, 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001225 set ai!
1226 call assert_equal([], g:options)
1227 call assert_equal(g:opt[0], g:opt[1])
1228
1229 " 6a: Setting global autoindent option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001230 let g:options = [['autoindent', 1, 1, 0, 0, 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001231 noa setlocal ai
1232 noa setglobal noai
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001233 set ai!
1234 call assert_equal([], g:options)
1235 call assert_equal(g:opt[0], g:opt[1])
1236
1237 " Should not print anything, use :noa
1238 " 7: don't trigger OptionSet"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001239 let g:options = [['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid']]
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001240 noa set nonu
Bram Moolenaard7c96872019-06-15 17:12:48 +02001241 call assert_equal([['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid']], g:options)
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001242 call assert_equal(g:opt[0], g:opt[1])
1243
1244 " 8: Setting several global list and number option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001245 let g:options = [['list', 0, 0, 0, 1, 'global', 'set'], ['number', 0, 0, 0, 1, 'global', 'set']]
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001246 set list nu
1247 call assert_equal([], g:options)
1248 call assert_equal(g:opt[0], g:opt[1])
1249
1250 " 9: don't trigger OptionSet"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001251 let g:options = [['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid'], ['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid']]
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001252 noa set nolist nonu
Bram Moolenaard7c96872019-06-15 17:12:48 +02001253 call assert_equal([['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid'], ['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid']], g:options)
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001254 call assert_equal(g:opt[0], g:opt[1])
1255
1256 " 10: Setting global acd"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001257 let g:options = [['autochdir', 0, 0, '', 1, 'local', 'setlocal']]
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001258 setlocal acd
1259 call assert_equal([], g:options)
1260 call assert_equal(g:opt[0], g:opt[1])
1261
1262 " 11: Setting global autoread (also sets local value)"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001263 let g:options = [['autoread', 0, 0, 0, 1, 'global', 'set']]
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001264 set ar
1265 call assert_equal([], g:options)
1266 call assert_equal(g:opt[0], g:opt[1])
1267
1268 " 12: Setting local autoread"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001269 let g:options = [['autoread', 1, 1, '', 1, 'local', 'setlocal']]
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001270 setlocal ar
1271 call assert_equal([], g:options)
1272 call assert_equal(g:opt[0], g:opt[1])
1273
1274 " 13: Setting global autoread"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001275 let g:options = [['autoread', 1, '', 1, 0, 'global', 'setglobal']]
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001276 setglobal invar
1277 call assert_equal([], g:options)
1278 call assert_equal(g:opt[0], g:opt[1])
1279
1280 " 14: Setting option backspace through :let"
Luca Saccarola959ef612024-12-01 16:25:53 +01001281 let g:options = [['backspace', 'indent,eol,start', 'indent,eol,start', 'indent,eol,start', '', 'global', 'set']]
1282 let &bs = ''
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001283 call assert_equal([], g:options)
1284 call assert_equal(g:opt[0], g:opt[1])
1285
1286 " 15: Setting option backspace through setbufvar()"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001287 let g:options = [['backup', 0, 0, '', 1, 'local', 'setlocal']]
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001288 " try twice, first time, shouldn't trigger because option name is invalid,
1289 " second time, it should trigger
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +02001290 let bnum = bufnr('%')
Bram Moolenaare2e40752020-09-04 21:18:46 +02001291 call assert_fails("call setbufvar(bnum, '&l:bk', 1)", 'E355:')
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001292 " should trigger, use correct option name
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +02001293 call setbufvar(bnum, '&backup', 1)
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001294 call assert_equal([], g:options)
1295 call assert_equal(g:opt[0], g:opt[1])
1296
1297 " 16: Setting number option using setwinvar"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001298 let g:options = [['number', 0, 0, '', 1, 'local', 'setlocal']]
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001299 call setwinvar(0, '&number', 1)
1300 call assert_equal([], g:options)
1301 call assert_equal(g:opt[0], g:opt[1])
1302
1303 " 17: Setting key option, shouldn't trigger"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001304 let g:options = [['key', 'invalid', 'invalid1', 'invalid2', 'invalid3', 'invalid4', 'invalid5']]
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001305 setlocal key=blah
1306 setlocal key=
Bram Moolenaard7c96872019-06-15 17:12:48 +02001307 call assert_equal([['key', 'invalid', 'invalid1', 'invalid2', 'invalid3', 'invalid4', 'invalid5']], g:options)
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001308 call assert_equal(g:opt[0], g:opt[1])
1309
Bram Moolenaard7c96872019-06-15 17:12:48 +02001310
1311 " 18a: Setting string global option"
1312 let oldval = &backupext
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001313 let g:options = [['backupext', oldval, oldval, oldval, 'foo', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001314 set backupext=foo
1315 call assert_equal([], g:options)
1316 call assert_equal(g:opt[0], g:opt[1])
1317
1318 " 18b: Resetting string global option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001319 let g:options = [['backupext', 'foo', 'foo', 'foo', oldval, 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001320 set backupext&
1321 call assert_equal([], g:options)
1322 call assert_equal(g:opt[0], g:opt[1])
1323
1324 " 18c: Setting global string global option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001325 let g:options = [['backupext', oldval, '', oldval, 'bar', 'global', 'setglobal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001326 setglobal backupext=bar
1327 call assert_equal([], g:options)
1328 call assert_equal(g:opt[0], g:opt[1])
1329
1330 " 18d: Setting local string global option"
1331 " As this is a global option this sets the global value even though
1332 " :setlocal is used!
1333 noa set backupext& " Reset global and local value (without triggering autocmd)
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001334 let g:options = [['backupext', oldval, oldval, '', 'baz', 'local', 'setlocal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001335 setlocal backupext=baz
1336 call assert_equal([], g:options)
1337 call assert_equal(g:opt[0], g:opt[1])
1338
1339 " 18e: Setting again string global option"
1340 noa setglobal backupext=ext_global " Reset global and local value (without triggering autocmd)
1341 noa setlocal backupext=ext_local " Sets the global(!) value!
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001342 let g:options = [['backupext', 'ext_local', 'ext_local', 'ext_local', 'fuu', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001343 set backupext=fuu
1344 call assert_equal([], g:options)
1345 call assert_equal(g:opt[0], g:opt[1])
1346
1347
zeertzjqb811de52021-10-21 10:50:44 +01001348 " 19a: Setting string global-local (to buffer) option"
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001349 let oldval = &tags
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001350 let g:options = [['tags', oldval, oldval, oldval, 'tagpath', 'global', 'set']]
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001351 set tags=tagpath
1352 call assert_equal([], g:options)
1353 call assert_equal(g:opt[0], g:opt[1])
1354
zeertzjqb811de52021-10-21 10:50:44 +01001355 " 19b: Resetting string global-local (to buffer) option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001356 let g:options = [['tags', 'tagpath', 'tagpath', 'tagpath', oldval, 'global', 'set']]
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001357 set tags&
1358 call assert_equal([], g:options)
1359 call assert_equal(g:opt[0], g:opt[1])
1360
zeertzjqb811de52021-10-21 10:50:44 +01001361 " 19c: Setting global string global-local (to buffer) option "
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001362 let g:options = [['tags', oldval, '', oldval, 'tagpath1', 'global', 'setglobal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001363 setglobal tags=tagpath1
1364 call assert_equal([], g:options)
1365 call assert_equal(g:opt[0], g:opt[1])
1366
zeertzjqb811de52021-10-21 10:50:44 +01001367 " 19d: Setting local string global-local (to buffer) option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001368 let g:options = [['tags', 'tagpath1', 'tagpath1', '', 'tagpath2', 'local', 'setlocal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001369 setlocal tags=tagpath2
1370 call assert_equal([], g:options)
1371 call assert_equal(g:opt[0], g:opt[1])
1372
zeertzjqb811de52021-10-21 10:50:44 +01001373 " 19e: Setting again string global-local (to buffer) option"
1374 " Note: v:option_old is the old global value for global-local string options
Bram Moolenaard7c96872019-06-15 17:12:48 +02001375 " but the old local value for all other kinds of options.
1376 noa setglobal tags=tag_global " Reset global and local value (without triggering autocmd)
1377 noa setlocal tags=tag_local
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001378 let g:options = [['tags', 'tag_global', 'tag_local', 'tag_global', 'tagpath', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001379 set tags=tagpath
1380 call assert_equal([], g:options)
1381 call assert_equal(g:opt[0], g:opt[1])
1382
zeertzjqb811de52021-10-21 10:50:44 +01001383 " 19f: Setting string global-local (to buffer) option to an empty string"
1384 " Note: v:option_old is the old global value for global-local string options
Bram Moolenaard7c96872019-06-15 17:12:48 +02001385 " but the old local value for all other kinds of options.
1386 noa set tags=tag_global " Reset global and local value (without triggering autocmd)
1387 noa setlocal tags= " empty string
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001388 let g:options = [['tags', 'tag_global', '', 'tag_global', 'tagpath', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001389 set tags=tagpath
1390 call assert_equal([], g:options)
1391 call assert_equal(g:opt[0], g:opt[1])
1392
1393
1394 " 20a: Setting string local (to buffer) option"
1395 let oldval = &spelllang
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001396 let g:options = [['spelllang', oldval, oldval, oldval, 'elvish,klingon', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001397 set spelllang=elvish,klingon
1398 call assert_equal([], g:options)
1399 call assert_equal(g:opt[0], g:opt[1])
1400
1401 " 20b: Resetting string local (to buffer) option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001402 let g:options = [['spelllang', 'elvish,klingon', 'elvish,klingon', 'elvish,klingon', oldval, 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001403 set spelllang&
1404 call assert_equal([], g:options)
1405 call assert_equal(g:opt[0], g:opt[1])
1406
1407 " 20c: Setting global string local (to buffer) option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001408 let g:options = [['spelllang', oldval, '', oldval, 'elvish', 'global', 'setglobal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001409 setglobal spelllang=elvish
1410 call assert_equal([], g:options)
1411 call assert_equal(g:opt[0], g:opt[1])
1412
1413 " 20d: Setting local string local (to buffer) option"
1414 noa set spelllang& " Reset global and local value (without triggering autocmd)
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001415 let g:options = [['spelllang', oldval, oldval, '', 'klingon', 'local', 'setlocal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001416 setlocal spelllang=klingon
1417 call assert_equal([], g:options)
1418 call assert_equal(g:opt[0], g:opt[1])
1419
1420 " 20e: Setting again string local (to buffer) option"
zeertzjqb811de52021-10-21 10:50:44 +01001421 " Note: v:option_old is the old global value for global-local string options
Bram Moolenaard7c96872019-06-15 17:12:48 +02001422 " but the old local value for all other kinds of options.
1423 noa setglobal spelllang=spellglobal " Reset global and local value (without triggering autocmd)
1424 noa setlocal spelllang=spelllocal
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001425 let g:options = [['spelllang', 'spelllocal', 'spelllocal', 'spellglobal', 'foo', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001426 set spelllang=foo
1427 call assert_equal([], g:options)
1428 call assert_equal(g:opt[0], g:opt[1])
1429
1430
zeertzjqb811de52021-10-21 10:50:44 +01001431 " 21a: Setting string global-local (to window) option"
Bram Moolenaard7c96872019-06-15 17:12:48 +02001432 let oldval = &statusline
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001433 let g:options = [['statusline', oldval, oldval, oldval, 'foo', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001434 set statusline=foo
1435 call assert_equal([], g:options)
1436 call assert_equal(g:opt[0], g:opt[1])
1437
zeertzjqb811de52021-10-21 10:50:44 +01001438 " 21b: Resetting string global-local (to window) option"
1439 " Note: v:option_old is the old global value for global-local string options
Bram Moolenaard7c96872019-06-15 17:12:48 +02001440 " but the old local value for all other kinds of options.
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001441 let g:options = [['statusline', 'foo', 'foo', 'foo', oldval, 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001442 set statusline&
1443 call assert_equal([], g:options)
1444 call assert_equal(g:opt[0], g:opt[1])
1445
zeertzjqb811de52021-10-21 10:50:44 +01001446 " 21c: Setting global string global-local (to window) option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001447 let g:options = [['statusline', oldval, '', oldval, 'bar', 'global', 'setglobal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001448 setglobal statusline=bar
1449 call assert_equal([], g:options)
1450 call assert_equal(g:opt[0], g:opt[1])
1451
zeertzjqb811de52021-10-21 10:50:44 +01001452 " 21d: Setting local string global-local (to window) option"
Bram Moolenaard7c96872019-06-15 17:12:48 +02001453 noa set statusline& " Reset global and local value (without triggering autocmd)
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001454 let g:options = [['statusline', oldval, oldval, '', 'baz', 'local', 'setlocal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001455 setlocal statusline=baz
1456 call assert_equal([], g:options)
1457 call assert_equal(g:opt[0], g:opt[1])
1458
zeertzjqb811de52021-10-21 10:50:44 +01001459 " 21e: Setting again string global-local (to window) option"
1460 " Note: v:option_old is the old global value for global-local string options
Bram Moolenaard7c96872019-06-15 17:12:48 +02001461 " but the old local value for all other kinds of options.
1462 noa setglobal statusline=bar " Reset global and local value (without triggering autocmd)
1463 noa setlocal statusline=baz
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001464 let g:options = [['statusline', 'bar', 'baz', 'bar', 'foo', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001465 set statusline=foo
1466 call assert_equal([], g:options)
1467 call assert_equal(g:opt[0], g:opt[1])
1468
1469
1470 " 22a: Setting string local (to window) option"
1471 let oldval = &foldignore
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001472 let g:options = [['foldignore', oldval, oldval, oldval, 'fo', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001473 set foldignore=fo
1474 call assert_equal([], g:options)
1475 call assert_equal(g:opt[0], g:opt[1])
1476
1477 " 22b: Resetting string local (to window) option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001478 let g:options = [['foldignore', 'fo', 'fo', 'fo', oldval, 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001479 set foldignore&
1480 call assert_equal([], g:options)
1481 call assert_equal(g:opt[0], g:opt[1])
1482
1483 " 22c: Setting global string local (to window) option"
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001484 let g:options = [['foldignore', oldval, '', oldval, 'bar', 'global', 'setglobal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001485 setglobal foldignore=bar
1486 call assert_equal([], g:options)
1487 call assert_equal(g:opt[0], g:opt[1])
1488
1489 " 22d: Setting local string local (to window) option"
1490 noa set foldignore& " Reset global and local value (without triggering autocmd)
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001491 let g:options = [['foldignore', oldval, oldval, '', 'baz', 'local', 'setlocal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001492 setlocal foldignore=baz
1493 call assert_equal([], g:options)
1494 call assert_equal(g:opt[0], g:opt[1])
1495
1496 " 22e: Setting again string local (to window) option"
1497 noa setglobal foldignore=glob " Reset global and local value (without triggering autocmd)
1498 noa setlocal foldignore=loc
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001499 let g:options = [['foldignore', 'loc', 'loc', 'glob', 'fo', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001500 set foldignore=fo
1501 call assert_equal([], g:options)
1502 call assert_equal(g:opt[0], g:opt[1])
1503
1504
zeertzjqb811de52021-10-21 10:50:44 +01001505 " 23a: Setting global number global option"
Bram Moolenaard7c96872019-06-15 17:12:48 +02001506 noa setglobal cmdheight=8 " Reset global and local value (without triggering autocmd)
1507 noa setlocal cmdheight=1 " Sets the global(!) value!
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001508 let g:options = [['cmdheight', '1', '', '1', '2', 'global', 'setglobal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001509 setglobal cmdheight=2
1510 call assert_equal([], g:options)
1511 call assert_equal(g:opt[0], g:opt[1])
1512
1513 " 23b: Setting local number global option"
1514 noa setglobal cmdheight=8 " Reset global and local value (without triggering autocmd)
1515 noa setlocal cmdheight=1 " Sets the global(!) value!
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001516 let g:options = [['cmdheight', '1', '1', '', '2', 'local', 'setlocal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001517 setlocal cmdheight=2
1518 call assert_equal([], g:options)
1519 call assert_equal(g:opt[0], g:opt[1])
1520
1521 " 23c: Setting again number global option"
1522 noa setglobal cmdheight=8 " Reset global and local value (without triggering autocmd)
1523 noa setlocal cmdheight=1 " Sets the global(!) value!
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001524 let g:options = [['cmdheight', '1', '1', '1', '2', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001525 set cmdheight=2
1526 call assert_equal([], g:options)
1527 call assert_equal(g:opt[0], g:opt[1])
1528
1529 " 23d: Setting again number global option"
1530 noa set cmdheight=8 " Reset global and local value (without triggering autocmd)
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001531 let g:options = [['cmdheight', '8', '8', '8', '2', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001532 set cmdheight=2
1533 call assert_equal([], g:options)
1534 call assert_equal(g:opt[0], g:opt[1])
1535
1536
1537 " 24a: Setting global number global-local (to buffer) option"
1538 noa setglobal undolevels=8 " Reset global and local value (without triggering autocmd)
1539 noa setlocal undolevels=1
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001540 let g:options = [['undolevels', '8', '', '8', '2', 'global', 'setglobal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001541 setglobal undolevels=2
1542 call assert_equal([], g:options)
1543 call assert_equal(g:opt[0], g:opt[1])
1544
1545 " 24b: Setting local number global-local (to buffer) option"
1546 noa setglobal undolevels=8 " Reset global and local value (without triggering autocmd)
1547 noa setlocal undolevels=1
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001548 let g:options = [['undolevels', '1', '1', '', '2', 'local', 'setlocal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001549 setlocal undolevels=2
1550 call assert_equal([], g:options)
1551 call assert_equal(g:opt[0], g:opt[1])
1552
1553 " 24c: Setting again number global-local (to buffer) option"
1554 noa setglobal undolevels=8 " Reset global and local value (without triggering autocmd)
1555 noa setlocal undolevels=1
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001556 let g:options = [['undolevels', '1', '1', '8', '2', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001557 set undolevels=2
1558 call assert_equal([], g:options)
1559 call assert_equal(g:opt[0], g:opt[1])
1560
1561 " 24d: Setting again global number global-local (to buffer) option"
1562 noa set undolevels=8 " Reset global and local value (without triggering autocmd)
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001563 let g:options = [['undolevels', '8', '8', '8', '2', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001564 set undolevels=2
1565 call assert_equal([], g:options)
1566 call assert_equal(g:opt[0], g:opt[1])
1567
1568
1569 " 25a: Setting global number local (to buffer) option"
1570 noa setglobal wrapmargin=8 " Reset global and local value (without triggering autocmd)
1571 noa setlocal wrapmargin=1
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001572 let g:options = [['wrapmargin', '8', '', '8', '2', 'global', 'setglobal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001573 setglobal wrapmargin=2
1574 call assert_equal([], g:options)
1575 call assert_equal(g:opt[0], g:opt[1])
1576
1577 " 25b: Setting local number local (to buffer) option"
1578 noa setglobal wrapmargin=8 " Reset global and local value (without triggering autocmd)
1579 noa setlocal wrapmargin=1
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001580 let g:options = [['wrapmargin', '1', '1', '', '2', 'local', 'setlocal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001581 setlocal wrapmargin=2
1582 call assert_equal([], g:options)
1583 call assert_equal(g:opt[0], g:opt[1])
1584
1585 " 25c: Setting again number local (to buffer) option"
1586 noa setglobal wrapmargin=8 " Reset global and local value (without triggering autocmd)
1587 noa setlocal wrapmargin=1
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001588 let g:options = [['wrapmargin', '1', '1', '8', '2', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001589 set wrapmargin=2
1590 call assert_equal([], g:options)
1591 call assert_equal(g:opt[0], g:opt[1])
1592
1593 " 25d: Setting again global number local (to buffer) option"
1594 noa set wrapmargin=8 " Reset global and local value (without triggering autocmd)
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001595 let g:options = [['wrapmargin', '8', '8', '8', '2', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001596 set wrapmargin=2
1597 call assert_equal([], g:options)
1598 call assert_equal(g:opt[0], g:opt[1])
1599
1600
1601 " 26: Setting number global-local (to window) option.
1602 " Such option does currently not exist.
1603
1604
1605 " 27a: Setting global number local (to window) option"
1606 noa setglobal foldcolumn=8 " Reset global and local value (without triggering autocmd)
1607 noa setlocal foldcolumn=1
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001608 let g:options = [['foldcolumn', '8', '', '8', '2', 'global', 'setglobal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001609 setglobal foldcolumn=2
1610 call assert_equal([], g:options)
1611 call assert_equal(g:opt[0], g:opt[1])
1612
1613 " 27b: Setting local number local (to window) option"
1614 noa setglobal foldcolumn=8 " Reset global and local value (without triggering autocmd)
1615 noa setlocal foldcolumn=1
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001616 let g:options = [['foldcolumn', '1', '1', '', '2', 'local', 'setlocal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001617 setlocal foldcolumn=2
1618 call assert_equal([], g:options)
1619 call assert_equal(g:opt[0], g:opt[1])
1620
1621 " 27c: Setting again number local (to window) option"
1622 noa setglobal foldcolumn=8 " Reset global and local value (without triggering autocmd)
1623 noa setlocal foldcolumn=1
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001624 let g:options = [['foldcolumn', '1', '1', '8', '2', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001625 set foldcolumn=2
1626 call assert_equal([], g:options)
1627 call assert_equal(g:opt[0], g:opt[1])
1628
zeertzjqb811de52021-10-21 10:50:44 +01001629 " 27d: Setting again global number local (to window) option"
Bram Moolenaard7c96872019-06-15 17:12:48 +02001630 noa set foldcolumn=8 " Reset global and local value (without triggering autocmd)
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001631 let g:options = [['foldcolumn', '8', '8', '8', '2', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001632 set foldcolumn=2
1633 call assert_equal([], g:options)
1634 call assert_equal(g:opt[0], g:opt[1])
1635
1636
1637 " 28a: Setting global boolean global option"
1638 noa setglobal nowrapscan " Reset global and local value (without triggering autocmd)
1639 noa setlocal wrapscan " Sets the global(!) value!
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001640 let g:options = [['wrapscan', '1', '', '1', '0', 'global', 'setglobal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001641 setglobal nowrapscan
1642 call assert_equal([], g:options)
1643 call assert_equal(g:opt[0], g:opt[1])
1644
1645 " 28b: Setting local boolean global option"
1646 noa setglobal nowrapscan " Reset global and local value (without triggering autocmd)
1647 noa setlocal wrapscan " Sets the global(!) value!
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001648 let g:options = [['wrapscan', '1', '1', '', '0', 'local', 'setlocal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001649 setlocal nowrapscan
1650 call assert_equal([], g:options)
1651 call assert_equal(g:opt[0], g:opt[1])
1652
1653 " 28c: Setting again boolean global option"
1654 noa setglobal nowrapscan " Reset global and local value (without triggering autocmd)
1655 noa setlocal wrapscan " Sets the global(!) value!
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001656 let g:options = [['wrapscan', '1', '1', '1', '0', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001657 set nowrapscan
1658 call assert_equal([], g:options)
1659 call assert_equal(g:opt[0], g:opt[1])
1660
1661 " 28d: Setting again global boolean global option"
1662 noa set nowrapscan " Reset global and local value (without triggering autocmd)
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001663 let g:options = [['wrapscan', '0', '0', '0', '1', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001664 set wrapscan
1665 call assert_equal([], g:options)
1666 call assert_equal(g:opt[0], g:opt[1])
1667
1668
1669 " 29a: Setting global boolean global-local (to buffer) option"
1670 noa setglobal noautoread " Reset global and local value (without triggering autocmd)
1671 noa setlocal autoread
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001672 let g:options = [['autoread', '0', '', '0', '1', 'global', 'setglobal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001673 setglobal autoread
1674 call assert_equal([], g:options)
1675 call assert_equal(g:opt[0], g:opt[1])
1676
1677 " 29b: Setting local boolean global-local (to buffer) option"
1678 noa setglobal noautoread " Reset global and local value (without triggering autocmd)
1679 noa setlocal autoread
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001680 let g:options = [['autoread', '1', '1', '', '0', 'local', 'setlocal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001681 setlocal noautoread
1682 call assert_equal([], g:options)
1683 call assert_equal(g:opt[0], g:opt[1])
1684
1685 " 29c: Setting again boolean global-local (to buffer) option"
1686 noa setglobal noautoread " Reset global and local value (without triggering autocmd)
1687 noa setlocal autoread
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001688 let g:options = [['autoread', '1', '1', '0', '1', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001689 set autoread
1690 call assert_equal([], g:options)
1691 call assert_equal(g:opt[0], g:opt[1])
1692
1693 " 29d: Setting again global boolean global-local (to buffer) option"
1694 noa set noautoread " Reset global and local value (without triggering autocmd)
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001695 let g:options = [['autoread', '0', '0', '0', '1', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001696 set autoread
1697 call assert_equal([], g:options)
1698 call assert_equal(g:opt[0], g:opt[1])
1699
1700
1701 " 30a: Setting global boolean local (to buffer) option"
1702 noa setglobal nocindent " Reset global and local value (without triggering autocmd)
1703 noa setlocal cindent
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001704 let g:options = [['cindent', '0', '', '0', '1', 'global', 'setglobal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001705 setglobal cindent
1706 call assert_equal([], g:options)
1707 call assert_equal(g:opt[0], g:opt[1])
1708
1709 " 30b: Setting local boolean local (to buffer) option"
1710 noa setglobal nocindent " Reset global and local value (without triggering autocmd)
1711 noa setlocal cindent
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001712 let g:options = [['cindent', '1', '1', '', '0', 'local', 'setlocal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001713 setlocal nocindent
1714 call assert_equal([], g:options)
1715 call assert_equal(g:opt[0], g:opt[1])
1716
1717 " 30c: Setting again boolean local (to buffer) option"
1718 noa setglobal nocindent " Reset global and local value (without triggering autocmd)
1719 noa setlocal cindent
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001720 let g:options = [['cindent', '1', '1', '0', '1', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001721 set cindent
1722 call assert_equal([], g:options)
1723 call assert_equal(g:opt[0], g:opt[1])
1724
1725 " 30d: Setting again global boolean local (to buffer) option"
1726 noa set nocindent " Reset global and local value (without triggering autocmd)
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001727 let g:options = [['cindent', '0', '0', '0', '1', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001728 set cindent
1729 call assert_equal([], g:options)
1730 call assert_equal(g:opt[0], g:opt[1])
1731
1732
1733 " 31: Setting boolean global-local (to window) option
1734 " Currently no such option exists.
1735
1736
1737 " 32a: Setting global boolean local (to window) option"
1738 noa setglobal nocursorcolumn " Reset global and local value (without triggering autocmd)
1739 noa setlocal cursorcolumn
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001740 let g:options = [['cursorcolumn', '0', '', '0', '1', 'global', 'setglobal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001741 setglobal cursorcolumn
1742 call assert_equal([], g:options)
1743 call assert_equal(g:opt[0], g:opt[1])
1744
1745 " 32b: Setting local boolean local (to window) option"
1746 noa setglobal nocursorcolumn " Reset global and local value (without triggering autocmd)
1747 noa setlocal cursorcolumn
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001748 let g:options = [['cursorcolumn', '1', '1', '', '0', 'local', 'setlocal']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001749 setlocal nocursorcolumn
1750 call assert_equal([], g:options)
1751 call assert_equal(g:opt[0], g:opt[1])
1752
1753 " 32c: Setting again boolean local (to window) option"
1754 noa setglobal nocursorcolumn " Reset global and local value (without triggering autocmd)
1755 noa setlocal cursorcolumn
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001756 let g:options = [['cursorcolumn', '1', '1', '0', '1', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001757 set cursorcolumn
1758 call assert_equal([], g:options)
1759 call assert_equal(g:opt[0], g:opt[1])
1760
1761 " 32d: Setting again global boolean local (to window) option"
1762 noa set nocursorcolumn " Reset global and local value (without triggering autocmd)
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001763 let g:options = [['cursorcolumn', '0', '0', '0', '1', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001764 set cursorcolumn
1765 call assert_equal([], g:options)
1766 call assert_equal(g:opt[0], g:opt[1])
1767
1768
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02001769 " 33: Test autocommands when an option value is converted internally.
Bram Moolenaard7c96872019-06-15 17:12:48 +02001770 noa set backspace=1 " Reset global and local value (without triggering autocmd)
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001771 let g:options = [['backspace', 'indent,eol', 'indent,eol', 'indent,eol', '2', 'global', 'set']]
Bram Moolenaard7c96872019-06-15 17:12:48 +02001772 set backspace=2
1773 call assert_equal([], g:options)
1774 call assert_equal(g:opt[0], g:opt[1])
1775
1776
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001777 " Cleanup
1778 au! OptionSet
Bram Moolenaar0331faf2019-06-15 18:40:37 +02001779 " set tags&
Bram Moolenaard7c96872019-06-15 17:12:48 +02001780 for opt in ['nu', 'ai', 'acd', 'ar', 'bs', 'backup', 'cul', 'cp', 'backupext', 'tags', 'spelllang', 'statusline', 'foldignore', 'cmdheight', 'undolevels', 'wrapmargin', 'foldcolumn', 'wrapscan', 'autoread', 'cindent', 'cursorcolumn']
Bram Moolenaar91d2e782018-08-07 19:05:01 +02001781 exe printf(":set %s&vim", opt)
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001782 endfor
1783 call test_override('starting', 0)
1784 delfunc! AutoCommandOptionSet
1785endfunc
1786
1787func Test_OptionSet_diffmode()
1788 call test_override('starting', 1)
Bram Moolenaar26d98212019-01-27 22:32:55 +01001789 " 18: Changing an option when entering diff mode
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001790 new
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01001791 au OptionSet diff :let &l:cul = v:option_new
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001792
1793 call setline(1, ['buffer 1', 'line2', 'line3', 'line4'])
1794 call assert_equal(0, &l:cul)
1795 diffthis
1796 call assert_equal(1, &l:cul)
1797
1798 vnew
1799 call setline(1, ['buffer 2', 'line 2', 'line 3', 'line4'])
1800 call assert_equal(0, &l:cul)
1801 diffthis
1802 call assert_equal(1, &l:cul)
1803
1804 diffoff
1805 call assert_equal(0, &l:cul)
1806 call assert_equal(1, getwinvar(2, '&l:cul'))
1807 bw!
1808
1809 call assert_equal(1, &l:cul)
1810 diffoff!
1811 call assert_equal(0, &l:cul)
1812 call assert_equal(0, getwinvar(1, '&l:cul'))
1813 bw!
1814
1815 " Cleanup
1816 au! OptionSet
1817 call test_override('starting', 0)
1818endfunc
1819
1820func Test_OptionSet_diffmode_close()
1821 call test_override('starting', 1)
1822 " 19: Try to close the current window when entering diff mode
1823 " should not segfault
1824 new
1825 au OptionSet diff close
1826
1827 call setline(1, ['buffer 1', 'line2', 'line3', 'line4'])
Bram Moolenaare2e40752020-09-04 21:18:46 +02001828 call assert_fails(':diffthis', 'E788:')
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001829 call assert_equal(1, &diff)
1830 vnew
1831 call setline(1, ['buffer 2', 'line 2', 'line 3', 'line4'])
Bram Moolenaare2e40752020-09-04 21:18:46 +02001832 call assert_fails(':diffthis', 'E788:')
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001833 call assert_equal(1, &diff)
Bram Moolenaara9aa86f2019-11-10 21:25:45 +01001834 set diffopt-=closeoff
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001835 bw!
Bram Moolenaare2e40752020-09-04 21:18:46 +02001836 call assert_fails(':diffoff!', 'E788:')
Bram Moolenaar04f62f82017-07-19 18:18:39 +02001837 bw!
1838
1839 " Cleanup
1840 au! OptionSet
1841 call test_override('starting', 0)
1842 "delfunc! AutoCommandOptionSet
1843endfunc
Bram Moolenaar4a137b42017-08-04 22:37:11 +02001844
1845" Test for Bufleave autocommand that deletes the buffer we are about to edit.
1846func Test_BufleaveWithDelete()
Bram Moolenaare7cda972022-08-29 11:02:59 +01001847 new | edit XbufLeave1
Bram Moolenaar4a137b42017-08-04 22:37:11 +02001848
1849 augroup test_bufleavewithdelete
1850 autocmd!
Bram Moolenaare7cda972022-08-29 11:02:59 +01001851 autocmd BufLeave XbufLeave1 bwipe XbufLeave2
Bram Moolenaar4a137b42017-08-04 22:37:11 +02001852 augroup END
1853
Bram Moolenaare7cda972022-08-29 11:02:59 +01001854 call assert_fails('edit XbufLeave2', 'E143:')
1855 call assert_equal('XbufLeave1', bufname('%'))
Bram Moolenaar4a137b42017-08-04 22:37:11 +02001856
Bram Moolenaare7cda972022-08-29 11:02:59 +01001857 autocmd! test_bufleavewithdelete BufLeave XbufLeave1
Bram Moolenaar4a137b42017-08-04 22:37:11 +02001858 augroup! test_bufleavewithdelete
1859
1860 new
Bram Moolenaare7cda972022-08-29 11:02:59 +01001861 bwipe! XbufLeave1
Bram Moolenaar4a137b42017-08-04 22:37:11 +02001862endfunc
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +02001863
1864" Test for autocommand that changes the buffer list, when doing ":ball".
1865func Test_Acmd_BufAll()
1866 enew!
1867 %bwipe!
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01001868 call writefile(['Test file Xxx1'], 'Xxx1', 'D')
1869 call writefile(['Test file Xxx2'], 'Xxx2', 'D')
1870 call writefile(['Test file Xxx3'], 'Xxx3', 'D')
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +02001871
1872 " Add three files to the buffer list
1873 split Xxx1
1874 close
1875 split Xxx2
1876 close
1877 split Xxx3
1878 close
1879
1880 " Wipe the buffer when the buffer is opened
1881 au BufReadPost Xxx2 bwipe
1882
1883 call append(0, 'Test file Xxx4')
1884 ball
1885
1886 call assert_equal(2, winnr('$'))
1887 call assert_equal('Xxx1', bufname(winbufnr(winnr('$'))))
1888 wincmd t
1889
1890 au! BufReadPost
1891 %bwipe!
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +02001892 enew! | only
1893endfunc
1894
1895" Test for autocommand that changes current buffer on BufEnter event.
1896" Check if modelines are interpreted for the correct buffer.
1897func Test_Acmd_BufEnter()
1898 %bwipe!
1899 call writefile(['start of test file Xxx1',
1900 \ "\<Tab>this is a test",
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01001901 \ 'end of test file Xxx1'], 'Xxx1', 'D')
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +02001902 call writefile(['start of test file Xxx2',
1903 \ 'vim: set noai :',
1904 \ "\<Tab>this is a test",
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01001905 \ 'end of test file Xxx2'], 'Xxx2', 'D')
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +02001906
1907 au BufEnter Xxx2 brew
1908 set ai modeline modelines=3
1909 edit Xxx1
1910 " edit Xxx2, autocmd will do :brew
1911 edit Xxx2
1912 exe "normal G?this is a\<CR>"
1913 " Append text with autoindent to this file
1914 normal othis should be auto-indented
1915 call assert_equal("\<Tab>this should be auto-indented", getline('.'))
1916 call assert_equal(3, line('.'))
1917 " Remove autocmd and edit Xxx2 again
1918 au! BufEnter Xxx2
1919 buf! Xxx2
1920 exe "normal G?this is a\<CR>"
1921 " append text without autoindent to Xxx
1922 normal othis should be in column 1
1923 call assert_equal("this should be in column 1", getline('.'))
1924 call assert_equal(4, line('.'))
1925
1926 %bwipe!
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +02001927 set ai&vim modeline&vim modelines&vim
1928endfunc
1929
1930" Test for issue #57
1931" do not move cursor on <c-o> when autoindent is set
1932func Test_ai_CTRL_O()
1933 enew!
1934 set ai
1935 let save_fo = &fo
1936 set fo+=r
1937 exe "normal o# abcdef\<Esc>2hi\<CR>\<C-O>d0\<Esc>"
1938 exe "normal o# abcdef\<Esc>2hi\<C-O>d0\<Esc>"
1939 call assert_equal(['# abc', 'def', 'def'], getline(2, 4))
1940
1941 set ai&vim
1942 let &fo = save_fo
1943 enew!
1944endfunc
1945
1946" Test for autocommand that deletes the current buffer on BufLeave event.
1947" Also test deleting the last buffer, should give a new, empty buffer.
1948func Test_BufLeave_Wipe()
1949 %bwipe!
1950 let content = ['start of test file Xxx',
1951 \ 'this is a test',
1952 \ 'end of test file Xxx']
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01001953 call writefile(content, 'Xxx1', 'D')
1954 call writefile(content, 'Xxx2', 'D')
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +02001955
1956 au BufLeave Xxx2 bwipe
1957 edit Xxx1
1958 split Xxx2
1959 " delete buffer Xxx2, we should be back to Xxx1
1960 bwipe
1961 call assert_equal('Xxx1', bufname('%'))
1962 call assert_equal(1, winnr('$'))
1963
1964 " Create an alternate buffer
1965 %write! test.out
1966 call assert_equal('test.out', bufname('#'))
1967 " delete alternate buffer
1968 bwipe test.out
1969 call assert_equal('Xxx1', bufname('%'))
1970 call assert_equal('', bufname('#'))
1971
1972 au BufLeave Xxx1 bwipe
1973 " delete current buffer, get an empty one
1974 bwipe!
1975 call assert_equal(1, line('$'))
1976 call assert_equal('', bufname('%'))
Bram Moolenaarb2c87502017-10-14 21:15:58 +02001977 let g:bufinfo = getbufinfo()
1978 call assert_equal(1, len(g:bufinfo))
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +02001979
Bram Moolenaar53f0c962017-10-22 14:23:59 +02001980 call delete('test.out')
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +02001981 %bwipe
1982 au! BufLeave
Bram Moolenaarb2c87502017-10-14 21:15:58 +02001983
1984 " check that bufinfo doesn't contain a pointer to freed memory
1985 call test_garbagecollect_now()
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +02001986endfunc
Bram Moolenaar87ffb5c2017-10-19 12:37:42 +02001987
1988func Test_QuitPre()
1989 edit Xfoo
1990 let winid = win_getid(winnr())
1991 split Xbar
1992 au! QuitPre * let g:afile = expand('<afile>')
1993 " Close the other window, <afile> should be correct.
1994 exe win_id2win(winid) . 'q'
1995 call assert_equal('Xfoo', g:afile)
LemonBoy66e13ae2022-04-21 22:52:11 +01001996
Bram Moolenaar87ffb5c2017-10-19 12:37:42 +02001997 unlet g:afile
1998 bwipe Xfoo
1999 bwipe Xbar
2000endfunc
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +02002001
Girish Palya92f68e22025-04-21 11:12:41 +02002002func Test_Cmdline_Trigger()
2003 autocmd CmdlineLeavePre : let g:log = "CmdlineLeavePre"
Girish Palya612f63b2025-04-28 18:29:52 +02002004 autocmd CmdlineLeave : let g:log2 = "CmdlineLeave"
Girish Palya92f68e22025-04-21 11:12:41 +02002005 new
2006 let g:log = ''
Girish Palya46755e62025-04-27 19:28:06 +02002007 let g:log2 = ''
Girish Palya92f68e22025-04-21 11:12:41 +02002008 nnoremap <F1> <Cmd>echo "hello"<CR>
2009 call feedkeys("\<F1>", 'x')
2010 call assert_equal('', g:log)
Girish Palya46755e62025-04-27 19:28:06 +02002011 call assert_equal('', g:log2)
Girish Palya92f68e22025-04-21 11:12:41 +02002012 nunmap <F1>
Girish Palya46755e62025-04-27 19:28:06 +02002013
Girish Palya92f68e22025-04-21 11:12:41 +02002014 let g:log = ''
Girish Palya46755e62025-04-27 19:28:06 +02002015 let g:log2 = ''
Girish Palya92f68e22025-04-21 11:12:41 +02002016 nnoremap <F1> :echo "hello"<CR>
2017 call feedkeys("\<F1>", 'x')
2018 call assert_equal('CmdlineLeavePre', g:log)
Girish Palya46755e62025-04-27 19:28:06 +02002019 call assert_equal('CmdlineLeave', g:log2)
Girish Palya92f68e22025-04-21 11:12:41 +02002020 nunmap <F1>
Girish Palya46755e62025-04-27 19:28:06 +02002021
Girish Palya92f68e22025-04-21 11:12:41 +02002022 let g:log = ''
Girish Palya46755e62025-04-27 19:28:06 +02002023 let g:log2 = ''
2024 call feedkeys(":\<bs>", "tx")
2025 call assert_equal('CmdlineLeavePre', g:log)
2026 call assert_equal('CmdlineLeave', g:log2)
2027
2028 let g:log = ''
2029 let g:log2 = ''
Girish Palya92f68e22025-04-21 11:12:41 +02002030 split
2031 call assert_equal('', g:log)
2032 call feedkeys(":echo hello", "tx")
2033 call assert_equal('CmdlineLeavePre', g:log)
Girish Palya46755e62025-04-27 19:28:06 +02002034 call assert_equal('CmdlineLeave', g:log2)
2035
Girish Palya92f68e22025-04-21 11:12:41 +02002036 let g:log = ''
Girish Palya46755e62025-04-27 19:28:06 +02002037 let g:log2 = ''
Girish Palya92f68e22025-04-21 11:12:41 +02002038 close
2039 call assert_equal('', g:log)
2040 call feedkeys(":echo hello", "tx")
2041 call assert_equal('CmdlineLeavePre', g:log)
Girish Palya46755e62025-04-27 19:28:06 +02002042 call assert_equal('CmdlineLeave', g:log2)
2043
Girish Palya92f68e22025-04-21 11:12:41 +02002044 let g:log = ''
Girish Palya46755e62025-04-27 19:28:06 +02002045 let g:log2 = ''
Girish Palya92f68e22025-04-21 11:12:41 +02002046 tabnew
2047 call assert_equal('', g:log)
2048 call feedkeys(":echo hello", "tx")
2049 call assert_equal('CmdlineLeavePre', g:log)
Girish Palya46755e62025-04-27 19:28:06 +02002050 call assert_equal('CmdlineLeave', g:log2)
2051
Girish Palya92f68e22025-04-21 11:12:41 +02002052 let g:log = ''
Girish Palya46755e62025-04-27 19:28:06 +02002053 let g:log2 = ''
Girish Palya92f68e22025-04-21 11:12:41 +02002054 split
2055 call assert_equal('', g:log)
2056 call feedkeys(":echo hello", "tx")
2057 call assert_equal('CmdlineLeavePre', g:log)
Girish Palya46755e62025-04-27 19:28:06 +02002058 call assert_equal('CmdlineLeave', g:log2)
2059
Girish Palya92f68e22025-04-21 11:12:41 +02002060 let g:log = ''
Girish Palya46755e62025-04-27 19:28:06 +02002061 let g:log2 = ''
Girish Palya92f68e22025-04-21 11:12:41 +02002062 tabclose
2063 call assert_equal('', g:log)
2064 call feedkeys(":echo hello", "tx")
2065 call assert_equal('CmdlineLeavePre', g:log)
Girish Palya46755e62025-04-27 19:28:06 +02002066 call assert_equal('CmdlineLeave', g:log2)
2067
zeertzjq92403692025-04-28 18:04:00 +02002068 autocmd CmdlineLeavePre * let g:cmdline += [getcmdline()]
2069
2070 for end_keys in ["\<CR>", "\<NL>", "\<kEnter>", "\<C-C>", "\<Esc>",
2071 \ "\<C-\>\<C-N>", "\<C-\>\<C-G>"]
2072 let g:cmdline = []
2073 let g:log = ''
2074 let g:log2 = ''
2075 call assert_equal('', g:log)
2076 let keys = $':echo "hello"{end_keys}'
2077 let msg = keytrans(keys)
2078 call feedkeys(keys, "tx")
2079 call assert_equal(['echo "hello"'], g:cmdline, msg)
2080 call assert_equal('CmdlineLeavePre', g:log, msg)
2081 call assert_equal('CmdlineLeave', g:log2, msg)
2082 endfor
2083
2084 let g:cmdline = []
2085 call feedkeys(":let c = input('? ')\<cr>ABCDE\<cr>", "tx")
2086 call assert_equal(["let c = input('? ')", 'ABCDE'], g:cmdline)
2087
2088 au! CmdlineLeavePre
2089 unlet! g:cmdline
Girish Palya5c3d1e32025-04-22 19:52:16 +02002090 unlet! g:log
Girish Palya46755e62025-04-27 19:28:06 +02002091 unlet! g:log2
Girish Palya92f68e22025-04-21 11:12:41 +02002092 bw!
2093endfunc
2094
Girish Palya46755e62025-04-27 19:28:06 +02002095" Ensure :cabbr does not cause a spurious CmdlineLeavePre.
2096func Test_CmdlineLeavePre_cabbr()
Girish Palya6220bba2025-04-28 18:00:40 +02002097 " For unknown reason this fails intermittently on MS-Windows
2098 CheckNotMSWindows
Girish Palya46755e62025-04-27 19:28:06 +02002099 CheckFeature terminal
2100 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3})
2101 call assert_equal('running', term_getstatus(buf))
2102 call term_sendkeys(buf, ":let g:a=0\<cr>")
2103 call term_wait(buf, 50)
2104 call term_sendkeys(buf, ":cabbr v v\<cr>")
2105 call term_wait(buf, 50)
2106 call term_sendkeys(buf, ":command! -nargs=* Foo echo\<cr>")
2107 call term_wait(buf, 50)
2108 call term_sendkeys(buf, ":au! CmdlineLeavePre * :let g:a+=1\<cr>")
2109 call term_wait(buf, 50)
2110 call term_sendkeys(buf, ":Foo v\<cr>")
2111 call term_wait(buf, 50)
2112 call term_sendkeys(buf, ":echo g:a\<cr>")
2113 call term_wait(buf, 50)
2114 call WaitForAssert({-> assert_match('^2.*$', term_getline(buf, 3))})
2115 bwipe!
2116endfunc
2117
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +02002118func Test_Cmdline()
Bram Moolenaar153b7042018-01-31 15:48:32 +01002119 au! CmdlineChanged : let g:text = getcmdline()
2120 let g:text = 0
2121 call feedkeys(":echom 'hello'\<CR>", 'xt')
2122 call assert_equal("echom 'hello'", g:text)
2123 au! CmdlineChanged
2124
2125 au! CmdlineChanged : let g:entered = expand('<afile>')
2126 let g:entered = 0
2127 call feedkeys(":echom 'hello'\<CR>", 'xt')
2128 call assert_equal(':', g:entered)
2129 au! CmdlineChanged
2130
zeertzjq412e0e42023-02-11 10:34:07 +00002131 autocmd CmdlineChanged : let g:log += [getcmdline()]
2132
Bram Moolenaarbb393d82022-12-09 12:21:50 +00002133 let g:log = []
2134 cnoremap <F1> <Cmd>call setcmdline('ls')<CR>
Bram Moolenaarbb393d82022-12-09 12:21:50 +00002135 call feedkeys(":\<F1>", 'xt')
2136 call assert_equal(['ls'], g:log)
Bram Moolenaarbb393d82022-12-09 12:21:50 +00002137 cunmap <F1>
2138
zeertzjqaf9e28a2023-02-06 20:58:09 +00002139 let g:log = []
zeertzjqaf9e28a2023-02-06 20:58:09 +00002140 call feedkeys(":sign \<Tab>\<Tab>\<C-N>\<C-P>\<S-Tab>\<S-Tab>\<Esc>", 'xt')
2141 call assert_equal([
2142 \ 's',
2143 \ 'si',
2144 \ 'sig',
2145 \ 'sign',
2146 \ 'sign ',
2147 \ 'sign define',
2148 \ 'sign jump',
2149 \ 'sign list',
2150 \ 'sign jump',
2151 \ 'sign define',
2152 \ 'sign ',
2153 \ ], g:log)
2154 let g:log = []
2155 set wildmenu wildoptions+=pum
2156 call feedkeys(":sign \<S-Tab>\<PageUp>\<kPageUp>\<kPageDown>\<PageDown>\<Esc>", 'xt')
2157 call assert_equal([
2158 \ 's',
2159 \ 'si',
2160 \ 'sig',
2161 \ 'sign',
2162 \ 'sign ',
2163 \ 'sign unplace',
2164 \ 'sign jump',
2165 \ 'sign define',
2166 \ 'sign undefine',
2167 \ 'sign unplace',
2168 \ ], g:log)
2169 set wildmenu& wildoptions&
zeertzjq412e0e42023-02-11 10:34:07 +00002170
2171 let g:log = []
2172 let @r = 'abc'
2173 call feedkeys(":0\<C-R>r1\<C-R>\<C-O>r2\<C-R>\<C-R>r3\<Esc>", 'xt')
2174 call assert_equal([
2175 \ '0',
2176 \ '0a',
2177 \ '0ab',
2178 \ '0abc',
2179 \ '0abc1',
2180 \ '0abc1abc',
2181 \ '0abc1abc2',
2182 \ '0abc1abc2abc',
2183 \ '0abc1abc2abc3',
2184 \ ], g:log)
2185
zeertzjqaf9e28a2023-02-06 20:58:09 +00002186 unlet g:log
2187 au! CmdlineChanged
2188
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +02002189 au! CmdlineEnter : let g:entered = expand('<afile>')
2190 au! CmdlineLeave : let g:left = expand('<afile>')
Girish Palya92f68e22025-04-21 11:12:41 +02002191 au! CmdlineLeavePre : let g:leftpre = expand('<afile>')
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +02002192 let g:entered = 0
2193 let g:left = 0
Girish Palya92f68e22025-04-21 11:12:41 +02002194 let g:leftpre = 0
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +02002195 call feedkeys(":echo 'hello'\<CR>", 'xt')
2196 call assert_equal(':', g:entered)
2197 call assert_equal(':', g:left)
Girish Palya92f68e22025-04-21 11:12:41 +02002198 call assert_equal(':', g:leftpre)
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +02002199 au! CmdlineEnter
2200 au! CmdlineLeave
Girish Palya92f68e22025-04-21 11:12:41 +02002201 au! CmdlineLeavePre
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +02002202
Bram Moolenaara4baf5b2018-04-22 13:27:44 +02002203 let save_shellslash = &shellslash
2204 set noshellslash
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +02002205 au! CmdlineEnter / let g:entered = expand('<afile>')
2206 au! CmdlineLeave / let g:left = expand('<afile>')
Girish Palya92f68e22025-04-21 11:12:41 +02002207 au! CmdlineLeavePre / let g:leftpre = expand('<afile>')
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +02002208 let g:entered = 0
2209 let g:left = 0
Girish Palya92f68e22025-04-21 11:12:41 +02002210 let g:leftpre = 0
Bram Moolenaar53f0c962017-10-22 14:23:59 +02002211 new
2212 call setline(1, 'hello')
2213 call feedkeys("/hello\<CR>", 'xt')
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +02002214 call assert_equal('/', g:entered)
2215 call assert_equal('/', g:left)
Girish Palya92f68e22025-04-21 11:12:41 +02002216 call assert_equal('/', g:leftpre)
Bram Moolenaar53f0c962017-10-22 14:23:59 +02002217 bwipe!
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +02002218 au! CmdlineEnter
2219 au! CmdlineLeave
Girish Palya92f68e22025-04-21 11:12:41 +02002220 au! CmdlineLeavePre
Bram Moolenaara4baf5b2018-04-22 13:27:44 +02002221 let &shellslash = save_shellslash
Shougo Matsushitad0952142024-06-20 22:05:16 +02002222
Girish Palya92f68e22025-04-21 11:12:41 +02002223 let g:left = "cancelled"
2224 let g:leftpre = "cancelled"
2225 au! CmdlineLeave : let g:left = "triggered"
2226 au! CmdlineLeavePre : let g:leftpre = "triggered"
2227 call feedkeys(":echo 'hello'\<esc>", 'xt')
2228 call assert_equal('triggered', g:left)
2229 call assert_equal('triggered', g:leftpre)
2230 let g:left = "cancelled"
2231 let g:leftpre = "cancelled"
2232 au! CmdlineLeave : let g:left = "triggered"
2233 call feedkeys(":echo 'hello'\<c-c>", 'xt')
2234 call assert_equal('triggered', g:left)
2235 call assert_equal('triggered', g:leftpre)
2236 au! CmdlineLeave
2237 au! CmdlineLeavePre
2238
zeertzjqbc6f9672024-06-21 07:51:40 +02002239 au! CursorMovedC : let g:pos += [getcmdpos()]
2240 let g:pos = []
zeertzjq81456202024-07-07 20:48:25 +02002241 call feedkeys(":foo bar baz\<C-W>\<C-W>\<C-W>\<Esc>", 'xt')
2242 call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 9, 5, 1], g:pos)
2243 let g:pos = []
2244 call feedkeys(":hello\<C-B>\<Esc>", 'xt')
2245 call assert_equal([2, 3, 4, 5, 6, 1], g:pos)
2246 let g:pos = []
2247 call feedkeys(":hello\<C-U>\<Esc>", 'xt')
2248 call assert_equal([2, 3, 4, 5, 6, 1], g:pos)
2249 let g:pos = []
zeertzjqbc6f9672024-06-21 07:51:40 +02002250 call feedkeys(":hello\<Left>\<C-R>=''\<CR>\<Left>\<Right>\<Esc>", 'xt')
zeertzjq81456202024-07-07 20:48:25 +02002251 call assert_equal([2, 3, 4, 5, 6, 5, 4, 5], g:pos)
zeertzjqbc6f9672024-06-21 07:51:40 +02002252 let g:pos = []
2253 call feedkeys(":12345678\<C-R>=setcmdpos(3)??''\<CR>\<Esc>", 'xt')
zeertzjq81456202024-07-07 20:48:25 +02002254 call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 3], g:pos)
zeertzjqbc6f9672024-06-21 07:51:40 +02002255 let g:pos = []
2256 call feedkeys(":12345678\<C-R>=setcmdpos(3)??''\<CR>\<Left>\<Esc>", 'xt')
zeertzjq81456202024-07-07 20:48:25 +02002257 call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 3, 2], g:pos)
Shougo Matsushitad0952142024-06-20 22:05:16 +02002258 au! CursorMovedC
2259
zeertzjqbc6f9672024-06-21 07:51:40 +02002260 " setcmdpos() is no-op inside an autocommand
2261 au! CursorMovedC : let g:pos += [getcmdpos()] | call setcmdpos(1)
2262 let g:pos = []
2263 call feedkeys(":hello\<Left>\<Left>\<Esc>", 'xt')
zeertzjq81456202024-07-07 20:48:25 +02002264 call assert_equal([2, 3, 4, 5, 6, 5, 4], g:pos)
Shougo Matsushitad0952142024-06-20 22:05:16 +02002265 au! CursorMovedC
zeertzjqbc6f9672024-06-21 07:51:40 +02002266
2267 unlet g:entered
2268 unlet g:left
2269 unlet g:pos
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +02002270endfunc
Bram Moolenaar53f0c962017-10-22 14:23:59 +02002271
2272" Test for BufWritePre autocommand that deletes or unloads the buffer.
2273func Test_BufWritePre()
2274 %bwipe
2275 au BufWritePre Xxx1 bunload
2276 au BufWritePre Xxx2 bwipe
2277
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01002278 call writefile(['start of Xxx1', 'test', 'end of Xxx1'], 'Xxx1', 'D')
2279 call writefile(['start of Xxx2', 'test', 'end of Xxx2'], 'Xxx2', 'D')
Bram Moolenaar53f0c962017-10-22 14:23:59 +02002280
2281 edit Xtest
2282 e! Xxx2
2283 bdel Xtest
2284 e Xxx1
2285 " write it, will unload it and give an error msg
Bram Moolenaare2e40752020-09-04 21:18:46 +02002286 call assert_fails('w', 'E203:')
Bram Moolenaar53f0c962017-10-22 14:23:59 +02002287 call assert_equal('Xxx2', bufname('%'))
2288 edit Xtest
2289 e! Xxx2
2290 bwipe Xtest
2291 " write it, will delete the buffer and give an error msg
Bram Moolenaare2e40752020-09-04 21:18:46 +02002292 call assert_fails('w', 'E203:')
Bram Moolenaar53f0c962017-10-22 14:23:59 +02002293 call assert_equal('Xxx1', bufname('%'))
2294 au! BufWritePre
Bram Moolenaar53f0c962017-10-22 14:23:59 +02002295endfunc
2296
2297" Test for BufUnload autocommand that unloads all the other buffers
2298func Test_bufunload_all()
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +01002299 let g:test_is_flaky = 1
Christian Brabandtee17b6f2023-09-09 11:23:50 +02002300 call writefile(['Test file Xxx1'], 'Xxx1', 'D')
2301 call writefile(['Test file Xxx2'], 'Xxx2', 'D')
Bram Moolenaar53f0c962017-10-22 14:23:59 +02002302
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002303 let content =<< trim [CODE]
2304 func UnloadAllBufs()
2305 let i = 1
2306 while i <= bufnr('$')
2307 if i != bufnr('%') && bufloaded(i)
2308 exe i . 'bunload'
2309 endif
2310 let i += 1
2311 endwhile
2312 endfunc
2313 au BufUnload * call UnloadAllBufs()
2314 au VimLeave * call writefile(['Test Finished'], 'Xout')
2315 edit Xxx1
2316 split Xxx2
2317 q
2318 [CODE]
2319
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01002320 call writefile(content, 'Xbunloadtest', 'D')
Bram Moolenaar53f0c962017-10-22 14:23:59 +02002321
2322 call delete('Xout')
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01002323 call system(GetVimCommandClean() .. ' -N --not-a-term -S Xbunloadtest')
Bram Moolenaar53f0c962017-10-22 14:23:59 +02002324 call assert_true(filereadable('Xout'))
2325
Bram Moolenaar53f0c962017-10-22 14:23:59 +02002326 call delete('Xout')
2327endfunc
2328
2329" Some tests for buffer-local autocommands
2330func Test_buflocal_autocmd()
2331 let g:bname = ''
2332 edit xx
2333 au BufLeave <buffer> let g:bname = expand("%")
2334 " here, autocommand for xx should trigger.
2335 " but autocommand shall not apply to buffer named <buffer>.
2336 edit somefile
2337 call assert_equal('xx', g:bname)
2338 let g:bname = ''
2339 " here, autocommand shall be auto-deleted
2340 bwipe xx
2341 " autocmd should not trigger
2342 edit xx
2343 call assert_equal('', g:bname)
2344 " autocmd should not trigger
2345 edit somefile
2346 call assert_equal('', g:bname)
2347 enew
2348 unlet g:bname
2349endfunc
Bram Moolenaar430dc5d2017-11-02 21:04:47 +01002350
2351" Test for "*Cmd" autocommands
2352func Test_Cmd_Autocmds()
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01002353 call writefile(['start of Xxx', "\tabc2", 'end of Xxx'], 'Xxx', 'D')
Bram Moolenaar430dc5d2017-11-02 21:04:47 +01002354
2355 enew!
2356 au BufReadCmd XtestA 0r Xxx|$del
2357 edit XtestA " will read text of Xxd instead
2358 call assert_equal('start of Xxx', getline(1))
2359
2360 au BufWriteCmd XtestA call append(line("$"), "write")
2361 write " will append a line to the file
2362 call assert_equal('write', getline('$'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002363 call assert_fails('read XtestA', 'E484:') " should not read anything
Bram Moolenaar430dc5d2017-11-02 21:04:47 +01002364 call assert_equal('write', getline(4))
2365
2366 " now we have:
2367 " 1 start of Xxx
2368 " 2 abc2
2369 " 3 end of Xxx
2370 " 4 write
2371
2372 au FileReadCmd XtestB '[r Xxx
2373 2r XtestB " will read Xxx below line 2 instead
2374 call assert_equal('start of Xxx', getline(3))
2375
2376 " now we have:
2377 " 1 start of Xxx
2378 " 2 abc2
2379 " 3 start of Xxx
2380 " 4 abc2
2381 " 5 end of Xxx
2382 " 6 end of Xxx
2383 " 7 write
2384
2385 au FileWriteCmd XtestC '[,']copy $
2386 normal 4GA1
2387 4,5w XtestC " will copy lines 4 and 5 to the end
2388 call assert_equal("\tabc21", getline(8))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002389 call assert_fails('r XtestC', 'E484:') " should not read anything
Bram Moolenaar430dc5d2017-11-02 21:04:47 +01002390 call assert_equal("end of Xxx", getline(9))
2391
2392 " now we have:
2393 " 1 start of Xxx
2394 " 2 abc2
2395 " 3 start of Xxx
2396 " 4 abc21
2397 " 5 end of Xxx
2398 " 6 end of Xxx
2399 " 7 write
2400 " 8 abc21
2401 " 9 end of Xxx
2402
2403 let g:lines = []
2404 au FileAppendCmd XtestD call extend(g:lines, getline(line("'["), line("']")))
2405 w >>XtestD " will add lines to 'lines'
2406 call assert_equal(9, len(g:lines))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002407 call assert_fails('$r XtestD', 'E484:') " should not read anything
Bram Moolenaar430dc5d2017-11-02 21:04:47 +01002408 call assert_equal(9, line('$'))
2409 call assert_equal('end of Xxx', getline('$'))
2410
2411 au BufReadCmd XtestE 0r Xxx|$del
2412 sp XtestE " split window with test.out
2413 call assert_equal('end of Xxx', getline(3))
2414
2415 let g:lines = []
2416 exe "normal 2Goasdf\<Esc>\<C-W>\<C-W>"
2417 au BufWriteCmd XtestE call extend(g:lines, getline(0, '$'))
2418 wall " will write other window to 'lines'
2419 call assert_equal(4, len(g:lines), g:lines)
2420 call assert_equal('asdf', g:lines[2])
2421
2422 au! BufReadCmd
2423 au! BufWriteCmd
2424 au! FileReadCmd
2425 au! FileWriteCmd
2426 au! FileAppendCmd
2427 %bwipe!
Bram Moolenaar430dc5d2017-11-02 21:04:47 +01002428 enew!
2429endfunc
Bram Moolenaaraace2152017-11-05 16:23:10 +01002430
Bram Moolenaar0fff4412020-03-29 16:06:29 +02002431func s:ReadFile()
2432 setl noswapfile nomodified
2433 let filename = resolve(expand("<afile>:p"))
2434 execute 'read' fnameescape(filename)
2435 1d_
2436 exe 'file' fnameescape(filename)
2437 setl buftype=acwrite
2438endfunc
2439
2440func s:WriteFile()
2441 let filename = resolve(expand("<afile>:p"))
2442 setl buftype=
2443 noautocmd execute 'write' fnameescape(filename)
2444 setl buftype=acwrite
2445 setl nomodified
2446endfunc
2447
2448func Test_BufReadCmd()
2449 autocmd BufReadCmd *.test call s:ReadFile()
2450 autocmd BufWriteCmd *.test call s:WriteFile()
2451
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01002452 call writefile(['one', 'two', 'three'], 'Xcmd.test', 'D')
Bram Moolenaar0fff4412020-03-29 16:06:29 +02002453 edit Xcmd.test
2454 call assert_match('Xcmd.test" line 1 of 3', execute('file'))
2455 normal! Gofour
2456 write
2457 call assert_equal(['one', 'two', 'three', 'four'], readfile('Xcmd.test'))
2458
2459 bwipe!
Bram Moolenaar0fff4412020-03-29 16:06:29 +02002460 au! BufReadCmd
2461 au! BufWriteCmd
2462endfunc
2463
zeertzjq9c8f9462022-08-30 18:17:15 +01002464func Test_BufWriteCmd()
2465 autocmd BufWriteCmd Xbufwritecmd let g:written = 1
2466 new
2467 file Xbufwritecmd
2468 set buftype=acwrite
Bram Moolenaar6f14da12022-09-07 21:30:44 +01002469 call mkdir('Xbufwritecmd', 'D')
zeertzjq9c8f9462022-08-30 18:17:15 +01002470 write
2471 " BufWriteCmd should be triggered even if a directory has the same name
2472 call assert_equal(1, g:written)
zeertzjq9c8f9462022-08-30 18:17:15 +01002473 unlet g:written
2474 au! BufWriteCmd
2475 bwipe!
2476endfunc
2477
Bram Moolenaaraace2152017-11-05 16:23:10 +01002478func SetChangeMarks(start, end)
Bram Moolenaar97c69432021-01-15 16:45:21 +01002479 exe a:start .. 'mark ['
2480 exe a:end .. 'mark ]'
Bram Moolenaaraace2152017-11-05 16:23:10 +01002481endfunc
2482
2483" Verify the effects of autocmds on '[ and ']
2484func Test_change_mark_in_autocmds()
2485 edit! Xtest
Bram Moolenaar97c69432021-01-15 16:45:21 +01002486 call feedkeys("ia\<CR>b\<CR>c\<CR>d\<C-g>u\<Esc>", 'xtn')
Bram Moolenaaraace2152017-11-05 16:23:10 +01002487
2488 call SetChangeMarks(2, 3)
2489 write
2490 call assert_equal([1, 4], [line("'["), line("']")])
2491
2492 call SetChangeMarks(2, 3)
2493 au BufWritePre * call assert_equal([1, 4], [line("'["), line("']")])
2494 write
2495 au! BufWritePre
2496
Bram Moolenaar14ddd222020-08-05 12:02:40 +02002497 if has('unix')
Bram Moolenaaraace2152017-11-05 16:23:10 +01002498 write XtestFilter
2499 write >> XtestFilter
2500
2501 call SetChangeMarks(2, 3)
2502 " Marks are set to the entire range of the write
2503 au FilterWritePre * call assert_equal([1, 4], [line("'["), line("']")])
2504 " '[ is adjusted to just before the line that will receive the filtered
2505 " data
2506 au FilterReadPre * call assert_equal([4, 4], [line("'["), line("']")])
2507 " The filtered data is read into the buffer, and the source lines are
2508 " still present, so the range is after the source lines
2509 au FilterReadPost * call assert_equal([5, 12], [line("'["), line("']")])
2510 %!cat XtestFilter
2511 " After the filtered data is read, the original lines are deleted
2512 call assert_equal([1, 8], [line("'["), line("']")])
2513 au! FilterWritePre,FilterReadPre,FilterReadPost
2514 undo
2515
2516 call SetChangeMarks(1, 4)
2517 au FilterWritePre * call assert_equal([2, 3], [line("'["), line("']")])
2518 au FilterReadPre * call assert_equal([3, 3], [line("'["), line("']")])
2519 au FilterReadPost * call assert_equal([4, 11], [line("'["), line("']")])
2520 2,3!cat XtestFilter
2521 call assert_equal([2, 9], [line("'["), line("']")])
2522 au! FilterWritePre,FilterReadPre,FilterReadPost
2523 undo
2524
2525 call delete('XtestFilter')
2526 endif
2527
2528 call SetChangeMarks(1, 4)
2529 au FileWritePre * call assert_equal([2, 3], [line("'["), line("']")])
2530 2,3write Xtest2
2531 au! FileWritePre
2532
2533 call SetChangeMarks(2, 3)
2534 au FileAppendPre * call assert_equal([1, 4], [line("'["), line("']")])
2535 write >> Xtest2
2536 au! FileAppendPre
2537
2538 call SetChangeMarks(1, 4)
2539 au FileAppendPre * call assert_equal([2, 3], [line("'["), line("']")])
2540 2,3write >> Xtest2
2541 au! FileAppendPre
2542
2543 call SetChangeMarks(1, 1)
2544 au FileReadPre * call assert_equal([3, 1], [line("'["), line("']")])
2545 au FileReadPost * call assert_equal([4, 11], [line("'["), line("']")])
2546 3read Xtest2
2547 au! FileReadPre,FileReadPost
2548 undo
2549
2550 call SetChangeMarks(4, 4)
2551 " When the line is 0, it's adjusted to 1
2552 au FileReadPre * call assert_equal([1, 4], [line("'["), line("']")])
2553 au FileReadPost * call assert_equal([1, 8], [line("'["), line("']")])
2554 0read Xtest2
2555 au! FileReadPre,FileReadPost
2556 undo
2557
2558 call SetChangeMarks(4, 4)
2559 " When the line is 0, it's adjusted to 1
2560 au FileReadPre * call assert_equal([1, 4], [line("'["), line("']")])
2561 au FileReadPost * call assert_equal([2, 9], [line("'["), line("']")])
2562 1read Xtest2
2563 au! FileReadPre,FileReadPost
2564 undo
2565
2566 bwipe!
2567 call delete('Xtest')
2568 call delete('Xtest2')
2569endfunc
2570
2571func Test_Filter_noshelltemp()
Bram Moolenaaraeb313f2020-11-27 19:13:28 +01002572 CheckExecutable cat
Bram Moolenaaraace2152017-11-05 16:23:10 +01002573
2574 enew!
2575 call setline(1, ['a', 'b', 'c', 'd'])
2576
2577 let shelltemp = &shelltemp
2578 set shelltemp
2579
2580 let g:filter_au = 0
2581 au FilterWritePre * let g:filter_au += 1
2582 au FilterReadPre * let g:filter_au += 1
2583 au FilterReadPost * let g:filter_au += 1
2584 %!cat
2585 call assert_equal(3, g:filter_au)
2586
2587 if has('filterpipe')
2588 set noshelltemp
2589
2590 let g:filter_au = 0
2591 au FilterWritePre * let g:filter_au += 1
2592 au FilterReadPre * let g:filter_au += 1
2593 au FilterReadPost * let g:filter_au += 1
2594 %!cat
2595 call assert_equal(0, g:filter_au)
2596 endif
2597
2598 au! FilterWritePre,FilterReadPre,FilterReadPost
2599 let &shelltemp = shelltemp
2600 bwipe!
2601endfunc
Bram Moolenaar7e1652c2017-12-16 18:27:02 +01002602
2603func Test_TextYankPost()
2604 enew!
2605 call setline(1, ['foo'])
2606
2607 let g:event = []
2608 au TextYankPost * let g:event = copy(v:event)
2609
2610 call assert_equal({}, v:event)
2611 call assert_fails('let v:event = {}', 'E46:')
2612 call assert_fails('let v:event.mykey = 0', 'E742:')
2613
2614 norm "ayiw
2615 call assert_equal(
Bram Moolenaara016eeb2022-04-09 11:37:38 +01002616 \ #{regcontents: ['foo'], regname: 'a', operator: 'y',
2617 \ regtype: 'v', visual: v:false, inclusive: v:true},
2618 \ g:event)
Bram Moolenaar7e1652c2017-12-16 18:27:02 +01002619 norm y_
2620 call assert_equal(
Bram Moolenaara016eeb2022-04-09 11:37:38 +01002621 \ #{regcontents: ['foo'], regname: '', operator: 'y', regtype: 'V',
2622 \ visual: v:false, inclusive: v:false},
2623 \ g:event)
Bram Moolenaar37d16732020-06-12 22:09:01 +02002624 norm Vy
2625 call assert_equal(
Bram Moolenaara016eeb2022-04-09 11:37:38 +01002626 \ #{regcontents: ['foo'], regname: '', operator: 'y', regtype: 'V',
2627 \ visual: v:true, inclusive: v:true},
2628 \ g:event)
Bram Moolenaar7e1652c2017-12-16 18:27:02 +01002629 call feedkeys("\<C-V>y", 'x')
2630 call assert_equal(
Bram Moolenaara016eeb2022-04-09 11:37:38 +01002631 \ #{regcontents: ['f'], regname: '', operator: 'y', regtype: "\x161",
2632 \ visual: v:true, inclusive: v:true},
2633 \ g:event)
Bram Moolenaar7e1652c2017-12-16 18:27:02 +01002634 norm "xciwbar
2635 call assert_equal(
Bram Moolenaara016eeb2022-04-09 11:37:38 +01002636 \ #{regcontents: ['foo'], regname: 'x', operator: 'c', regtype: 'v',
2637 \ visual: v:false, inclusive: v:true},
2638 \ g:event)
Bram Moolenaar7e1652c2017-12-16 18:27:02 +01002639 norm "bdiw
2640 call assert_equal(
Bram Moolenaara016eeb2022-04-09 11:37:38 +01002641 \ #{regcontents: ['bar'], regname: 'b', operator: 'd', regtype: 'v',
2642 \ visual: v:false, inclusive: v:true},
2643 \ g:event)
2644
2645 call setline(1, 'foobar')
2646 " exclusive motion
2647 norm $"ay0
2648 call assert_equal(
2649 \ #{regcontents: ['fooba'], regname: 'a', operator: 'y', regtype: 'v',
2650 \ visual: v:false, inclusive: v:false},
2651 \ g:event)
2652 " inclusive motion
2653 norm 0"ay$
2654 call assert_equal(
2655 \ #{regcontents: ['foobar'], regname: 'a', operator: 'y', regtype: 'v',
2656 \ visual: v:false, inclusive: v:true},
2657 \ g:event)
Bram Moolenaar7e1652c2017-12-16 18:27:02 +01002658
2659 call assert_equal({}, v:event)
2660
Bram Moolenaarfccbf062020-11-26 20:34:00 +01002661 if has('clipboard_working') && !has('gui_running')
2662 " Test that when the visual selection is automatically copied to clipboard
2663 " register a TextYankPost is emitted
2664 call setline(1, ['foobar'])
2665
2666 let @* = ''
2667 set clipboard=autoselect
2668 exe "norm! ggviw\<Esc>"
2669 call assert_equal(
Bram Moolenaara016eeb2022-04-09 11:37:38 +01002670 \ #{regcontents: ['foobar'], regname: '*', operator: 'y',
2671 \ regtype: 'v', visual: v:true, inclusive: v:false},
2672 \ g:event)
Bram Moolenaarfccbf062020-11-26 20:34:00 +01002673
2674 let @+ = ''
2675 set clipboard=autoselectplus
2676 exe "norm! ggviw\<Esc>"
2677 call assert_equal(
Bram Moolenaara016eeb2022-04-09 11:37:38 +01002678 \ #{regcontents: ['foobar'], regname: '+', operator: 'y',
2679 \ regtype: 'v', visual: v:true, inclusive: v:false},
2680 \ g:event)
Bram Moolenaarfccbf062020-11-26 20:34:00 +01002681
2682 set clipboard&vim
2683 endif
2684
Bram Moolenaar7e1652c2017-12-16 18:27:02 +01002685 au! TextYankPost
2686 unlet g:event
2687 bwipe!
2688endfunc
Bram Moolenaar9bca8052017-12-18 12:37:55 +01002689
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01002690func Test_autocommand_all_events()
2691 call assert_fails('au * * bwipe', 'E1155:')
2692 call assert_fails('au * x bwipe', 'E1155:')
Bram Moolenaarb6db1462021-12-24 19:24:47 +00002693 call assert_fails('au! * x bwipe', 'E1155:')
Bram Moolenaar4fb921e2017-12-18 15:33:00 +01002694endfunc
Bram Moolenaarb7407d32018-02-03 17:36:27 +01002695
Bram Moolenaarf6246f52022-02-11 16:30:12 +00002696func Test_autocmd_user()
2697 au User MyEvent let s:res = [expand("<afile>"), expand("<amatch>")]
2698 doautocmd User MyEvent
2699 call assert_equal(['MyEvent', 'MyEvent'], s:res)
2700 au! User
2701 unlet s:res
2702endfunc
2703
Bram Moolenaar3b014be2022-11-13 17:53:46 +00002704func Test_autocmd_user_clear_group()
2705 CheckRunVimInTerminal
2706
2707 let lines =<< trim END
2708 autocmd! User
2709 for i in range(1, 999)
2710 exe 'autocmd User ' .. 'Foo' .. i .. ' bar'
2711 endfor
2712 au CmdlineLeave : call timer_start(0, {-> execute('autocmd! User')})
2713 END
2714 call writefile(lines, 'XautoUser', 'D')
2715 let buf = RunVimInTerminal('-S XautoUser', {'rows': 10})
2716
2717 " this was using freed memory
2718 call term_sendkeys(buf, ":autocmd User\<CR>")
2719 call TermWait(buf, 50)
2720 call term_sendkeys(buf, "G")
2721
2722 call StopVimInTerminal(buf)
2723endfunc
2724
Bram Moolenaaref2c3252022-11-25 16:31:51 +00002725func Test_autocmd_CmdlineLeave_unlet()
2726 CheckRunVimInTerminal
2727
2728 let lines =<< trim END
2729 for i in range(1, 999)
2730 exe 'let g:var' .. i '=' i
2731 endfor
2732 au CmdlineLeave : call timer_start(0, {-> execute('unlet g:var990')})
2733 END
2734 call writefile(lines, 'XleaveUnlet', 'D')
2735 let buf = RunVimInTerminal('-S XleaveUnlet', {'rows': 10})
2736
2737 " this was using freed memory
2738 call term_sendkeys(buf, ":let g:\<CR>")
2739 call TermWait(buf, 50)
2740 call term_sendkeys(buf, "G")
2741 call TermWait(buf, 50)
2742 call term_sendkeys(buf, "\<CR>") " for the hit-enter prompt
2743
2744 call StopVimInTerminal(buf)
2745endfunc
2746
Bram Moolenaarb7407d32018-02-03 17:36:27 +01002747function s:Before_test_dirchanged()
2748 augroup test_dirchanged
2749 autocmd!
2750 augroup END
2751 let s:li = []
2752 let s:dir_this = getcwd()
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02002753 let s:dir_foo = s:dir_this . '/Xfoo'
Bram Moolenaar2caad3f2018-12-16 15:38:02 +01002754 call mkdir(s:dir_foo)
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02002755 let s:dir_bar = s:dir_this . '/Xbar'
Bram Moolenaar2caad3f2018-12-16 15:38:02 +01002756 call mkdir(s:dir_bar)
Bram Moolenaarb7407d32018-02-03 17:36:27 +01002757endfunc
2758
2759function s:After_test_dirchanged()
Bram Moolenaar3503d7c2019-11-09 20:10:17 +01002760 call chdir(s:dir_this)
Bram Moolenaar2caad3f2018-12-16 15:38:02 +01002761 call delete(s:dir_foo, 'd')
2762 call delete(s:dir_bar, 'd')
Bram Moolenaarb7407d32018-02-03 17:36:27 +01002763 augroup test_dirchanged
2764 autocmd!
2765 augroup END
2766endfunc
2767
2768function Test_dirchanged_global()
2769 call s:Before_test_dirchanged()
Bram Moolenaarf6246f52022-02-11 16:30:12 +00002770 autocmd test_dirchanged DirChangedPre global call add(s:li, expand("<amatch>") .. " pre cd " .. v:event.directory)
Bram Moolenaarb7407d32018-02-03 17:36:27 +01002771 autocmd test_dirchanged DirChanged global call add(s:li, "cd:")
2772 autocmd test_dirchanged DirChanged global call add(s:li, expand("<afile>"))
Bram Moolenaar3503d7c2019-11-09 20:10:17 +01002773 call chdir(s:dir_foo)
Bram Moolenaarf6246f52022-02-11 16:30:12 +00002774 let expected = ["global pre cd " .. s:dir_foo, "cd:", s:dir_foo]
Bram Moolenaar28e8f732022-02-09 12:58:20 +00002775 call assert_equal(expected, s:li)
Bram Moolenaar3503d7c2019-11-09 20:10:17 +01002776 call chdir(s:dir_foo)
Bram Moolenaar28e8f732022-02-09 12:58:20 +00002777 call assert_equal(expected, s:li)
Bram Moolenaar3503d7c2019-11-09 20:10:17 +01002778 exe 'lcd ' .. fnameescape(s:dir_bar)
Bram Moolenaar28e8f732022-02-09 12:58:20 +00002779 call assert_equal(expected, s:li)
Bram Moolenaard8c9d322022-06-12 11:49:16 +01002780
2781 exe 'cd ' .. s:dir_foo
2782 exe 'cd ' .. s:dir_bar
2783 autocmd! test_dirchanged DirChanged global let g:result = expand("<afile>")
2784 cd -
Bram Moolenaardb77c492022-06-12 23:26:50 +01002785 call assert_equal(s:dir_foo, substitute(g:result, '\\', '/', 'g'))
Bram Moolenaard8c9d322022-06-12 11:49:16 +01002786
Bram Moolenaarb7407d32018-02-03 17:36:27 +01002787 call s:After_test_dirchanged()
2788endfunc
2789
2790function Test_dirchanged_local()
2791 call s:Before_test_dirchanged()
2792 autocmd test_dirchanged DirChanged window call add(s:li, "lcd:")
2793 autocmd test_dirchanged DirChanged window call add(s:li, expand("<afile>"))
Bram Moolenaar3503d7c2019-11-09 20:10:17 +01002794 call chdir(s:dir_foo)
Bram Moolenaarb7407d32018-02-03 17:36:27 +01002795 call assert_equal([], s:li)
Bram Moolenaar3503d7c2019-11-09 20:10:17 +01002796 exe 'lcd ' .. fnameescape(s:dir_bar)
Bram Moolenaar2caad3f2018-12-16 15:38:02 +01002797 call assert_equal(["lcd:", s:dir_bar], s:li)
Bram Moolenaar3503d7c2019-11-09 20:10:17 +01002798 exe 'lcd ' .. fnameescape(s:dir_bar)
Bram Moolenaar2caad3f2018-12-16 15:38:02 +01002799 call assert_equal(["lcd:", s:dir_bar], s:li)
Bram Moolenaarb7407d32018-02-03 17:36:27 +01002800 call s:After_test_dirchanged()
2801endfunc
2802
2803function Test_dirchanged_auto()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002804 CheckOption autochdir
Bram Moolenaarb7407d32018-02-03 17:36:27 +01002805 call s:Before_test_dirchanged()
2806 call test_autochdir()
Bram Moolenaar28e8f732022-02-09 12:58:20 +00002807 autocmd test_dirchanged DirChangedPre auto call add(s:li, "pre cd " .. v:event.directory)
Bram Moolenaarb7407d32018-02-03 17:36:27 +01002808 autocmd test_dirchanged DirChanged auto call add(s:li, "auto:")
2809 autocmd test_dirchanged DirChanged auto call add(s:li, expand("<afile>"))
2810 set acd
Bram Moolenaar3503d7c2019-11-09 20:10:17 +01002811 cd ..
Bram Moolenaarb7407d32018-02-03 17:36:27 +01002812 call assert_equal([], s:li)
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01002813 exe 'edit ' . s:dir_foo . '/Xautofile'
Bram Moolenaar2caad3f2018-12-16 15:38:02 +01002814 call assert_equal(s:dir_foo, getcwd())
Bram Moolenaar28e8f732022-02-09 12:58:20 +00002815 let expected = ["pre cd " .. s:dir_foo, "auto:", s:dir_foo]
2816 call assert_equal(expected, s:li)
Bram Moolenaarb7407d32018-02-03 17:36:27 +01002817 set noacd
2818 bwipe!
2819 call s:After_test_dirchanged()
2820endfunc
Bram Moolenaar5a093432018-02-10 18:15:19 +01002821
2822" Test TextChangedI and TextChangedP
2823func Test_ChangedP()
2824 new
2825 call setline(1, ['foo', 'bar', 'foobar'])
2826 call test_override("char_avail", 1)
2827 set complete=. completeopt=menuone
2828
2829 func! TextChangedAutocmd(char)
2830 let g:autocmd .= a:char
2831 endfunc
2832
Christian Brabandtdb3b4462021-10-16 11:58:55 +01002833 " TextChanged will not be triggered, only check that it isn't.
Bram Moolenaar5a093432018-02-10 18:15:19 +01002834 au! TextChanged <buffer> :call TextChangedAutocmd('N')
2835 au! TextChangedI <buffer> :call TextChangedAutocmd('I')
2836 au! TextChangedP <buffer> :call TextChangedAutocmd('P')
2837
2838 call cursor(3, 1)
2839 let g:autocmd = ''
2840 call feedkeys("o\<esc>", 'tnix')
Evgeni Chasnovskid7ae2632023-10-15 09:59:00 +02002841 call assert_equal('I', g:autocmd)
Bram Moolenaar5a093432018-02-10 18:15:19 +01002842
2843 let g:autocmd = ''
Christian Brabandt4bca4892023-10-27 19:26:49 +02002844 call feedkeys("Sf", 'tnix')
2845 call assert_equal('II', g:autocmd)
2846
2847 let g:autocmd = ''
Bram Moolenaar5a093432018-02-10 18:15:19 +01002848 call feedkeys("Sf\<C-N>", 'tnix')
Christian Brabandt4bca4892023-10-27 19:26:49 +02002849 call assert_equal('IIP', g:autocmd)
Bram Moolenaar5a093432018-02-10 18:15:19 +01002850
2851 let g:autocmd = ''
2852 call feedkeys("Sf\<C-N>\<C-N>", 'tnix')
Christian Brabandt4bca4892023-10-27 19:26:49 +02002853 call assert_equal('IIPP', g:autocmd)
Bram Moolenaar5a093432018-02-10 18:15:19 +01002854
2855 let g:autocmd = ''
2856 call feedkeys("Sf\<C-N>\<C-N>\<C-N>", 'tnix')
Christian Brabandt4bca4892023-10-27 19:26:49 +02002857 call assert_equal('IIPPP', g:autocmd)
Bram Moolenaar5a093432018-02-10 18:15:19 +01002858
2859 let g:autocmd = ''
2860 call feedkeys("Sf\<C-N>\<C-N>\<C-N>\<C-N>", 'tnix')
Christian Brabandt4bca4892023-10-27 19:26:49 +02002861 call assert_equal('IIPPPP', g:autocmd)
Bram Moolenaar5a093432018-02-10 18:15:19 +01002862
2863 call assert_equal(['foo', 'bar', 'foobar', 'foo'], getline(1, '$'))
2864 " TODO: how should it handle completeopt=noinsert,noselect?
2865
2866 " CleanUp
2867 call test_override("char_avail", 0)
2868 au! TextChanged
2869 au! TextChangedI
2870 au! TextChangedP
2871 delfu TextChangedAutocmd
2872 unlet! g:autocmd
2873 set complete&vim completeopt&vim
2874
2875 bw!
2876endfunc
Bram Moolenaar8c64a362018-03-23 22:39:31 +01002877
Bram Moolenaar91d2e782018-08-07 19:05:01 +02002878let g:setline_handled = v:false
Bram Moolenaar1e115362019-01-09 23:01:02 +01002879func SetLineOne()
Bram Moolenaar91d2e782018-08-07 19:05:01 +02002880 if !g:setline_handled
2881 call setline(1, "(x)")
2882 let g:setline_handled = v:true
2883 endif
2884endfunc
2885
2886func Test_TextChangedI_with_setline()
2887 new
2888 call test_override('char_avail', 1)
2889 autocmd TextChangedI <buffer> call SetLineOne()
2890 call feedkeys("i(\<CR>\<Esc>", 'tx')
2891 call assert_equal('(', getline(1))
2892 call assert_equal('x)', getline(2))
2893 undo
Bram Moolenaar91d2e782018-08-07 19:05:01 +02002894 call assert_equal('', getline(1))
Bram Moolenaar9fa95062018-08-08 22:08:32 +02002895 call assert_equal('', getline(2))
Bram Moolenaar91d2e782018-08-07 19:05:01 +02002896
Bram Moolenaarca34db32022-01-20 11:17:18 +00002897 call test_override('char_avail', 0)
Bram Moolenaar91d2e782018-08-07 19:05:01 +02002898 bwipe!
2899endfunc
2900
Christian Brabandtc9e79e52024-02-09 19:34:36 +01002901func Test_TextChanged_with_norm()
2902 " For unknown reason this fails on MS-Windows
2903 CheckNotMSWindows
2904 CheckFeature terminal
2905 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3})
2906 call assert_equal('running', term_getstatus(buf))
2907 call term_sendkeys(buf, ":let g:a=0\<cr>")
2908 call term_wait(buf, 50)
2909 call term_sendkeys(buf, ":au! TextChanged * :let g:a+=1\<cr>")
2910 call term_wait(buf, 50)
2911 call term_sendkeys(buf, ":norm! ia\<cr>")
2912 call term_wait(buf, 50)
2913 call term_sendkeys(buf, ":echo g:a\<cr>")
2914 call term_wait(buf, 50)
2915 call WaitForAssert({-> assert_match('^1.*$', term_getline(buf, 3))})
2916 bwipe!
2917endfunc
2918
Bram Moolenaar8c64a362018-03-23 22:39:31 +01002919func Test_Changed_FirstTime()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +02002920 CheckFeature terminal
2921 CheckNotGui
Bram Moolenaar3cdcb092020-03-18 19:18:10 +01002922 " Starting a terminal to run Vim is always considered flaky.
Bram Moolenaar30d53e22020-03-18 21:10:44 +01002923 let g:test_is_flaky = 1
Bram Moolenaar8c5a2782019-08-07 23:07:07 +02002924
Bram Moolenaar8c64a362018-03-23 22:39:31 +01002925 " Prepare file for TextChanged event.
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01002926 call writefile([''], 'Xchanged.txt', 'D')
Bram Moolenaar8c64a362018-03-23 22:39:31 +01002927 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3})
2928 call assert_equal('running', term_getstatus(buf))
Bram Moolenaar1834d372018-03-29 17:40:46 +02002929 " Wait for the ruler (in the status line) to be shown.
Bram Moolenaaraa5df7e2019-02-03 14:53:10 +01002930 " In ConPTY, there is additional character which is drawn up to the width of
2931 " the screen.
2932 if has('conpty')
2933 call WaitForAssert({-> assert_match('\<All.*$', term_getline(buf, 3))})
2934 else
2935 call WaitForAssert({-> assert_match('\<All$', term_getline(buf, 3))})
2936 endif
Bram Moolenaar8c64a362018-03-23 22:39:31 +01002937 " It's only adding autocmd, so that no event occurs.
2938 call term_sendkeys(buf, ":au! TextChanged <buffer> call writefile(['No'], 'Xchanged.txt')\<cr>")
2939 call term_sendkeys(buf, "\<C-\\>\<C-N>:qa!\<cr>")
Bram Moolenaar50182fa2018-04-28 21:34:40 +02002940 call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))})
Bram Moolenaar8c64a362018-03-23 22:39:31 +01002941 call assert_equal([''], readfile('Xchanged.txt'))
2942
2943 " clean up
Bram Moolenaar8c64a362018-03-23 22:39:31 +01002944 bwipe!
2945endfunc
Bram Moolenaar0566e892019-01-24 19:37:40 +01002946
Bram Moolenaareb93f3f2019-04-04 15:04:56 +02002947func Test_autocmd_nested()
2948 let g:did_nested = 0
Christian Brabandtfb3f9692024-08-11 20:09:17 +02002949 defer CleanUpTestAuGroup()
2950 augroup testing
Bram Moolenaareb93f3f2019-04-04 15:04:56 +02002951 au WinNew * edit somefile
2952 au BufNew * let g:did_nested = 1
2953 augroup END
2954 split
2955 call assert_equal(0, g:did_nested)
2956 close
2957 bwipe! somefile
2958
2959 " old nested argument still works
Christian Brabandtfb3f9692024-08-11 20:09:17 +02002960 augroup testing
Bram Moolenaareb93f3f2019-04-04 15:04:56 +02002961 au!
2962 au WinNew * nested edit somefile
2963 au BufNew * let g:did_nested = 1
2964 augroup END
2965 split
2966 call assert_equal(1, g:did_nested)
2967 close
2968 bwipe! somefile
2969
2970 " New ++nested argument works
2971 augroup Testing
2972 au!
2973 au WinNew * ++nested edit somefile
2974 au BufNew * let g:did_nested = 1
2975 augroup END
2976 split
2977 call assert_equal(1, g:did_nested)
2978 close
2979 bwipe! somefile
2980
Bram Moolenaarf0775142022-03-04 20:10:38 +00002981 " nested without ++ does not work in Vim9 script
2982 call assert_fails('vim9cmd au WinNew * nested echo fails', 'E1078:')
2983
Bram Moolenaareb93f3f2019-04-04 15:04:56 +02002984 augroup Testing
2985 au!
2986 augroup END
2987
2988 call assert_fails('au WinNew * ++nested ++nested echo bad', 'E983:')
2989 call assert_fails('au WinNew * nested nested echo bad', 'E983:')
2990endfunc
2991
Bram Moolenaar5fa9f232022-07-23 09:06:48 +01002992func Test_autocmd_nested_cursor_invalid()
2993 set laststatus=0
2994 copen
2995 cclose
2996 call setline(1, ['foo', 'bar', 'baz'])
2997 3
2998 augroup nested_inv
2999 autocmd User foo ++nested copen
3000 autocmd BufAdd * let &laststatus = 2 - &laststatus
3001 augroup END
3002 doautocmd User foo
3003
3004 augroup nested_inv
3005 au!
3006 augroup END
3007 set laststatus&
Bram Moolenaarb03950f2022-07-26 13:47:13 +01003008 cclose
Bram Moolenaar5fa9f232022-07-23 09:06:48 +01003009 bwipe!
3010endfunc
3011
Bram Moolenaar3d6ee8b2022-07-27 15:23:35 +01003012func Test_autocmd_nested_keeps_cursor_pos()
3013 enew
3014 call setline(1, 'foo')
3015 autocmd User foo ++nested normal! $a
3016 autocmd InsertLeave * :
3017 doautocmd User foo
3018 call assert_equal([0, 1, 3, 0], getpos('.'))
3019
3020 bwipe!
3021endfunc
3022
Bram Moolenaarb03950f2022-07-26 13:47:13 +01003023func Test_autocmd_nested_switch_window()
3024 " run this in a separate Vim so that SafeState works
3025 CheckRunVimInTerminal
Drew Vogelea67ba72025-05-07 22:05:17 +02003026 CheckScreendump
Bram Moolenaarb03950f2022-07-26 13:47:13 +01003027
3028 let lines =<< trim END
3029 vim9script
3030 ['()']->writefile('Xautofile')
3031 autocmd VimEnter * ++nested edit Xautofile | split
3032 autocmd BufReadPost * autocmd SafeState * ++once foldclosed('.')
3033 autocmd WinEnter * matchadd('ErrorMsg', 'pat')
3034 END
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01003035 call writefile(lines, 'Xautoscript', 'D')
Bram Moolenaarb03950f2022-07-26 13:47:13 +01003036 let buf = RunVimInTerminal('-S Xautoscript', {'rows': 10})
3037 call VerifyScreenDump(buf, 'Test_autocmd_nested_switch', {})
3038
3039 call StopVimInTerminal(buf)
3040 call delete('Xautofile')
Bram Moolenaarb03950f2022-07-26 13:47:13 +01003041endfunc
3042
Bram Moolenaareb93f3f2019-04-04 15:04:56 +02003043func Test_autocmd_once()
3044 " Without ++once WinNew triggers twice
3045 let g:did_split = 0
3046 augroup Testing
3047 au WinNew * let g:did_split += 1
3048 augroup END
3049 split
3050 split
3051 call assert_equal(2, g:did_split)
3052 call assert_true(exists('#WinNew'))
3053 close
3054 close
3055
3056 " With ++once WinNew triggers once
3057 let g:did_split = 0
3058 augroup Testing
3059 au!
3060 au WinNew * ++once let g:did_split += 1
3061 augroup END
3062 split
3063 split
3064 call assert_equal(1, g:did_split)
3065 call assert_false(exists('#WinNew'))
3066 close
3067 close
3068
3069 call assert_fails('au WinNew * ++once ++once echo bad', 'E983:')
3070endfunc
3071
Bram Moolenaara68e5952019-04-25 22:22:01 +02003072func Test_autocmd_bufreadpre()
3073 new
3074 let b:bufreadpre = 1
Bram Moolenaarab505b12020-03-23 19:28:44 +01003075 call append(0, range(1000))
Bram Moolenaara68e5952019-04-25 22:22:01 +02003076 w! XAutocmdBufReadPre.txt
3077 autocmd BufReadPre <buffer> :let b:bufreadpre += 1
Bram Moolenaarab505b12020-03-23 19:28:44 +01003078 norm! 500gg
Bram Moolenaara68e5952019-04-25 22:22:01 +02003079 sp
Bram Moolenaarab505b12020-03-23 19:28:44 +01003080 norm! 1000gg
Bram Moolenaara68e5952019-04-25 22:22:01 +02003081 wincmd p
3082 let g:wsv1 = winsaveview()
3083 wincmd p
3084 let g:wsv2 = winsaveview()
3085 " triggers BufReadPre, should not move the cursor in either window
3086 " The topline may change one line in a large window.
3087 edit
3088 call assert_inrange(g:wsv2.topline - 1, g:wsv2.topline + 1, winsaveview().topline)
3089 call assert_equal(g:wsv2.lnum, winsaveview().lnum)
3090 call assert_equal(2, b:bufreadpre)
3091 wincmd p
3092 call assert_equal(g:wsv1.topline, winsaveview().topline)
3093 call assert_equal(g:wsv1.lnum, winsaveview().lnum)
3094 call assert_equal(2, b:bufreadpre)
3095 " Now set the cursor position in an BufReadPre autocommand
3096 " (even though the position will be invalid, this should make Vim reset the
3097 " cursor position in the other window.
3098 wincmd p
3099 set cpo+=g
3100 " won't do anything, but try to set the cursor on an invalid lnum
3101 autocmd BufReadPre <buffer> :norm! 70gg
3102 " triggers BufReadPre, should not move the cursor in either window
3103 e
3104 call assert_equal(1, winsaveview().topline)
3105 call assert_equal(1, winsaveview().lnum)
3106 call assert_equal(3, b:bufreadpre)
3107 wincmd p
3108 call assert_equal(g:wsv1.topline, winsaveview().topline)
3109 call assert_equal(g:wsv1.lnum, winsaveview().lnum)
3110 call assert_equal(3, b:bufreadpre)
3111 close
3112 close
3113 call delete('XAutocmdBufReadPre.txt')
3114 set cpo-=g
3115endfunc
3116
Bram Moolenaar5e66b422019-01-24 21:58:10 +01003117" FileChangedShell tested in test_filechanged.vim
Bram Moolenaar69ea5872019-04-25 20:29:00 +02003118
3119" Tests for the following autocommands:
3120" - FileWritePre writing a compressed file
3121" - FileReadPost reading a compressed file
3122" - BufNewFile reading a file template
3123" - BufReadPre decompressing the file to be read
3124" - FilterReadPre substituting characters in the temp file
3125" - FilterReadPost substituting characters after filtering
3126" - FileReadPre set options for decompression
3127" - FileReadPost decompress the file
3128func Test_ReadWrite_Autocmds()
3129 " Run this test only on Unix-like systems and if gzip is available
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003130 CheckUnix
3131 CheckExecutable gzip
Bram Moolenaar69ea5872019-04-25 20:29:00 +02003132
3133 " Make $GZIP empty, "-v" would cause trouble.
3134 let $GZIP = ""
3135
3136 " Use a FileChangedShell autocommand to avoid a prompt for 'Xtestfile.gz'
3137 " being modified outside of Vim (noticed on Solaris).
3138 au FileChangedShell * echo 'caught FileChangedShell'
3139
3140 " Test for the FileReadPost, FileWritePre and FileWritePost autocmds
3141 augroup Test1
3142 au!
3143 au FileWritePre *.gz '[,']!gzip
3144 au FileWritePost *.gz undo
3145 au FileReadPost *.gz '[,']!gzip -d
3146 augroup END
3147
3148 new
3149 set bin
3150 call append(0, [
3151 \ 'line 2 Abcdefghijklmnopqrstuvwxyz',
3152 \ 'line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3153 \ 'line 4 Abcdefghijklmnopqrstuvwxyz',
3154 \ 'line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3155 \ 'line 6 Abcdefghijklmnopqrstuvwxyz',
3156 \ 'line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3157 \ 'line 8 Abcdefghijklmnopqrstuvwxyz',
3158 \ 'line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3159 \ 'line 10 Abcdefghijklmnopqrstuvwxyz'
3160 \ ])
3161 1,9write! Xtestfile.gz
3162 enew! | close
3163
3164 new
3165 " Read and decompress the testfile
3166 0read Xtestfile.gz
3167 call assert_equal([
3168 \ 'line 2 Abcdefghijklmnopqrstuvwxyz',
3169 \ 'line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3170 \ 'line 4 Abcdefghijklmnopqrstuvwxyz',
3171 \ 'line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3172 \ 'line 6 Abcdefghijklmnopqrstuvwxyz',
3173 \ 'line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3174 \ 'line 8 Abcdefghijklmnopqrstuvwxyz',
3175 \ 'line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3176 \ 'line 10 Abcdefghijklmnopqrstuvwxyz'
3177 \ ], getline(1, 9))
3178 enew! | close
3179
3180 augroup Test1
3181 au!
3182 augroup END
3183
3184 " Test for the FileAppendPre and FileAppendPost autocmds
3185 augroup Test2
3186 au!
3187 au BufNewFile *.c read Xtest.c
3188 au FileAppendPre *.out '[,']s/new/NEW/
3189 au FileAppendPost *.out !cat Xtest.c >> test.out
3190 augroup END
3191
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01003192 call writefile(['/*', ' * Here is a new .c file', ' */'], 'Xtest.c', 'D')
Bram Moolenaar69ea5872019-04-25 20:29:00 +02003193 new foo.c " should load Xtest.c
3194 call assert_equal(['/*', ' * Here is a new .c file', ' */'], getline(2, 4))
3195 w! >> test.out " append it to the output file
3196
3197 let contents = readfile('test.out')
3198 call assert_equal(' * Here is a NEW .c file', contents[2])
3199 call assert_equal(' * Here is a new .c file', contents[5])
3200
3201 call delete('test.out')
3202 enew! | close
3203 augroup Test2
3204 au!
3205 augroup END
3206
3207 " Test for the BufReadPre and BufReadPost autocmds
3208 augroup Test3
3209 au!
3210 " setup autocommands to decompress before reading and re-compress
3211 " afterwards
3212 au BufReadPre *.gz exe '!gzip -d ' . shellescape(expand("<afile>"))
3213 au BufReadPre *.gz call rename(expand("<afile>:r"), expand("<afile>"))
3214 au BufReadPost *.gz call rename(expand("<afile>"), expand("<afile>:r"))
3215 au BufReadPost *.gz exe '!gzip ' . shellescape(expand("<afile>:r"))
3216 augroup END
3217
3218 e! Xtestfile.gz " Edit compressed file
3219 call assert_equal([
3220 \ 'line 2 Abcdefghijklmnopqrstuvwxyz',
3221 \ 'line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3222 \ 'line 4 Abcdefghijklmnopqrstuvwxyz',
3223 \ 'line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3224 \ 'line 6 Abcdefghijklmnopqrstuvwxyz',
3225 \ 'line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3226 \ 'line 8 Abcdefghijklmnopqrstuvwxyz',
3227 \ 'line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3228 \ 'line 10 Abcdefghijklmnopqrstuvwxyz'
3229 \ ], getline(1, 9))
3230
3231 w! >> test.out " Append it to the output file
3232
3233 augroup Test3
3234 au!
3235 augroup END
3236
3237 " Test for the FilterReadPre and FilterReadPost autocmds.
3238 set shelltemp " need temp files here
3239 augroup Test4
3240 au!
3241 au FilterReadPre *.out call rename(expand("<afile>"), expand("<afile>") . ".t")
3242 au FilterReadPre *.out exe 'silent !sed s/e/E/ ' . shellescape(expand("<afile>")) . ".t >" . shellescape(expand("<afile>"))
3243 au FilterReadPre *.out exe 'silent !rm ' . shellescape(expand("<afile>")) . '.t'
3244 au FilterReadPost *.out '[,']s/x/X/g
3245 augroup END
3246
3247 e! test.out " Edit the output file
3248 1,$!cat
3249 call assert_equal([
3250 \ 'linE 2 AbcdefghijklmnopqrstuvwXyz',
3251 \ 'linE 3 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
3252 \ 'linE 4 AbcdefghijklmnopqrstuvwXyz',
3253 \ 'linE 5 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
3254 \ 'linE 6 AbcdefghijklmnopqrstuvwXyz',
3255 \ 'linE 7 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
3256 \ 'linE 8 AbcdefghijklmnopqrstuvwXyz',
3257 \ 'linE 9 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
3258 \ 'linE 10 AbcdefghijklmnopqrstuvwXyz'
3259 \ ], getline(1, 9))
3260 call assert_equal([
3261 \ 'line 2 Abcdefghijklmnopqrstuvwxyz',
3262 \ 'line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3263 \ 'line 4 Abcdefghijklmnopqrstuvwxyz',
3264 \ 'line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3265 \ 'line 6 Abcdefghijklmnopqrstuvwxyz',
3266 \ 'line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3267 \ 'line 8 Abcdefghijklmnopqrstuvwxyz',
3268 \ 'line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3269 \ 'line 10 Abcdefghijklmnopqrstuvwxyz'
3270 \ ], readfile('test.out'))
3271
3272 augroup Test4
3273 au!
3274 augroup END
3275 set shelltemp&vim
3276
3277 " Test for the FileReadPre and FileReadPost autocmds.
3278 augroup Test5
3279 au!
3280 au FileReadPre *.gz exe 'silent !gzip -d ' . shellescape(expand("<afile>"))
3281 au FileReadPre *.gz call rename(expand("<afile>:r"), expand("<afile>"))
3282 au FileReadPost *.gz '[,']s/l/L/
3283 augroup END
3284
3285 new
3286 0r Xtestfile.gz " Read compressed file
3287 call assert_equal([
3288 \ 'Line 2 Abcdefghijklmnopqrstuvwxyz',
3289 \ 'Line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3290 \ 'Line 4 Abcdefghijklmnopqrstuvwxyz',
3291 \ 'Line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3292 \ 'Line 6 Abcdefghijklmnopqrstuvwxyz',
3293 \ 'Line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3294 \ 'Line 8 Abcdefghijklmnopqrstuvwxyz',
3295 \ 'Line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3296 \ 'Line 10 Abcdefghijklmnopqrstuvwxyz'
3297 \ ], getline(1, 9))
3298 call assert_equal([
3299 \ 'line 2 Abcdefghijklmnopqrstuvwxyz',
3300 \ 'line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3301 \ 'line 4 Abcdefghijklmnopqrstuvwxyz',
3302 \ 'line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3303 \ 'line 6 Abcdefghijklmnopqrstuvwxyz',
3304 \ 'line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3305 \ 'line 8 Abcdefghijklmnopqrstuvwxyz',
3306 \ 'line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
3307 \ 'line 10 Abcdefghijklmnopqrstuvwxyz'
3308 \ ], readfile('Xtestfile.gz'))
3309
3310 augroup Test5
3311 au!
3312 augroup END
3313
3314 au! FileChangedShell
3315 call delete('Xtestfile.gz')
Bram Moolenaar69ea5872019-04-25 20:29:00 +02003316 call delete('test.out')
3317endfunc
Bram Moolenaar23b51392019-05-09 21:38:43 +02003318
3319func Test_throw_in_BufWritePre()
3320 new
3321 call setline(1, ['one', 'two', 'three'])
3322 call assert_false(filereadable('Xthefile'))
3323 augroup throwing
3324 au BufWritePre X* throw 'do not write'
3325 augroup END
3326 try
3327 w Xthefile
3328 catch
3329 let caught = 1
3330 endtry
3331 call assert_equal(1, caught)
3332 call assert_false(filereadable('Xthefile'))
3333
3334 bwipe!
3335 au! throwing
3336endfunc
Bram Moolenaarcadbe1b2019-09-22 21:50:09 +02003337
Bram Moolenaar40fa12a2021-09-22 14:18:13 +02003338func Test_autocmd_in_try_block()
Bram Moolenaar6f14da12022-09-07 21:30:44 +01003339 call mkdir('Xintrydir', 'R')
Bram Moolenaar40fa12a2021-09-22 14:18:13 +02003340 au BufEnter * let g:fname = expand('%')
3341 try
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01003342 edit Xintrydir/
Bram Moolenaar40fa12a2021-09-22 14:18:13 +02003343 endtry
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01003344 call assert_match('Xintrydir', g:fname)
Bram Moolenaar40fa12a2021-09-22 14:18:13 +02003345
3346 unlet g:fname
3347 au! BufEnter
Bram Moolenaar40fa12a2021-09-22 14:18:13 +02003348endfunc
3349
Bram Moolenaarcadbe1b2019-09-22 21:50:09 +02003350func Test_autocmd_SafeState()
3351 CheckRunVimInTerminal
3352
3353 let lines =<< trim END
3354 let g:safe = 0
3355 let g:again = ''
3356 au SafeState * let g:safe += 1
3357 au SafeStateAgain * let g:again ..= 'x'
3358 func CallTimer()
3359 call timer_start(10, {id -> execute('let g:again ..= "t"')})
3360 endfunc
3361 END
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01003362 call writefile(lines, 'XSafeState', 'D')
Bram Moolenaarcadbe1b2019-09-22 21:50:09 +02003363 let buf = RunVimInTerminal('-S XSafeState', #{rows: 6})
3364
Bram Moolenaar8e7d6222020-12-18 19:49:56 +01003365 " Sometimes we loop to handle a K_IGNORE, SafeState may be triggered once or
Bram Moolenaar8fb1b472020-02-23 16:16:26 +01003366 " more often.
Bram Moolenaarcadbe1b2019-09-22 21:50:09 +02003367 call term_sendkeys(buf, ":echo g:safe\<CR>")
Bram Moolenaar8fb1b472020-02-23 16:16:26 +01003368 call WaitForAssert({-> assert_match('^\d ', term_getline(buf, 6))}, 1000)
Bram Moolenaarcadbe1b2019-09-22 21:50:09 +02003369
Bram Moolenaar8fb1b472020-02-23 16:16:26 +01003370 " SafeStateAgain should be invoked at least three times
Bram Moolenaarcadbe1b2019-09-22 21:50:09 +02003371 call term_sendkeys(buf, ":echo g:again\<CR>")
Bram Moolenaar8fb1b472020-02-23 16:16:26 +01003372 call WaitForAssert({-> assert_match('^xxx', term_getline(buf, 6))}, 1000)
Bram Moolenaarcadbe1b2019-09-22 21:50:09 +02003373
3374 call term_sendkeys(buf, ":let g:again = ''\<CR>:call CallTimer()\<CR>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02003375 call TermWait(buf, 50)
Bram Moolenaar0f6629a2019-09-22 23:24:13 +02003376 call term_sendkeys(buf, ":\<CR>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02003377 call TermWait(buf, 50)
Bram Moolenaarcadbe1b2019-09-22 21:50:09 +02003378 call term_sendkeys(buf, ":echo g:again\<CR>")
3379 call WaitForAssert({-> assert_match('xtx', term_getline(buf, 6))}, 1000)
3380
3381 call StopVimInTerminal(buf)
Bram Moolenaarcadbe1b2019-09-22 21:50:09 +02003382endfunc
Bram Moolenaar23324a02019-10-01 17:39:04 +02003383
3384func Test_autocmd_CmdWinEnter()
3385 CheckRunVimInTerminal
Bram Moolenaar21829c52021-01-26 22:42:21 +01003386
Bram Moolenaar23324a02019-10-01 17:39:04 +02003387 let lines =<< trim END
Egor Zvorykin125ffd22021-11-17 14:01:14 +00003388 augroup vimHints | au! | augroup END
Bram Moolenaar23324a02019-10-01 17:39:04 +02003389 let b:dummy_var = 'This is a dummy'
3390 autocmd CmdWinEnter * quit
3391 let winnr = winnr('$')
3392 END
Bram Moolenaar1cfb9bb2020-12-22 11:40:45 +01003393 let filename = 'XCmdWinEnter'
Bram Moolenaar23324a02019-10-01 17:39:04 +02003394 call writefile(lines, filename)
3395 let buf = RunVimInTerminal('-S '.filename, #{rows: 6})
3396
3397 call term_sendkeys(buf, "q:")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02003398 call TermWait(buf)
Bram Moolenaar23324a02019-10-01 17:39:04 +02003399 call term_sendkeys(buf, ":echo b:dummy_var\<cr>")
Bram Moolenaar353c3512020-03-15 14:19:26 +01003400 call WaitForAssert({-> assert_match('^This is a dummy', term_getline(buf, 6))}, 2000)
Bram Moolenaar23324a02019-10-01 17:39:04 +02003401 call term_sendkeys(buf, ":echo &buftype\<cr>")
3402 call WaitForAssert({-> assert_notmatch('^nofile', term_getline(buf, 6))}, 1000)
3403 call term_sendkeys(buf, ":echo winnr\<cr>")
3404 call WaitForAssert({-> assert_match('^1', term_getline(buf, 6))}, 1000)
3405
3406 " clean up
3407 call StopVimInTerminal(buf)
3408 call delete(filename)
3409endfunc
Bram Moolenaarec66c412019-10-11 21:19:13 +02003410
3411func Test_autocmd_was_using_freed_memory()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01003412 CheckFeature quickfix
3413
Bram Moolenaarec66c412019-10-11 21:19:13 +02003414 pedit xx
3415 n x
Bram Moolenaar92bb83e2021-02-03 23:04:46 +01003416 augroup winenter
3417 au WinEnter * if winnr('$') > 2 | quit | endif
3418 augroup END
Bram Moolenaarec66c412019-10-11 21:19:13 +02003419 split
Bram Moolenaar92bb83e2021-02-03 23:04:46 +01003420
3421 augroup winenter
3422 au! WinEnter
3423 augroup END
3424
3425 bwipe xx
3426 bwipe x
3427 pclose
Bram Moolenaarec66c412019-10-11 21:19:13 +02003428endfunc
Bram Moolenaarf4a1d1c2019-11-16 13:50:25 +01003429
3430func Test_BufWrite_lockmarks()
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +01003431 let g:test_is_flaky = 1
Bram Moolenaarf4a1d1c2019-11-16 13:50:25 +01003432 edit! Xtest
3433 call setline(1, ['a', 'b', 'c', 'd'])
3434
3435 " :lockmarks preserves the marks
3436 call SetChangeMarks(2, 3)
3437 lockmarks write
3438 call assert_equal([2, 3], [line("'["), line("']")])
3439
3440 " *WritePre autocmds get the correct line range, but lockmarks preserves the
3441 " original values for the user
3442 augroup lockmarks
3443 au!
3444 au BufWritePre,FilterWritePre * call assert_equal([1, 4], [line("'["), line("']")])
3445 au FileWritePre * call assert_equal([3, 4], [line("'["), line("']")])
3446 augroup END
3447
3448 lockmarks write
3449 call assert_equal([2, 3], [line("'["), line("']")])
3450
3451 if executable('cat')
3452 lockmarks %!cat
3453 call assert_equal([2, 3], [line("'["), line("']")])
3454 endif
3455
3456 lockmarks 3,4write Xtest2
3457 call assert_equal([2, 3], [line("'["), line("']")])
3458
3459 au! lockmarks
3460 augroup! lockmarks
3461 call delete('Xtest')
3462 call delete('Xtest2')
3463endfunc
Bram Moolenaarce6db022020-01-07 20:11:42 +01003464
3465func Test_FileType_spell()
3466 if !isdirectory('/tmp')
3467 throw "Skipped: requires /tmp directory"
3468 endif
3469
3470 " this was crashing with an invalid free()
3471 setglobal spellfile=/tmp/en.utf-8.add
3472 augroup crash
3473 autocmd!
3474 autocmd BufNewFile,BufReadPost crashfile setf somefiletype
3475 autocmd BufNewFile,BufReadPost crashfile set ft=anotherfiletype
3476 autocmd FileType anotherfiletype setlocal spell
3477 augroup END
3478 func! NoCrash() abort
3479 edit /tmp/crashfile
3480 endfunc
3481 call NoCrash()
3482
3483 au! crash
3484 setglobal spellfile=
3485endfunc
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01003486
Bram Moolenaaref976322022-09-28 11:48:30 +01003487" this was wiping out the current buffer and using freed memory
3488func Test_SpellFileMissing_bwipe()
3489 next 0
3490 au SpellFileMissing 0 bwipe
3491 call assert_fails('set spell spelllang=0', 'E937:')
3492
3493 au! SpellFileMissing
Bram Moolenaar0a60f792022-11-19 21:18:11 +00003494 set nospell spelllang=en
Bram Moolenaaref976322022-09-28 11:48:30 +01003495 bwipe
3496endfunc
3497
Bram Moolenaar406cd902020-02-18 21:54:41 +01003498" Test closing a window or editing another buffer from a FileChangedRO handler
3499" in a readonly buffer
3500func Test_FileChangedRO_winclose()
Bram Moolenaar62cd26a2020-10-11 20:08:44 +02003501 call test_override('ui_delay', 10)
3502
Bram Moolenaar406cd902020-02-18 21:54:41 +01003503 augroup FileChangedROTest
3504 au!
3505 autocmd FileChangedRO * quit
3506 augroup END
3507 new
3508 set readonly
3509 call assert_fails('normal i', 'E788:')
3510 close
3511 augroup! FileChangedROTest
3512
3513 augroup FileChangedROTest
3514 au!
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01003515 autocmd FileChangedRO * edit Xrofile
Bram Moolenaar406cd902020-02-18 21:54:41 +01003516 augroup END
3517 new
3518 set readonly
3519 call assert_fails('normal i', 'E788:')
3520 close
3521 augroup! FileChangedROTest
Bram Moolenaar62cd26a2020-10-11 20:08:44 +02003522 call test_override('ALL', 0)
Bram Moolenaar406cd902020-02-18 21:54:41 +01003523endfunc
3524
Bram Moolenaar0c81d1b2020-02-22 22:45:55 +01003525func LogACmd()
3526 call add(g:logged, line('$'))
3527endfunc
3528
3529func Test_TermChanged()
Bram Moolenaard28e0b32020-02-22 23:08:52 +01003530 CheckNotGui
3531
Bram Moolenaar0c81d1b2020-02-22 22:45:55 +01003532 enew!
3533 tabnew
3534 call setline(1, ['a', 'b', 'c', 'd'])
3535 $
3536 au TermChanged * call LogACmd()
3537 let g:logged = []
3538 let term_save = &term
3539 set term=xterm
3540 call assert_equal([1, 4], g:logged)
3541
3542 au! TermChanged
3543 let &term = term_save
3544 bwipe!
3545endfunc
3546
Bram Moolenaare3284872020-03-19 13:55:03 +01003547" Test for FileReadCmd autocmd
3548func Test_autocmd_FileReadCmd()
3549 func ReadFileCmd()
3550 call append(line('$'), "v:cmdarg = " .. v:cmdarg)
3551 endfunc
3552 augroup FileReadCmdTest
3553 au!
3554 au FileReadCmd Xtest call ReadFileCmd()
3555 augroup END
3556
3557 new
3558 read ++bin Xtest
3559 read ++nobin Xtest
3560 read ++edit Xtest
3561 read ++bad=keep Xtest
3562 read ++bad=drop Xtest
3563 read ++bad=- Xtest
3564 read ++ff=unix Xtest
3565 read ++ff=dos Xtest
3566 read ++ff=mac Xtest
3567 read ++enc=utf-8 Xtest
3568
3569 call assert_equal(['',
3570 \ 'v:cmdarg = ++bin',
3571 \ 'v:cmdarg = ++nobin',
3572 \ 'v:cmdarg = ++edit',
3573 \ 'v:cmdarg = ++bad=keep',
3574 \ 'v:cmdarg = ++bad=drop',
3575 \ 'v:cmdarg = ++bad=-',
3576 \ 'v:cmdarg = ++ff=unix',
3577 \ 'v:cmdarg = ++ff=dos',
3578 \ 'v:cmdarg = ++ff=mac',
3579 \ 'v:cmdarg = ++enc=utf-8'], getline(1, '$'))
3580
Bram Moolenaar23526d22022-12-05 15:50:41 +00003581 bwipe!
Bram Moolenaare3284872020-03-19 13:55:03 +01003582 augroup FileReadCmdTest
3583 au!
3584 augroup END
3585 delfunc ReadFileCmd
3586endfunc
3587
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02003588" Test for passing invalid arguments to autocmd
3589func Test_autocmd_invalid_args()
3590 " Additional character after * for event
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01003591 call assert_fails('autocmd *a Xinvfile set ff=unix', 'E215:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02003592 augroup Test
3593 augroup END
3594 " Invalid autocmd event
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01003595 call assert_fails('autocmd Bufabc Xinvfile set ft=vim', 'E216:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02003596 " Invalid autocmd event in a autocmd group
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01003597 call assert_fails('autocmd Test Bufabc Xinvfile set ft=vim', 'E216:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02003598 augroup! Test
3599 " Execute all autocmds
3600 call assert_fails('doautocmd * BufEnter', 'E217:')
3601 call assert_fails('augroup! x1a2b3', 'E367:')
3602 call assert_fails('autocmd BufNew <buffer=999> pwd', 'E680:')
Bram Moolenaar531be472020-09-23 22:38:05 +02003603 call assert_fails('autocmd BufNew \) set ff=unix', 'E55:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02003604endfunc
3605
3606" Test for deep nesting of autocmds
3607func Test_autocmd_deep_nesting()
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01003608 autocmd BufEnter Xdeepfile doautocmd BufEnter Xdeepfile
3609 call assert_fails('doautocmd BufEnter Xdeepfile', 'E218:')
3610 autocmd! BufEnter Xdeepfile
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02003611endfunc
3612
Bram Moolenaarbe5ee862020-06-10 20:56:58 +02003613" Tests for SigUSR1 autocmd event, which is only available on posix systems.
3614func Test_autocmd_sigusr1()
3615 CheckUnix
Bram Moolenaar0056ca72022-09-23 21:26:39 +01003616 " FIXME: should this work on MacOS M1?
3617 CheckNotMacM1
Bram Moolenaar62cd26a2020-10-11 20:08:44 +02003618 CheckExecutable /bin/kill
Bram Moolenaarbe5ee862020-06-10 20:56:58 +02003619
3620 let g:sigusr1_passed = 0
3621 au SigUSR1 * let g:sigusr1_passed = 1
3622 call system('/bin/kill -s usr1 ' . getpid())
3623 call WaitForAssert({-> assert_true(g:sigusr1_passed)})
3624
3625 au! SigUSR1
3626 unlet g:sigusr1_passed
3627endfunc
3628
Bram Moolenaarb340bae2020-06-15 19:51:56 +02003629" Test for BufReadPre autocmd deleting the file
3630func Test_BufReadPre_delfile()
3631 augroup TestAuCmd
3632 au!
Bram Moolenaare7cda972022-08-29 11:02:59 +01003633 autocmd BufReadPre XbufreadPre call delete('XbufreadPre')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02003634 augroup END
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01003635 call writefile([], 'XbufreadPre', 'D')
Bram Moolenaare7cda972022-08-29 11:02:59 +01003636 call assert_fails('new XbufreadPre', 'E200:')
3637 call assert_equal('XbufreadPre', @%)
Bram Moolenaarb340bae2020-06-15 19:51:56 +02003638 call assert_equal(1, &readonly)
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01003639
Bram Moolenaarb340bae2020-06-15 19:51:56 +02003640 augroup TestAuCmd
3641 au!
3642 augroup END
3643 close!
3644endfunc
3645
3646" Test for BufReadPre autocmd changing the current buffer
3647func Test_BufReadPre_changebuf()
3648 augroup TestAuCmd
3649 au!
Bram Moolenaare7cda972022-08-29 11:02:59 +01003650 autocmd BufReadPre Xchangebuf edit Xsomeotherfile
Bram Moolenaarb340bae2020-06-15 19:51:56 +02003651 augroup END
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01003652 call writefile([], 'Xchangebuf', 'D')
Bram Moolenaare7cda972022-08-29 11:02:59 +01003653 call assert_fails('new Xchangebuf', 'E201:')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02003654 call assert_equal('Xsomeotherfile', @%)
3655 call assert_equal(1, &readonly)
Bram Moolenaare1f3ab72022-09-04 21:29:08 +01003656
Bram Moolenaarb340bae2020-06-15 19:51:56 +02003657 augroup TestAuCmd
3658 au!
3659 augroup END
3660 close!
3661endfunc
3662
3663" Test for BufWipeouti autocmd changing the current buffer when reading a file
3664" in an empty buffer with 'f' flag in 'cpo'
3665func Test_BufDelete_changebuf()
3666 new
3667 augroup TestAuCmd
3668 au!
3669 autocmd BufWipeout * let bufnr = bufadd('somefile') | exe "b " .. bufnr
3670 augroup END
3671 let save_cpo = &cpo
3672 set cpo+=f
Bram Moolenaarb18b4962022-09-02 21:55:50 +01003673 call assert_fails('r Xchangebuf', ['E812:', 'E484:'])
Bram Moolenaarb340bae2020-06-15 19:51:56 +02003674 call assert_equal('somefile', @%)
3675 let &cpo = save_cpo
3676 augroup TestAuCmd
3677 au!
3678 augroup END
3679 close!
3680endfunc
3681
Bram Moolenaar0fe937f2020-06-16 22:42:04 +02003682" Test for the temporary internal window used to execute autocmds
3683func Test_autocmd_window()
3684 %bw!
3685 edit one.txt
3686 tabnew two.txt
Bram Moolenaar41cd8032021-03-13 15:47:56 +01003687 vnew three.txt
3688 tabnew four.txt
3689 tabprevious
Bram Moolenaar0fe937f2020-06-16 22:42:04 +02003690 let g:blist = []
Bram Moolenaar832adf92020-06-25 19:01:36 +02003691 augroup aucmd_win_test1
Bram Moolenaar0fe937f2020-06-16 22:42:04 +02003692 au!
3693 au BufEnter * call add(g:blist, [expand('<afile>'),
3694 \ win_gettype(bufwinnr(expand('<afile>')))])
3695 augroup END
3696
3697 doautoall BufEnter
Bram Moolenaar41cd8032021-03-13 15:47:56 +01003698 call assert_equal([
3699 \ ['one.txt', 'autocmd'],
3700 \ ['two.txt', ''],
3701 \ ['four.txt', 'autocmd'],
3702 \ ['three.txt', ''],
3703 \ ], g:blist)
Bram Moolenaar0fe937f2020-06-16 22:42:04 +02003704
Bram Moolenaar832adf92020-06-25 19:01:36 +02003705 augroup aucmd_win_test1
Bram Moolenaar0fe937f2020-06-16 22:42:04 +02003706 au!
3707 augroup END
Bram Moolenaar832adf92020-06-25 19:01:36 +02003708 augroup! aucmd_win_test1
3709 %bw!
3710endfunc
3711
3712" Test for trying to close the temporary window used for executing an autocmd
3713func Test_close_autocmd_window()
3714 %bw!
3715 edit one.txt
3716 tabnew two.txt
3717 augroup aucmd_win_test2
3718 au!
3719 au BufEnter * if expand('<afile>') == 'one.txt' | 1close | endif
3720 augroup END
3721
3722 call assert_fails('doautoall BufEnter', 'E813:')
3723
3724 augroup aucmd_win_test2
3725 au!
3726 augroup END
3727 augroup! aucmd_win_test2
Bram Moolenaarcf844172020-06-26 19:44:06 +02003728 %bwipe!
3729endfunc
3730
3731" Test for trying to close the tab that has the temporary window for exeucing
3732" an autocmd.
3733func Test_close_autocmd_tab()
3734 edit one.txt
3735 tabnew two.txt
3736 augroup aucmd_win_test
3737 au!
3738 au BufEnter * if expand('<afile>') == 'one.txt' | tabfirst | tabonly | endif
3739 augroup END
3740
3741 call assert_fails('doautoall BufEnter', 'E813:')
3742
3743 tabonly
3744 augroup aucmd_win_test
3745 au!
3746 augroup END
3747 augroup! aucmd_win_test
3748 %bwipe!
Bram Moolenaar0fe937f2020-06-16 22:42:04 +02003749endfunc
3750
Bram Moolenaarcb1956d2022-01-07 15:45:18 +00003751func Test_Visual_doautoall_redraw()
3752 call setline(1, ['a', 'b'])
Bram Moolenaar94722c52023-01-28 19:19:03 +00003753 new
Bram Moolenaarcb1956d2022-01-07 15:45:18 +00003754 wincmd p
3755 call feedkeys("G\<C-V>", 'txn')
3756 autocmd User Explode ++once redraw
3757 doautoall User Explode
3758 %bwipe!
3759endfunc
3760
zeertzjq5717ee32025-05-25 16:59:50 +02003761func Test_get_Visual_selection_in_curbuf_autocmd()
3762 call test_override('starting', 1)
3763 new
3764 autocmd OptionSet list let b:text = getregion(getpos('.'), getpos('v'))
3765 call setline(1, 'foo bar baz')
3766
3767 normal! gg0fbvtb
3768 setlocal list
3769 call assert_equal(['bar '], b:text)
3770 exe "normal! \<Esc>"
3771
3772 normal! v0
3773 call setbufvar('%', '&list', v:false)
3774 call assert_equal(['foo bar '], b:text)
3775 exe "normal! \<Esc>"
3776
3777 autocmd! OptionSet list
3778 bwipe!
3779 call test_override('starting', 0)
3780endfunc
3781
Bram Moolenaar6bcb8772021-02-03 21:23:29 +01003782" This was using freed memory.
3783func Test_BufNew_arglocal()
3784 arglocal
3785 au BufNew * arglocal
3786 call assert_fails('drop xx', 'E1156:')
3787
3788 au! BufNew
3789endfunc
3790
Bram Moolenaar8ab37572021-02-03 21:56:59 +01003791func Test_autocmd_closes_window()
3792 au BufNew,BufWinLeave * e %e
3793 file yyy
3794 au BufNew,BufWinLeave * ball
Bram Moolenaaraad5f9d2021-02-06 17:30:31 +01003795 n xxx
Bram Moolenaar8ab37572021-02-03 21:56:59 +01003796
Bram Moolenaaraad5f9d2021-02-06 17:30:31 +01003797 %bwipe
Bram Moolenaar8ab37572021-02-03 21:56:59 +01003798 au! BufNew
3799 au! BufWinLeave
3800endfunc
3801
Bram Moolenaar92bb83e2021-02-03 23:04:46 +01003802func Test_autocmd_quit_psearch()
3803 sn aa bb
3804 augroup aucmd_win_test
3805 au!
3806 au BufEnter,BufLeave,BufNew,WinEnter,WinLeave,WinNew * if winnr('$') > 1 | q | endif
3807 augroup END
3808 ps /
3809
3810 augroup aucmd_win_test
3811 au!
3812 augroup END
zeertzjq7851c692022-04-21 11:14:01 +01003813 new
3814 pclose
Bram Moolenaar92bb83e2021-02-03 23:04:46 +01003815endfunc
3816
Bram Moolenaaraad5f9d2021-02-06 17:30:31 +01003817" Fuzzer found some strange combination that caused a crash.
3818func Test_autocmd_normal_mess()
Bram Moolenaardd07c022021-02-07 13:32:46 +01003819 " For unknown reason this hangs on MS-Windows
3820 CheckNotMSWindows
3821
Bram Moolenaaraad5f9d2021-02-06 17:30:31 +01003822 augroup aucmd_normal_test
3823 au BufLeave,BufWinLeave,BufHidden,BufUnload,BufDelete,BufWipeout * norm 7q/qc
3824 augroup END
zeertzjq67fe77d2025-04-20 10:21:18 +02003825 call assert_fails('o4', 'E1159:')
Bram Moolenaaraad5f9d2021-02-06 17:30:31 +01003826 silent! H
zeertzjq67fe77d2025-04-20 10:21:18 +02003827 call assert_fails('e xx', 'E1159:')
Bram Moolenaaraad5f9d2021-02-06 17:30:31 +01003828 normal G
3829
3830 augroup aucmd_normal_test
3831 au!
3832 augroup END
3833endfunc
3834
Bram Moolenaar8c6951f2021-02-06 18:08:45 +01003835func Test_autocmd_closing_cmdwin()
Bram Moolenaardd07c022021-02-07 13:32:46 +01003836 " For unknown reason this hangs on MS-Windows
3837 CheckNotMSWindows
3838
Bram Moolenaar8c6951f2021-02-06 18:08:45 +01003839 au BufWinLeave * nested q
3840 call assert_fails("norm 7q?\n", 'E855:')
3841
3842 au! BufWinLeave
3843 new
3844 only
3845endfunc
3846
Bram Moolenaar2c7080b2021-02-06 19:19:42 +01003847func Test_autocmd_vimgrep()
3848 augroup aucmd_vimgrep
Charlie Grovesfef44852022-04-19 16:24:12 +01003849 au QuickfixCmdPre,BufNew,BufReadCmd * sb
zeertzjq7851c692022-04-21 11:14:01 +01003850 au QuickfixCmdPre,BufNew,BufReadCmd * q9
Bram Moolenaar2c7080b2021-02-06 19:19:42 +01003851 augroup END
Bram Moolenaardd07c022021-02-07 13:32:46 +01003852 call assert_fails('lv ?a? foo', 'E926:')
Bram Moolenaar2c7080b2021-02-06 19:19:42 +01003853
3854 augroup aucmd_vimgrep
3855 au!
3856 augroup END
3857endfunc
3858
Bram Moolenaar73b8b0a2021-08-01 14:52:32 +02003859func Test_autocmd_with_block()
3860 augroup block_testing
3861 au BufReadPost *.xml {
3862 setlocal matchpairs+=<:>
3863 /<start
3864 }
Bram Moolenaar63b91732021-08-05 20:40:03 +02003865 au CursorHold * {
3866 autocmd BufReadPre * ++once echo 'one' | echo 'two'
3867 g:gotSafeState = 77
3868 }
Bram Moolenaar73b8b0a2021-08-01 14:52:32 +02003869 augroup END
3870
Ken Takataeccc9272024-09-03 23:01:55 +02003871 let expected = gettext("\n--- Autocommands ---") .. "\nblock_testing BufRead\n *.xml {^@ setlocal matchpairs+=<:>^@ /<start^@ }"
Bram Moolenaar73b8b0a2021-08-01 14:52:32 +02003872 call assert_equal(expected, execute('au BufReadPost *.xml'))
3873
Bram Moolenaar63b91732021-08-05 20:40:03 +02003874 doautocmd CursorHold
3875 call assert_equal(77, g:gotSafeState)
3876 unlet g:gotSafeState
3877
Bram Moolenaar73b8b0a2021-08-01 14:52:32 +02003878 augroup block_testing
3879 au!
Bram Moolenaar75ebd2a2022-06-03 17:39:46 +01003880 autocmd CursorHold * {
3881 if true
3882 # comment
3883 && true
3884
3885 && true
3886 g:done = 'yes'
3887 endif
3888 }
3889 augroup END
3890 doautocmd CursorHold
3891 call assert_equal('yes', g:done)
3892
3893 unlet g:done
3894 augroup block_testing
3895 au!
Bram Moolenaar73b8b0a2021-08-01 14:52:32 +02003896 augroup END
3897endfunc
3898
Bram Moolenaar6f2465d2022-03-22 18:13:01 +00003899func Test_closing_autocmd_window()
3900 let lines =<< trim END
3901 edit Xa.txt
3902 tabnew Xb.txt
3903 autocmd BufEnter Xa.txt unhide 1
3904 doautoall BufEnter
3905 END
3906 call v9.CheckScriptFailure(lines, 'E814:')
3907 au! BufEnter
Bram Moolenaar6f2465d2022-03-22 18:13:01 +00003908 bwipe Xa.txt
3909 bwipe Xb.txt
3910endfunc
3911
zeertzjq46bdae02023-09-24 23:16:08 +02003912func Test_switch_window_in_autocmd_window()
3913 edit Xa.txt
3914 tabnew Xb.txt
3915 autocmd BufEnter Xa.txt wincmd w
3916 doautoall BufEnter
3917 au! BufEnter
3918 bwipe Xa.txt
3919 call assert_false(bufexists('Xa.txt'))
3920 bwipe Xb.txt
3921 call assert_false(bufexists('Xb.txt'))
3922endfunc
3923
zeertzjq9d956ee2024-04-07 18:16:10 +02003924" Test that using the autocommand window doesn't change current directory.
3925func Test_autocmd_window_cwd()
3926 let saveddir = getcwd()
3927 call mkdir('Xcwd/a/b/c/d', 'pR')
3928
3929 new Xa.txt
3930 tabnew
3931 new Xb.txt
3932
3933 tabprev
3934 cd Xcwd
3935 call assert_match('/Xcwd$', getcwd())
3936 call assert_match('\[global\] .*/Xcwd$', trim(execute('verbose pwd')))
3937
3938 autocmd BufEnter Xb.txt lcd ./a/b/c/d
3939 doautoall BufEnter
3940 au! BufEnter
3941 call assert_match('/Xcwd$', getcwd())
3942 call assert_match('\[global\] .*/Xcwd$', trim(execute('verbose pwd')))
3943
3944 tabnext
3945 cd ./a
3946 tcd ./b
3947 lcd ./c
3948 call assert_match('/Xcwd/a/b/c$', getcwd())
3949 call assert_match('\[window\] .*/Xcwd/a/b/c$', trim(execute('verbose pwd')))
3950
3951 autocmd BufEnter Xa.txt call assert_match('Xcwd/a/b/c$', getcwd())
3952 doautoall BufEnter
3953 au! BufEnter
3954 call assert_match('/Xcwd/a/b/c$', getcwd())
3955 call assert_match('\[window\] .*/Xcwd/a/b/c$', trim(execute('verbose pwd')))
3956 bwipe!
3957 call assert_match('/Xcwd/a/b$', getcwd())
3958 call assert_match('\[tabpage\] .*/Xcwd/a/b$', trim(execute('verbose pwd')))
3959 bwipe!
3960 call assert_match('/Xcwd/a$', getcwd())
3961 call assert_match('\[global\] .*/Xcwd/a$', trim(execute('verbose pwd')))
3962 bwipe!
3963
3964 call chdir(saveddir)
3965endfunc
3966
Bram Moolenaar347538f2022-03-26 16:28:06 +00003967func Test_bufwipeout_changes_window()
3968 " This should not crash, but we don't have any expectations about what
3969 " happens, changing window in BufWipeout has unpredictable results.
3970 tabedit
3971 let g:window_id = win_getid()
3972 topleft new
3973 setlocal bufhidden=wipe
3974 autocmd BufWipeout <buffer> call win_gotoid(g:window_id)
3975 tabprevious
3976 +tabclose
3977
3978 unlet g:window_id
3979 au! BufWipeout
3980 %bwipe!
3981endfunc
3982
zeertzjq021996f2022-04-10 11:44:04 +01003983func Test_v_event_readonly()
3984 autocmd CompleteChanged * let v:event.width = 0
3985 call assert_fails("normal! i\<C-X>\<C-V>", 'E46:')
3986 au! CompleteChanged
3987
3988 autocmd DirChangedPre * let v:event.directory = ''
3989 call assert_fails('cd .', 'E46:')
3990 au! DirChangedPre
3991
3992 autocmd ModeChanged * let v:event.new_mode = ''
3993 call assert_fails('normal! cc', 'E46:')
3994 au! ModeChanged
3995
3996 autocmd TextYankPost * let v:event.operator = ''
3997 call assert_fails('normal! yy', 'E46:')
3998 au! TextYankPost
3999endfunc
4000
zeertzjqc9e8fd62022-07-26 18:12:38 +01004001" Test for ModeChanged pattern
4002func Test_mode_changes()
4003 let g:index = 0
zeertzjq73916ba2023-04-26 16:50:19 +01004004 let g:mode_seq = ['n', 'i', 'n', 'v', 'V', 'i', 'ix', 'i', 'ic', 'i', 'n', 'no', 'noV', 'n', 'V', 'v', 's', 'n']
zeertzjqc9e8fd62022-07-26 18:12:38 +01004005 func! TestMode()
4006 call assert_equal(g:mode_seq[g:index], get(v:event, "old_mode"))
4007 call assert_equal(g:mode_seq[g:index + 1], get(v:event, "new_mode"))
4008 call assert_equal(mode(1), get(v:event, "new_mode"))
4009 let g:index += 1
4010 endfunc
4011
4012 au ModeChanged * :call TestMode()
4013 let g:n_to_any = 0
4014 au ModeChanged n:* let g:n_to_any += 1
zeertzjq73916ba2023-04-26 16:50:19 +01004015 call feedkeys("i\<esc>vVca\<CR>\<C-X>\<C-L>\<esc>ggdV\<MouseMove>G", 'tnix')
zeertzjqc9e8fd62022-07-26 18:12:38 +01004016
4017 let g:V_to_v = 0
4018 au ModeChanged V:v let g:V_to_v += 1
4019 call feedkeys("Vv\<C-G>\<esc>", 'tnix')
4020 call assert_equal(len(filter(g:mode_seq[1:], {idx, val -> val == 'n'})), g:n_to_any)
4021 call assert_equal(1, g:V_to_v)
4022 call assert_equal(len(g:mode_seq) - 1, g:index)
4023
4024 let g:n_to_i = 0
4025 au ModeChanged n:i let g:n_to_i += 1
4026 let g:n_to_niI = 0
4027 au ModeChanged i:niI let g:n_to_niI += 1
4028 let g:niI_to_i = 0
4029 au ModeChanged niI:i let g:niI_to_i += 1
4030 let g:nany_to_i = 0
4031 au ModeChanged n*:i let g:nany_to_i += 1
4032 let g:i_to_n = 0
4033 au ModeChanged i:n let g:i_to_n += 1
4034 let g:nori_to_any = 0
4035 au ModeChanged [ni]:* let g:nori_to_any += 1
4036 let g:i_to_any = 0
4037 au ModeChanged i:* let g:i_to_any += 1
4038 let g:index = 0
4039 let g:mode_seq = ['n', 'i', 'niI', 'i', 'n']
4040 call feedkeys("a\<C-O>l\<esc>", 'tnix')
4041 call assert_equal(len(g:mode_seq) - 1, g:index)
4042 call assert_equal(1, g:n_to_i)
4043 call assert_equal(1, g:n_to_niI)
4044 call assert_equal(1, g:niI_to_i)
4045 call assert_equal(2, g:nany_to_i)
4046 call assert_equal(1, g:i_to_n)
4047 call assert_equal(2, g:i_to_any)
4048 call assert_equal(3, g:nori_to_any)
4049
4050 if has('terminal')
4051 let g:mode_seq += ['c', 'n', 't', 'nt', 'c', 'nt', 'n']
4052 call feedkeys(":term\<CR>\<C-W>N:bd!\<CR>", 'tnix')
4053 call assert_equal(len(g:mode_seq) - 1, g:index)
4054 call assert_equal(1, g:n_to_i)
4055 call assert_equal(1, g:n_to_niI)
4056 call assert_equal(1, g:niI_to_i)
4057 call assert_equal(2, g:nany_to_i)
4058 call assert_equal(1, g:i_to_n)
4059 call assert_equal(2, g:i_to_any)
4060 call assert_equal(5, g:nori_to_any)
4061 endif
4062
zeertzjqd1955982022-10-05 11:24:46 +01004063 let g:n_to_c = 0
4064 au ModeChanged n:c let g:n_to_c += 1
4065 let g:c_to_n = 0
4066 au ModeChanged c:n let g:c_to_n += 1
4067 let g:mode_seq += ['c', 'n', 'c', 'n']
4068 call feedkeys("q:\<C-C>\<Esc>", 'tnix')
4069 call assert_equal(len(g:mode_seq) - 1, g:index)
4070 call assert_equal(2, g:n_to_c)
4071 call assert_equal(2, g:c_to_n)
zeertzjqc9e8fd62022-07-26 18:12:38 +01004072
Bram Moolenaar61c4b042022-10-18 15:10:11 +01004073 let g:n_to_v = 0
4074 au ModeChanged n:v let g:n_to_v += 1
4075 let g:v_to_n = 0
4076 au ModeChanged v:n let g:v_to_n += 1
4077 let g:mode_seq += ['v', 'n']
4078 call feedkeys("v\<C-C>", 'tnix')
4079 call assert_equal(len(g:mode_seq) - 1, g:index)
4080 call assert_equal(1, g:n_to_v)
4081 call assert_equal(1, g:v_to_n)
zeertzjqfcaeb3d2023-11-28 20:46:29 +01004082
4083 let g:mode_seq += ['c', 'cr', 'c', 'cr', 'n']
4084 call feedkeys(":\<Insert>\<Insert>\<Insert>\<CR>", 'tnix')
4085 call assert_equal(len(g:mode_seq) - 1, g:index)
Bram Moolenaar61c4b042022-10-18 15:10:11 +01004086
zeertzjqc9e8fd62022-07-26 18:12:38 +01004087 au! ModeChanged
4088 delfunc TestMode
4089 unlet! g:mode_seq
4090 unlet! g:index
4091 unlet! g:n_to_any
4092 unlet! g:V_to_v
4093 unlet! g:n_to_i
4094 unlet! g:n_to_niI
4095 unlet! g:niI_to_i
4096 unlet! g:nany_to_i
4097 unlet! g:i_to_n
4098 unlet! g:nori_to_any
4099 unlet! g:i_to_any
zeertzjqfcaeb3d2023-11-28 20:46:29 +01004100 unlet! g:n_to_c
4101 unlet! g:c_to_n
4102 unlet! g:n_to_v
4103 unlet! g:v_to_n
zeertzjqc9e8fd62022-07-26 18:12:38 +01004104endfunc
4105
4106func Test_recursive_ModeChanged()
4107 au! ModeChanged * norm 0u
4108 sil! norm 
4109 au! ModeChanged
4110endfunc
4111
4112func Test_ModeChanged_starts_visual()
4113 " This was triggering ModeChanged before setting VIsual, causing a crash.
4114 au! ModeChanged * norm 0u
4115 sil! norm 
4116
4117 au! ModeChanged
4118endfunc
Bram Moolenaar347538f2022-03-26 16:28:06 +00004119
Charlie Grovesfef44852022-04-19 16:24:12 +01004120func Test_noname_autocmd()
4121 augroup test_noname_autocmd_group
4122 autocmd!
4123 autocmd BufEnter * call add(s:li, ["BufEnter", expand("<afile>")])
4124 autocmd BufDelete * call add(s:li, ["BufDelete", expand("<afile>")])
4125 autocmd BufLeave * call add(s:li, ["BufLeave", expand("<afile>")])
4126 autocmd BufUnload * call add(s:li, ["BufUnload", expand("<afile>")])
4127 autocmd BufWipeout * call add(s:li, ["BufWipeout", expand("<afile>")])
4128 augroup END
4129
4130 let s:li = []
4131 edit foo
4132 call assert_equal([['BufUnload', ''], ['BufDelete', ''], ['BufWipeout', ''], ['BufEnter', 'foo']], s:li)
4133
4134 au! test_noname_autocmd_group
4135 augroup! test_noname_autocmd_group
4136endfunc
4137
Yegappan Lakshmanan1755a912022-05-19 10:31:47 +01004138" Test for the autocmd_get() function
4139func Test_autocmd_get()
4140 augroup TestAutoCmdFns
4141 au!
4142 autocmd BufAdd *.vim echo "bufadd-vim"
4143 autocmd BufAdd *.py echo "bufadd-py"
4144 autocmd BufHidden *.vim echo "bufhidden"
4145 augroup END
4146 augroup TestAutoCmdFns2
4147 autocmd BufAdd *.vim echo "bufadd-vim-2"
4148 autocmd BufRead *.a1b2c3 echo "bufadd-vim-2"
4149 augroup END
4150
4151 let l = autocmd_get()
4152 call assert_true(l->len() > 0)
4153
4154 " Test for getting all the autocmds in a group
4155 let expected = [
4156 \ #{cmd: 'echo "bufadd-vim"', group: 'TestAutoCmdFns',
4157 \ pattern: '*.vim', nested: v:false, once: v:false,
4158 \ event: 'BufAdd'},
4159 \ #{cmd: 'echo "bufadd-py"', group: 'TestAutoCmdFns',
4160 \ pattern: '*.py', nested: v:false, once: v:false,
4161 \ event: 'BufAdd'},
4162 \ #{cmd: 'echo "bufhidden"', group: 'TestAutoCmdFns',
4163 \ pattern: '*.vim', nested: v:false,
4164 \ once: v:false, event: 'BufHidden'}]
4165 call assert_equal(expected, autocmd_get(#{group: 'TestAutoCmdFns'}))
4166
4167 " Test for getting autocmds for all the patterns in a group
4168 call assert_equal(expected, autocmd_get(#{group: 'TestAutoCmdFns',
4169 \ event: '*'}))
4170
4171 " Test for getting autocmds for an event in a group
4172 let expected = [
4173 \ #{cmd: 'echo "bufadd-vim"', group: 'TestAutoCmdFns',
4174 \ pattern: '*.vim', nested: v:false, once: v:false,
4175 \ event: 'BufAdd'},
4176 \ #{cmd: 'echo "bufadd-py"', group: 'TestAutoCmdFns',
4177 \ pattern: '*.py', nested: v:false, once: v:false,
4178 \ event: 'BufAdd'}]
4179 call assert_equal(expected, autocmd_get(#{group: 'TestAutoCmdFns',
4180 \ event: 'BufAdd'}))
4181
4182 " Test for getting the autocmds for all the events in a group for particular
4183 " pattern
4184 call assert_equal([{'cmd': 'echo "bufadd-py"', 'group': 'TestAutoCmdFns',
4185 \ 'pattern': '*.py', 'nested': v:false, 'once': v:false,
4186 \ 'event': 'BufAdd'}],
4187 \ autocmd_get(#{group: 'TestAutoCmdFns', event: '*', pattern: '*.py'}))
4188
4189 " Test for getting the autocmds for an events in a group for particular
4190 " pattern
4191 let l = autocmd_get(#{group: 'TestAutoCmdFns', event: 'BufAdd',
4192 \ pattern: '*.vim'})
4193 call assert_equal([
4194 \ #{cmd: 'echo "bufadd-vim"', group: 'TestAutoCmdFns',
4195 \ pattern: '*.vim', nested: v:false, once: v:false,
4196 \ event: 'BufAdd'}], l)
4197
4198 " Test for getting the autocmds for a pattern in a group
4199 let l = autocmd_get(#{group: 'TestAutoCmdFns', pattern: '*.vim'})
4200 call assert_equal([
4201 \ #{cmd: 'echo "bufadd-vim"', group: 'TestAutoCmdFns',
4202 \ pattern: '*.vim', nested: v:false, once: v:false,
4203 \ event: 'BufAdd'},
4204 \ #{cmd: 'echo "bufhidden"', group: 'TestAutoCmdFns',
4205 \ pattern: '*.vim', nested: v:false,
4206 \ once: v:false, event: 'BufHidden'}], l)
4207
4208 " Test for getting the autocmds for a pattern in all the groups
4209 let l = autocmd_get(#{pattern: '*.a1b2c3'})
4210 call assert_equal([{'cmd': 'echo "bufadd-vim-2"', 'group': 'TestAutoCmdFns2',
4211 \ 'pattern': '*.a1b2c3', 'nested': v:false, 'once': v:false,
4212 \ 'event': 'BufRead'}], l)
4213
4214 " Test for getting autocmds for a pattern without any autocmds
4215 call assert_equal([], autocmd_get(#{group: 'TestAutoCmdFns',
4216 \ pattern: '*.abc'}))
4217 call assert_equal([], autocmd_get(#{group: 'TestAutoCmdFns',
4218 \ event: 'BufAdd', pattern: '*.abc'}))
4219 call assert_equal([], autocmd_get(#{group: 'TestAutoCmdFns',
4220 \ event: 'BufWipeout'}))
zeertzjq2d1d5c62024-06-09 16:44:33 +02004221
4222 " Test for getting autocmds after removing one inside an autocmd
4223 func CheckAutocmdGet()
4224 augroup TestAutoCmdFns
4225 autocmd! BufAdd *.vim
4226 augroup END
4227
4228 let expected = [
4229 \ #{cmd: 'echo "bufadd-py"', group: 'TestAutoCmdFns',
4230 \ pattern: '*.py', nested: v:false, once: v:false,
4231 \ event: 'BufAdd'},
4232 \ #{cmd: 'echo "bufhidden"', group: 'TestAutoCmdFns',
4233 \ pattern: '*.vim', nested: v:false,
4234 \ once: v:false, event: 'BufHidden'}]
4235
4236 call assert_equal(expected, autocmd_get(#{group: 'TestAutoCmdFns'}))
4237 call assert_equal([expected[0]],
4238 \ autocmd_get(#{group: 'TestAutoCmdFns', pattern: '*.py'}))
4239 call assert_equal([expected[1]],
4240 \ autocmd_get(#{group: 'TestAutoCmdFns', pattern: '*.vim'}))
4241 endfunc
4242
4243 autocmd User Xauget call CheckAutocmdGet()
4244 doautocmd User Xauget
4245 autocmd! User Xauget
4246
Yegappan Lakshmanan1755a912022-05-19 10:31:47 +01004247 call assert_fails("call autocmd_get(#{group: 'abc', event: 'BufAdd'})",
4248 \ 'E367:')
4249 let cmd = "echo autocmd_get(#{group: 'TestAutoCmdFns', event: 'abc'})"
4250 call assert_fails(cmd, 'E216:')
4251 call assert_fails("call autocmd_get(#{group: 'abc'})", 'E367:')
4252 call assert_fails("echo autocmd_get(#{event: 'abc'})", 'E216:')
4253
4254 augroup TestAutoCmdFns
4255 au!
4256 augroup END
4257 call assert_equal([], autocmd_get(#{group: 'TestAutoCmdFns'}))
4258
4259 " Test for nested and once autocmds
4260 augroup TestAutoCmdFns
4261 au!
4262 autocmd VimSuspend * ++nested echo "suspend"
4263 autocmd VimResume * ++once echo "resume"
4264 augroup END
4265
4266 let expected = [
Yegappan Lakshmanan1755a912022-05-19 10:31:47 +01004267 \ {'cmd': 'echo "resume"', 'group': 'TestAutoCmdFns', 'pattern': '*',
Luuk van Baalb7147f82025-02-08 18:52:39 +01004268 \ 'nested': v:false, 'once': v:true, 'event': 'VimResume'},
4269 \ {'cmd': 'echo "suspend"', 'group': 'TestAutoCmdFns', 'pattern': '*',
4270 \ 'nested': v:true, 'once': v:false, 'event': 'VimSuspend'}]
Yegappan Lakshmanan1755a912022-05-19 10:31:47 +01004271 call assert_equal(expected, autocmd_get(#{group: 'TestAutoCmdFns'}))
4272
4273 " Test for buffer-local autocmd
4274 augroup TestAutoCmdFns
4275 au!
4276 autocmd TextYankPost <buffer> echo "textyankpost"
4277 augroup END
4278
4279 let expected = [
4280 \ {'cmd': 'echo "textyankpost"', 'group': 'TestAutoCmdFns',
4281 \ 'pattern': '<buffer=' .. bufnr() .. '>', 'nested': v:false,
4282 \ 'once': v:false, 'bufnr': bufnr(), 'event': 'TextYankPost'}]
4283 call assert_equal(expected, autocmd_get(#{group: 'TestAutoCmdFns'}))
4284
4285 augroup TestAutoCmdFns
4286 au!
4287 augroup END
4288 augroup! TestAutoCmdFns
4289 augroup TestAutoCmdFns2
4290 au!
4291 augroup END
4292 augroup! TestAutoCmdFns2
4293
4294 call assert_fails("echo autocmd_get(#{group: []})", 'E730:')
4295 call assert_fails("echo autocmd_get(#{event: {}})", 'E731:')
4296 call assert_fails("echo autocmd_get([])", 'E1206:')
4297endfunc
4298
4299" Test for the autocmd_add() function
4300func Test_autocmd_add()
4301 " Define a single autocmd in a group
4302 call autocmd_add([#{group: 'TestAcSet', event: 'BufAdd', pattern: '*.sh',
4303 \ cmd: 'echo "bufadd"', once: v:true, nested: v:true}])
4304 call assert_equal([#{cmd: 'echo "bufadd"', group: 'TestAcSet',
4305 \ pattern: '*.sh', nested: v:true, once: v:true,
4306 \ event: 'BufAdd'}], autocmd_get(#{group: 'TestAcSet'}))
4307
4308 " Define two autocmds in the same group
4309 call autocmd_delete([#{group: 'TestAcSet'}])
4310 call autocmd_add([#{group: 'TestAcSet', event: 'BufAdd', pattern: '*.sh',
4311 \ cmd: 'echo "bufadd"'},
4312 \ #{group: 'TestAcSet', event: 'BufEnter', pattern: '*.sh',
4313 \ cmd: 'echo "bufenter"'}])
4314 call assert_equal([
4315 \ #{cmd: 'echo "bufadd"', group: 'TestAcSet', pattern: '*.sh',
4316 \ nested: v:false, once: v:false, event: 'BufAdd'},
4317 \ #{cmd: 'echo "bufenter"', group: 'TestAcSet', pattern: '*.sh',
4318 \ nested: v:false, once: v:false, event: 'BufEnter'}],
4319 \ autocmd_get(#{group: 'TestAcSet'}))
4320
4321 " Define a buffer-local autocmd
4322 call autocmd_delete([#{group: 'TestAcSet'}])
4323 call autocmd_add([#{group: 'TestAcSet', event: 'CursorHold',
4324 \ bufnr: bufnr(), cmd: 'echo "cursorhold"'}])
4325 call assert_equal([
4326 \ #{cmd: 'echo "cursorhold"', group: 'TestAcSet',
4327 \ pattern: '<buffer=' .. bufnr() .. '>', nested: v:false,
4328 \ once: v:false, bufnr: bufnr(), event: 'CursorHold'}],
4329 \ autocmd_get(#{group: 'TestAcSet'}))
4330
4331 " Use an invalid buffer number
4332 call autocmd_delete([#{group: 'TestAcSet'}])
4333 call autocmd_add([#{group: 'TestAcSet', event: 'BufEnter',
4334 \ bufnr: -1, cmd: 'echo "bufenter"'}])
4335 let l = [#{group: 'TestAcSet', event: 'BufAdd', bufnr: 9999,
4336 \ cmd: 'echo "bufadd"'}]
4337 call assert_fails("echo autocmd_add(l)", 'E680:')
Yegappan Lakshmanan00e977c2022-06-01 12:31:53 +01004338 let l = [#{group: 'TestAcSet', event: 'BufAdd', bufnr: 9999,
4339 \ pattern: '*.py', cmd: 'echo "bufadd"'}]
4340 call assert_fails("echo autocmd_add(l)", 'E680:')
4341 let l = [#{group: 'TestAcSet', event: 'BufAdd', bufnr: 9999,
4342 \ pattern: ['*.py', '*.c'], cmd: 'echo "bufadd"'}]
4343 call assert_fails("echo autocmd_add(l)", 'E680:')
Yegappan Lakshmanan1755a912022-05-19 10:31:47 +01004344 let l = [#{group: 'TestAcSet', event: 'BufRead', bufnr: [],
4345 \ cmd: 'echo "bufread"'}]
4346 call assert_fails("echo autocmd_add(l)", 'E745:')
4347 call assert_equal([], autocmd_get(#{group: 'TestAcSet'}))
4348
4349 " Add two commands to the same group, event and pattern
4350 call autocmd_delete([#{group: 'TestAcSet'}])
4351 call autocmd_add([#{group: 'TestAcSet', event: 'BufUnload',
4352 \ pattern: 'abc', cmd: 'echo "cmd1"'}])
4353 call autocmd_add([#{group: 'TestAcSet', event: 'BufUnload',
4354 \ pattern: 'abc', cmd: 'echo "cmd2"'}])
4355 call assert_equal([
4356 \ #{cmd: 'echo "cmd1"', group: 'TestAcSet', pattern: 'abc',
4357 \ nested: v:false, once: v:false, event: 'BufUnload'},
4358 \ #{cmd: 'echo "cmd2"', group: 'TestAcSet', pattern: 'abc',
4359 \ nested: v:false, once: v:false, event: 'BufUnload'}],
4360 \ autocmd_get(#{group: 'TestAcSet'}))
4361
4362 " When adding a new autocmd, if the autocmd 'group' is not specified, then
4363 " the current autocmd group should be used.
4364 call autocmd_delete([#{group: 'TestAcSet'}])
4365 augroup TestAcSet
4366 call autocmd_add([#{event: 'BufHidden', pattern: 'abc', cmd: 'echo "abc"'}])
4367 augroup END
4368 call assert_equal([
4369 \ #{cmd: 'echo "abc"', group: 'TestAcSet', pattern: 'abc',
4370 \ nested: v:false, once: v:false, event: 'BufHidden'}],
4371 \ autocmd_get(#{group: 'TestAcSet'}))
4372
Yegappan Lakshmanan971f6822022-05-24 11:40:11 +01004373 " Test for replacing a cmd for an event in a group
4374 call autocmd_delete([#{group: 'TestAcSet'}])
4375 call autocmd_add([#{replace: v:true, group: 'TestAcSet', event: 'BufEnter',
4376 \ pattern: '*.py', cmd: 'echo "bufenter"'}])
4377 call autocmd_add([#{replace: v:true, group: 'TestAcSet', event: 'BufEnter',
4378 \ pattern: '*.py', cmd: 'echo "bufenter"'}])
4379 call assert_equal([
4380 \ #{cmd: 'echo "bufenter"', group: 'TestAcSet', pattern: '*.py',
4381 \ nested: v:false, once: v:false, event: 'BufEnter'}],
4382 \ autocmd_get(#{group: 'TestAcSet'}))
4383
4384 " Test for adding a command for an unsupported autocmd event
Yegappan Lakshmanan1755a912022-05-19 10:31:47 +01004385 let l = [#{group: 'TestAcSet', event: 'abc', pattern: '*.sh',
4386 \ cmd: 'echo "bufadd"'}]
4387 call assert_fails('call autocmd_add(l)', 'E216:')
4388
Yegappan Lakshmanane0ff3a72022-05-27 18:05:33 +01004389 " Test for using a list of events and patterns
4390 call autocmd_delete([#{group: 'TestAcSet'}])
4391 let l = [#{group: 'TestAcSet', event: ['BufEnter', 'BufLeave'],
4392 \ pattern: ['*.py', '*.sh'], cmd: 'echo "bufcmds"'}]
4393 call autocmd_add(l)
4394 call assert_equal([
4395 \ #{cmd: 'echo "bufcmds"', group: 'TestAcSet', pattern: '*.py',
4396 \ nested: v:false, once: v:false, event: 'BufEnter'},
4397 \ #{cmd: 'echo "bufcmds"', group: 'TestAcSet', pattern: '*.sh',
4398 \ nested: v:false, once: v:false, event: 'BufEnter'},
4399 \ #{cmd: 'echo "bufcmds"', group: 'TestAcSet', pattern: '*.py',
4400 \ nested: v:false, once: v:false, event: 'BufLeave'},
4401 \ #{cmd: 'echo "bufcmds"', group: 'TestAcSet', pattern: '*.sh',
4402 \ nested: v:false, once: v:false, event: 'BufLeave'}],
4403 \ autocmd_get(#{group: 'TestAcSet'}))
4404
4405 " Test for invalid values for 'event' item
4406 call autocmd_delete([#{group: 'TestAcSet'}])
4407 let l = [#{group: 'TestAcSet', event: test_null_string(),
4408 \ pattern: "*.py", cmd: 'echo "bufcmds"'}]
4409 call assert_fails('call autocmd_add(l)', 'E928:')
4410 let l = [#{group: 'TestAcSet', event: test_null_list(),
4411 \ pattern: "*.py", cmd: 'echo "bufcmds"'}]
4412 call assert_fails('call autocmd_add(l)', 'E714:')
4413 let l = [#{group: 'TestAcSet', event: {},
4414 \ pattern: "*.py", cmd: 'echo "bufcmds"'}]
4415 call assert_fails('call autocmd_add(l)', 'E777:')
4416 let l = [#{group: 'TestAcSet', event: [{}],
4417 \ pattern: "*.py", cmd: 'echo "bufcmds"'}]
4418 call assert_fails('call autocmd_add(l)', 'E928:')
4419 let l = [#{group: 'TestAcSet', event: [test_null_string()],
4420 \ pattern: "*.py", cmd: 'echo "bufcmds"'}]
4421 call assert_fails('call autocmd_add(l)', 'E928:')
4422 let l = [#{group: 'TestAcSet', event: 'BufEnter,BufLeave',
4423 \ pattern: '*.py', cmd: 'echo "bufcmds"'}]
4424 call assert_fails('call autocmd_add(l)', 'E216:')
4425 let l = [#{group: 'TestAcSet', event: [],
4426 \ pattern: "*.py", cmd: 'echo "bufcmds"'}]
4427 call autocmd_add(l)
4428 let l = [#{group: 'TestAcSet', event: [""],
4429 \ pattern: "*.py", cmd: 'echo "bufcmds"'}]
4430 call assert_fails('call autocmd_add(l)', 'E216:')
4431 let l = [#{group: 'TestAcSet', event: "",
4432 \ pattern: "*.py", cmd: 'echo "bufcmds"'}]
4433 call autocmd_add(l)
4434 call assert_equal([], autocmd_get(#{group: 'TestAcSet'}))
4435
4436 " Test for invalid values for 'pattern' item
4437 let l = [#{group: 'TestAcSet', event: "BufEnter",
4438 \ pattern: test_null_string(), cmd: 'echo "bufcmds"'}]
Yegappan Lakshmanan00e977c2022-06-01 12:31:53 +01004439 call assert_fails('call autocmd_add(l)', 'E928:')
Yegappan Lakshmanane0ff3a72022-05-27 18:05:33 +01004440 let l = [#{group: 'TestAcSet', event: "BufEnter",
4441 \ pattern: test_null_list(), cmd: 'echo "bufcmds"'}]
4442 call assert_fails('call autocmd_add(l)', 'E714:')
4443 let l = [#{group: 'TestAcSet', event: "BufEnter",
4444 \ pattern: {}, cmd: 'echo "bufcmds"'}]
4445 call assert_fails('call autocmd_add(l)', 'E777:')
4446 let l = [#{group: 'TestAcSet', event: "BufEnter",
4447 \ pattern: [{}], cmd: 'echo "bufcmds"'}]
4448 call assert_fails('call autocmd_add(l)', 'E928:')
4449 let l = [#{group: 'TestAcSet', event: "BufEnter",
4450 \ pattern: [test_null_string()], cmd: 'echo "bufcmds"'}]
4451 call assert_fails('call autocmd_add(l)', 'E928:')
4452 let l = [#{group: 'TestAcSet', event: "BufEnter",
4453 \ pattern: [], cmd: 'echo "bufcmds"'}]
4454 call autocmd_add(l)
4455 let l = [#{group: 'TestAcSet', event: "BufEnter",
4456 \ pattern: [""], cmd: 'echo "bufcmds"'}]
4457 call autocmd_add(l)
4458 let l = [#{group: 'TestAcSet', event: "BufEnter",
4459 \ pattern: "", cmd: 'echo "bufcmds"'}]
4460 call autocmd_add(l)
4461 call assert_equal([], autocmd_get(#{group: 'TestAcSet'}))
4462
4463 let l = [#{group: 'TestAcSet', event: 'BufEnter,abc,BufLeave',
4464 \ pattern: '*.py', cmd: 'echo "bufcmds"'}]
4465 call assert_fails('call autocmd_add(l)', 'E216:')
4466
Yegappan Lakshmanan1755a912022-05-19 10:31:47 +01004467 call assert_fails("call autocmd_add({})", 'E1211:')
4468 call assert_equal(v:false, autocmd_add(test_null_list()))
4469 call assert_true(autocmd_add([[]]))
4470 call assert_true(autocmd_add([test_null_dict()]))
4471
4472 augroup TestAcSet
4473 au!
4474 augroup END
4475
4476 call autocmd_add([#{group: 'TestAcSet'}])
4477 call autocmd_add([#{group: 'TestAcSet', event: 'BufAdd'}])
4478 call autocmd_add([#{group: 'TestAcSet', pat: '*.sh'}])
4479 call autocmd_add([#{group: 'TestAcSet', cmd: 'echo "a"'}])
4480 call autocmd_add([#{group: 'TestAcSet', event: 'BufAdd', pat: '*.sh'}])
4481 call autocmd_add([#{group: 'TestAcSet', event: 'BufAdd', cmd: 'echo "a"'}])
4482 call autocmd_add([#{group: 'TestAcSet', pat: '*.sh', cmd: 'echo "a"'}])
4483 call assert_equal([], autocmd_get(#{group: 'TestAcSet'}))
4484
4485 augroup! TestAcSet
4486endfunc
4487
4488" Test for deleting autocmd events and groups
4489func Test_autocmd_delete()
4490 " Delete an event in an autocmd group
4491 augroup TestAcSet
4492 au!
4493 au BufAdd *.sh echo "bufadd"
4494 au BufEnter *.sh echo "bufenter"
4495 augroup END
4496 call autocmd_delete([#{group: 'TestAcSet', event: 'BufAdd'}])
4497 call assert_equal([#{cmd: 'echo "bufenter"', group: 'TestAcSet',
4498 \ pattern: '*.sh', nested: v:false, once: v:false,
4499 \ event: 'BufEnter'}], autocmd_get(#{group: 'TestAcSet'}))
4500
4501 " Delete all the events in an autocmd group
4502 augroup TestAcSet
4503 au BufAdd *.sh echo "bufadd"
4504 augroup END
4505 call autocmd_delete([#{group: 'TestAcSet', event: '*'}])
4506 call assert_equal([], autocmd_get(#{group: 'TestAcSet'}))
4507
4508 " Delete a non-existing autocmd group
4509 call assert_fails("call autocmd_delete([#{group: 'abc'}])", 'E367:')
4510 " Delete a non-existing autocmd event
4511 let l = [#{group: 'TestAcSet', event: 'abc'}]
4512 call assert_fails("call autocmd_delete(l)", 'E216:')
4513 " Delete a non-existing autocmd pattern
4514 let l = [#{group: 'TestAcSet', event: 'BufAdd', pat: 'abc'}]
4515 call assert_true(autocmd_delete(l))
Yegappan Lakshmanan00e977c2022-06-01 12:31:53 +01004516 " Delete an autocmd for a non-existing buffer
4517 let l = [#{event: '*', bufnr: 9999, cmd: 'echo "x"'}]
4518 call assert_fails('call autocmd_delete(l)', 'E680:')
Yegappan Lakshmanan1755a912022-05-19 10:31:47 +01004519
4520 " Delete an autocmd group
4521 augroup TestAcSet
4522 au!
4523 au BufAdd *.sh echo "bufadd"
4524 au BufEnter *.sh echo "bufenter"
4525 augroup END
4526 call autocmd_delete([#{group: 'TestAcSet'}])
4527 call assert_fails("call autocmd_get(#{group: 'TestAcSet'})", 'E367:')
4528
4529 call assert_true(autocmd_delete([[]]))
4530 call assert_true(autocmd_delete([test_null_dict()]))
4531endfunc
4532
Bram Moolenaar8f3c3c62022-10-18 17:05:54 +01004533func Test_autocmd_split_dummy()
4534 " Autocommand trying to split a window containing a dummy buffer.
Bram Moolenaar94722c52023-01-28 19:19:03 +00004535 auto BufReadPre * exe "sbuf " .. expand("<abuf>")
Bram Moolenaar8f3c3c62022-10-18 17:05:54 +01004536 " Avoid the "W11" prompt
4537 au FileChangedShell * let v:fcs_choice = 'reload'
4538 func Xautocmd_changelist()
4539 cal writefile(['Xtestfile2:4:4'], 'Xerr')
4540 edit Xerr
4541 lex 'Xtestfile2:4:4'
4542 endfunc
4543 call Xautocmd_changelist()
Bram Moolenaar53c5c9f2022-10-18 17:25:03 +01004544 " Should get E86, but it doesn't always happen (timing?)
4545 silent! call Xautocmd_changelist()
Bram Moolenaar8f3c3c62022-10-18 17:05:54 +01004546
4547 au! BufReadPre
4548 au! FileChangedShell
4549 delfunc Xautocmd_changelist
4550 bwipe! Xerr
4551 call delete('Xerr')
4552endfunc
4553
Bram Moolenaare76062c2022-11-28 18:51:43 +00004554" This was crashing because there was only one window to execute autocommands
4555" in.
4556func Test_autocmd_nested_setbufvar()
4557 CheckFeature python3
4558
4559 set hidden
4560 edit Xaaa
4561 edit Xbbb
4562 call setline(1, 'bar')
4563 enew
4564 au BufWriteCmd Xbbb ++nested call setbufvar('Xaaa', '&ft', 'foo') | bw! Xaaa
4565 au FileType foo call py3eval('vim.current.buffer.options["cindent"]')
4566 wall
4567
4568 au! BufWriteCmd
4569 au! FileType foo
4570 set nohidden
4571 call delete('Xaaa')
4572 call delete('Xbbb')
4573 %bwipe!
4574endfunc
4575
Christian Brabandt9aee8ec2022-12-16 16:41:23 +00004576func SetupVimTest_shm()
4577 let g:bwe = []
4578 let g:brp = []
4579 set shortmess+=F
zeertzjq657b31f2023-04-15 21:28:02 +01004580 messages clear
Christian Brabandt9aee8ec2022-12-16 16:41:23 +00004581
4582 let dirname='XVimTestSHM'
4583 call mkdir(dirname, 'R')
4584 call writefile(['test'], dirname .. '/1')
4585 call writefile(['test'], dirname .. '/2')
4586 call writefile(['test'], dirname .. '/3')
4587
4588 augroup test
4589 autocmd!
4590 autocmd BufWinEnter * call add(g:bwe, $'BufWinEnter: {expand('<amatch>')}')
4591 autocmd BufReadPost * call add(g:brp, $'BufReadPost: {expand('<amatch>')}')
4592 augroup END
4593
4594 call setqflist([
4595 \ {'filename': dirname .. '/1', 'lnum': 1, 'col': 1, 'text': 'test', 'vcol': 0},
4596 \ {'filename': dirname .. '/2', 'lnum': 1, 'col': 1, 'text': 'test', 'vcol': 0},
4597 \ {'filename': dirname .. '/3', 'lnum': 1, 'col': 1, 'text': 'test', 'vcol': 0}
4598 \ ])
4599 cdo! substitute/test/TEST
4600
4601 " clean up
4602 noa enew!
4603 set shortmess&vim
4604 augroup test
4605 autocmd!
4606 augroup END
4607 augroup! test
4608endfunc
4609
4610func Test_autocmd_shortmess()
4611 CheckNotMSWindows
4612
4613 call SetupVimTest_shm()
4614 let output = execute(':mess')->split('\n')
4615
4616 let info = copy(output)->filter({idx, val -> val =~# '\d of 3'} )
4617 let bytes = copy(output)->filter({idx, val -> val =~# 'bytes'} )
4618
4619 " We test the following here:
4620 " BufReadPost should have been triggered 3 times, once per file
4621 " BufWinEnter should have been triggered 3 times, once per file
4622 " FileInfoMessage should have been shown 3 times, regardless of shm option
4623 " "(x of 3)" message from :cnext has been shown 3 times
4624
4625 call assert_equal(3, g:brp->len())
4626 call assert_equal(3, g:bwe->len())
4627 call assert_equal(3, info->len())
4628 call assert_equal(3, bytes->len())
4629
4630 delfunc SetupVimTest_shm
4631endfunc
Bram Moolenaare76062c2022-11-28 18:51:43 +00004632
Christian Brabandtf0d3d4a2024-02-15 20:15:04 +01004633func Test_autocmd_invalidates_undo_on_textchanged()
4634 CheckRunVimInTerminal
4635 let script =<< trim END
4636 set hidden
4637 " create quickfix list (at least 2 lines to move line)
4638 vimgrep /u/j %
4639
4640 " enter quickfix window
4641 cwindow
4642
4643 " set modifiable
4644 setlocal modifiable
4645
4646 " set autocmd to clear quickfix list
4647
4648 autocmd! TextChanged <buffer> call setqflist([])
4649 " move line
4650 move+1
4651 END
4652 call writefile(script, 'XTest_autocmd_invalidates_undo_on_textchanged', 'D')
4653 let buf = RunVimInTerminal('XTest_autocmd_invalidates_undo_on_textchanged', {'rows': 20})
4654 call term_sendkeys(buf, ":so %\<cr>")
4655 call term_sendkeys(buf, "G")
4656 call WaitForAssert({-> assert_match('^XTest_autocmd_invalidates_undo_on_textchanged\s*$', term_getline(buf, 20))}, 1000)
4657
4658 call StopVimInTerminal(buf)
4659endfunc
4660
Christian Brabandt55f8bba2024-02-28 23:32:00 +01004661func Test_autocmd_creates_new_buffer_on_bufleave()
4662 e a.txt
4663 e b.txt
4664 setlocal bufhidden=wipe
4665 autocmd BufLeave <buffer> diffsplit c.txt
4666 bn
4667 call assert_equal(1, winnr('$'))
4668 call assert_equal('a.txt', bufname('%'))
4669 bw a.txt
4670 bw c.txt
4671endfunc
4672
Colin Kennedye5f22802024-03-26 18:20:16 +01004673" Ensure `expected` was just recently written as a Vim session
4674func s:assert_session_path(expected)
4675 call assert_equal(a:expected, v:this_session)
4676endfunc
4677
4678" Check for `expected` after a session is written to-disk.
4679func s:watch_for_session_path(expected)
4680 execute 'autocmd SessionWritePost * ++once execute "call s:assert_session_path(\"'
4681 \ . a:expected
4682 \ . '\")"'
4683endfunc
4684
4685" Ensure v:this_session gets the full session path, if explicitly stated
4686func Test_explicit_session_absolute_path()
4687 %bwipeout!
4688
4689 let directory = getcwd()
4690
4691 let v:this_session = ""
4692 let name = "some_file.vim"
4693 let expected = fnamemodify(name, ":p")
4694 call s:watch_for_session_path(expected)
4695 execute "mksession! " .. expected
4696
4697 call delete(expected)
4698endfunc
4699
4700" Ensure v:this_session gets the full session path, if explicitly stated
4701func Test_explicit_session_relative_path()
4702 %bwipeout!
4703
4704 let directory = getcwd()
4705
4706 let v:this_session = ""
4707 let name = "some_file.vim"
4708 let expected = fnamemodify(name, ":p")
4709 call s:watch_for_session_path(expected)
4710 execute "mksession! " .. name
4711
4712 call delete(expected)
4713endfunc
4714
4715" Ensure v:this_session gets the full session path, if not specified
4716func Test_implicit_session()
4717 %bwipeout!
4718
4719 let directory = getcwd()
4720
4721 let v:this_session = ""
4722 let expected = fnamemodify("Session.vim", ":p")
4723 call s:watch_for_session_path(expected)
4724 mksession!
4725
4726 call delete(expected)
4727endfunc
4728
Christian Brabandt86032702024-03-31 18:38:09 +02004729" Test TextChangedI and TextChanged
zeertzjqc4226622024-04-03 22:38:07 +02004730func Test_Changed_ChangedI()
zeertzjq8eb75232024-04-01 14:46:20 +02004731 " Run this test in a terminal because it requires running the main loop.
zeertzjqc4226622024-04-03 22:38:07 +02004732 " Don't use CheckRunVimInTerminal as that will skip the test on Windows.
4733 CheckFeature terminal
4734 CheckNotGui
4735 " Starting a terminal to run Vim is always considered flaky.
4736 let g:test_is_flaky = 1
4737
Christian Brabandt86032702024-03-31 18:38:09 +02004738 call writefile(['one', 'two', 'three'], 'XTextChangedI2', 'D')
4739 let before =<< trim END
zeertzjqc4226622024-04-03 22:38:07 +02004740 set ttimeout ttimeoutlen=10
zeertzjq8eb75232024-04-01 14:46:20 +02004741 let [g:autocmd_n, g:autocmd_i] = ['','']
4742
4743 func TextChangedAutocmd(char)
4744 let g:autocmd_{tolower(a:char)} = a:char .. b:changedtick
zeertzjqc4226622024-04-03 22:38:07 +02004745 call writefile([$'{g:autocmd_n},{g:autocmd_i}'], 'XTextChangedI3')
zeertzjq8eb75232024-04-01 14:46:20 +02004746 endfunc
4747
4748 au TextChanged <buffer> :call TextChangedAutocmd('N')
4749 au TextChangedI <buffer> :call TextChangedAutocmd('I')
4750
Christian Brabandt86032702024-03-31 18:38:09 +02004751 nnoremap <CR> o<Esc>
zeertzjq4a653912024-04-04 21:33:36 +02004752 autocmd SafeState * ++once call writefile([''], 'XTextChangedI3')
Christian Brabandt86032702024-03-31 18:38:09 +02004753 END
4754
4755 call writefile(before, 'Xinit', 'D')
zeertzjqc4226622024-04-03 22:38:07 +02004756 let buf = term_start(
4757 \ GetVimCommandCleanTerm() .. '-n -S Xinit XTextChangedI2',
4758 \ {'term_rows': 10})
4759 call assert_equal('running', term_getstatus(buf))
zeertzjq8eb75232024-04-01 14:46:20 +02004760 call WaitForAssert({-> assert_true(filereadable('XTextChangedI3'))})
zeertzjqe9ff79a2024-04-05 20:07:39 +02004761 defer delete('XTextChangedI3')
zeertzjq4a653912024-04-04 21:33:36 +02004762 call WaitForAssert({-> assert_equal([''], readfile('XTextChangedI3'))})
Christian Brabandt86032702024-03-31 18:38:09 +02004763
zeertzjqc4226622024-04-03 22:38:07 +02004764 " TextChanged should trigger if a mapping enters and leaves Insert mode.
4765 call term_sendkeys(buf, "\<CR>")
zeertzjqe9ff79a2024-04-05 20:07:39 +02004766 call WaitForAssert({-> assert_equal('N4,', readfile('XTextChangedI3')->join("\n"))})
zeertzjqc4226622024-04-03 22:38:07 +02004767
4768 call term_sendkeys(buf, "i")
4769 call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
zeertzjqe9ff79a2024-04-05 20:07:39 +02004770 call WaitForAssert({-> assert_equal('N4,', readfile('XTextChangedI3')->join("\n"))})
zeertzjqc4226622024-04-03 22:38:07 +02004771 " TextChangedI should trigger if change is done in Insert mode.
4772 call term_sendkeys(buf, "f")
zeertzjqe9ff79a2024-04-05 20:07:39 +02004773 call WaitForAssert({-> assert_equal('N4,I5', readfile('XTextChangedI3')->join("\n"))})
zeertzjqc4226622024-04-03 22:38:07 +02004774 call term_sendkeys(buf, "o")
zeertzjqe9ff79a2024-04-05 20:07:39 +02004775 call WaitForAssert({-> assert_equal('N4,I6', readfile('XTextChangedI3')->join("\n"))})
zeertzjqc4226622024-04-03 22:38:07 +02004776 call term_sendkeys(buf, "o")
zeertzjqe9ff79a2024-04-05 20:07:39 +02004777 call WaitForAssert({-> assert_equal('N4,I7', readfile('XTextChangedI3')->join("\n"))})
zeertzjqc4226622024-04-03 22:38:07 +02004778 " TextChanged shouldn't trigger when leaving Insert mode and TextChangedI
4779 " has been triggered.
4780 call term_sendkeys(buf, "\<Esc>")
4781 call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))})
zeertzjqe9ff79a2024-04-05 20:07:39 +02004782 call WaitForAssert({-> assert_equal('N4,I7', readfile('XTextChangedI3')->join("\n"))})
zeertzjqc4226622024-04-03 22:38:07 +02004783
4784 " TextChanged should trigger if change is done in Normal mode.
4785 call term_sendkeys(buf, "yyp")
zeertzjqe9ff79a2024-04-05 20:07:39 +02004786 call WaitForAssert({-> assert_equal('N8,I7', readfile('XTextChangedI3')->join("\n"))})
zeertzjqc4226622024-04-03 22:38:07 +02004787
4788 " TextChangedI shouldn't trigger if change isn't done in Insert mode.
4789 call term_sendkeys(buf, "i")
4790 call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
zeertzjqe9ff79a2024-04-05 20:07:39 +02004791 call WaitForAssert({-> assert_equal('N8,I7', readfile('XTextChangedI3')->join("\n"))})
zeertzjqc4226622024-04-03 22:38:07 +02004792 call term_sendkeys(buf, "\<Esc>")
4793 call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))})
zeertzjqe9ff79a2024-04-05 20:07:39 +02004794 call WaitForAssert({-> assert_equal('N8,I7', readfile('XTextChangedI3')->join("\n"))})
zeertzjqc4226622024-04-03 22:38:07 +02004795
4796 " TextChangedI should trigger if change is a mix of Normal and Insert modes.
4797 func! s:validate_mixed_textchangedi(buf, keys)
4798 let buf = a:buf
4799 call term_sendkeys(buf, "ifoo")
4800 call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
4801 call term_sendkeys(buf, "\<Esc>")
4802 call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))})
4803 call term_sendkeys(buf, ":let [g:autocmd_n, g:autocmd_i] = ['', '']\<CR>")
zeertzjqe9ff79a2024-04-05 20:07:39 +02004804 call writefile([], 'XTextChangedI3')
zeertzjqc4226622024-04-03 22:38:07 +02004805 call term_sendkeys(buf, a:keys)
4806 call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
zeertzjqe9ff79a2024-04-05 20:07:39 +02004807 call WaitForAssert({-> assert_match('^,I\d\+', readfile('XTextChangedI3')->join("\n"))})
zeertzjqc4226622024-04-03 22:38:07 +02004808 call term_sendkeys(buf, "\<Esc>")
4809 call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))})
zeertzjqe9ff79a2024-04-05 20:07:39 +02004810 call WaitForAssert({-> assert_match('^,I\d\+', readfile('XTextChangedI3')->join("\n"))})
zeertzjqc4226622024-04-03 22:38:07 +02004811 endfunc
4812
4813 call s:validate_mixed_textchangedi(buf, "o")
4814 call s:validate_mixed_textchangedi(buf, "O")
4815 call s:validate_mixed_textchangedi(buf, "ciw")
4816 call s:validate_mixed_textchangedi(buf, "cc")
4817 call s:validate_mixed_textchangedi(buf, "C")
4818 call s:validate_mixed_textchangedi(buf, "s")
4819 call s:validate_mixed_textchangedi(buf, "S")
4820
4821 " clean up
4822 bwipe!
Christian Brabandt86032702024-03-31 18:38:09 +02004823endfunc
4824
zeertzjq5bf6c212024-03-31 18:41:27 +02004825" Test that filetype detection still works when SwapExists autocommand sets
4826" filetype in another buffer.
4827func Test_SwapExists_set_other_buf_filetype()
4828 let lines =<< trim END
4829 set nocompatible directory=.
4830 filetype on
4831
4832 let g:buf = bufnr()
4833 new
4834
4835 func SwapExists()
4836 let v:swapchoice = 'o'
4837 call setbufvar(g:buf, '&filetype', 'text')
4838 endfunc
4839
4840 func SafeState()
4841 edit <script>
4842 redir! > XftSwapExists.out
4843 set readonly? filetype?
4844 redir END
4845 qall!
4846 endfunc
4847
4848 autocmd SwapExists * ++nested call SwapExists()
4849 autocmd SafeState * ++nested ++once call SafeState()
4850 END
4851 call writefile(lines, 'XftSwapExists.vim', 'D')
4852
4853 new XftSwapExists.vim
4854 if RunVim('', '', ' -S XftSwapExists.vim')
4855 call assert_equal(
4856 \ ['', ' readonly', ' filetype=vim'],
4857 \ readfile('XftSwapExists.out'))
4858 call delete('XftSwapExists.out')
4859 endif
4860
4861 bwipe!
4862endfunc
4863
4864" Test that file is not marked as modified when SwapExists autocommand sets
4865" 'modified' in another buffer.
4866func Test_SwapExists_set_other_buf_modified()
4867 let lines =<< trim END
4868 set nocompatible directory=.
4869
4870 let g:buf = bufnr()
4871 new
4872
4873 func SwapExists()
4874 let v:swapchoice = 'o'
4875 call setbufvar(g:buf, '&modified', 1)
4876 endfunc
4877
4878 func SafeState()
4879 edit <script>
4880 redir! > XmodSwapExists.out
4881 set readonly? modified?
4882 redir END
4883 qall!
4884 endfunc
4885
4886 autocmd SwapExists * ++nested call SwapExists()
4887 autocmd SafeState * ++nested ++once call SafeState()
4888 END
4889 call writefile(lines, 'XmodSwapExists.vim', 'D')
4890
4891 new XmodSwapExists.vim
4892 if RunVim('', '', ' -S XmodSwapExists.vim')
4893 call assert_equal(
4894 \ ['', ' readonly', 'nomodified'],
4895 \ readfile('XmodSwapExists.out'))
4896 call delete('XmodSwapExists.out')
4897 endif
4898
4899 bwipe!
4900endfunc
4901
Jaehwang Jungeb80b832024-04-26 18:48:48 +02004902func Test_BufEnter_botline()
4903 set hidden
4904 call writefile(range(10), 'Xxx1', 'D')
4905 call writefile(range(20), 'Xxx2', 'D')
4906 edit Xxx1
4907 edit Xxx2
4908 au BufEnter Xxx1 call assert_true(line('w$') > 1)
4909 edit Xxx1
zeertzjq340643e2024-04-27 11:33:24 +02004910
4911 bwipe! Xxx1
4912 bwipe! Xxx2
Jaehwang Jungeb80b832024-04-26 18:48:48 +02004913 au! BufEnter Xxx1
4914 set hidden&vim
4915endfunc
4916
Shougo Matsushita83678842024-07-11 22:05:12 +02004917func Test_KeyInputPre()
4918 " Consume previous keys
4919 call feedkeys('', 'ntx')
4920
4921 " KeyInputPre can record input keys.
4922 let s:keys = []
4923 au KeyInputPre n call add(s:keys, v:char)
4924
4925 call feedkeys('jkjkjjj', 'ntx')
4926 call assert_equal(
4927 \ ['j', 'k', 'j', 'k', 'j', 'j', 'j'],
4928 \ s:keys)
4929
4930 unlet s:keys
4931 au! KeyInputPre
4932
4933 " KeyInputPre can handle multibyte.
4934 let s:keys = []
4935 au KeyInputPre * call add(s:keys, v:char)
4936 edit Xxx1
4937
4938 call feedkeys("iあ\<ESC>", 'ntx')
4939 call assert_equal(['i', "あ", "\<ESC>"], s:keys)
4940
4941 bwipe! Xxx1
4942 unlet s:keys
4943 au! KeyInputPre
4944
4945 " KeyInputPre can change input keys.
4946 au KeyInputPre i if v:char ==# 'a' | let v:char = 'b' | endif
4947 edit Xxx1
4948
4949 call feedkeys("iaabb\<ESC>", 'ntx')
4950 call assert_equal(getline('.'), 'bbbb')
4951
4952 bwipe! Xxx1
4953 au! KeyInputPre
4954
4955 " KeyInputPre returns multiple characters.
4956 au KeyInputPre i if v:char ==# 'a' | let v:char = 'cccc' | endif
4957 edit Xxx1
4958
4959 call feedkeys("iaabb\<ESC>", 'ntx')
4960 call assert_equal(getline('.'), 'ccbb')
4961
4962 bwipe! Xxx1
4963 au! KeyInputPre
4964
4965 " KeyInputPre can use special keys.
4966 au KeyInputPre i if v:char ==# 'a' | let v:char = "\<Ignore>" | endif
4967 edit Xxx1
4968
4969 call feedkeys("iaabb\<ESC>", 'ntx')
4970 call assert_equal(getline('.'), 'bb')
4971
4972 bwipe! Xxx1
4973 au! KeyInputPre
4974
4975 " Test for v:event.typed
4976 au KeyInputPre n call assert_true(v:event.typed)
4977 call feedkeys('j', 'ntx')
4978
4979 au! KeyInputPre
4980
4981 au KeyInputPre n call assert_false(v:event.typed)
4982 call feedkeys('j', 'nx')
4983
4984 au! KeyInputPre
Shougo Matsushitafcc1b572024-07-17 20:25:22 +02004985
4986 " Test for v:event.typedchar
4987 nnoremap j k
4988 au KeyInputPre n
4989 \ call assert_equal(v:event.typedchar, 'j')
4990 \ | call assert_equal(v:char, 'k')
4991 call feedkeys('j', 'tx')
4992
4993 au! KeyInputPre
Shougo Matsushita83678842024-07-11 22:05:12 +02004994endfunc
4995
Christian Brabandtfb3f9692024-08-11 20:09:17 +02004996" those commands caused null pointer access, see #15464
4997func Test_WinNewPre_crash()
4998 defer CleanUpTestAuGroup()
4999 let _cmdheight=&cmdheight
5000 augroup testing
5001 au!
5002 autocmd WinNewPre * redraw
5003 augroup END
5004 tabnew
5005 tabclose
5006 augroup testing
5007 au!
5008 autocmd WinNewPre * wincmd t
5009 augroup END
5010 tabnew
5011 tabclose
5012 augroup testing
5013 au!
5014 autocmd WinNewPre * wincmd b
5015 augroup END
5016 tabnew
5017 tabclose
5018 augroup testing
5019 au!
5020 autocmd WinNewPre * set cmdheight+=1
5021 augroup END
5022 tabnew
5023 tabclose
5024 let &cmdheight=_cmdheight
5025endfunc
5026
Christian Brabandt84e31752024-09-02 09:59:18 +02005027" The specifics of the turkish locale may
5028" cause that Vim will not treat the GuiEnter autocommand
5029" as case insensitive and instead issues an error
5030func Test_GuiEnter_Turkish_locale()
5031 try
5032 let lng = v:lang
5033 lang tr_TR.UTF-8
5034 let result = execute(':au GuiEnter')
Ken Takataeccc9272024-09-03 23:01:55 +02005035 call assert_equal(gettext("\n--- Autocommands ---"), result)
Christian Brabandt84e31752024-09-02 09:59:18 +02005036 let result = execute(':au GUIENTER')
Ken Takataeccc9272024-09-03 23:01:55 +02005037 call assert_equal(gettext("\n--- Autocommands ---"), result)
Christian Brabandt84e31752024-09-02 09:59:18 +02005038 let result = execute(':au guienter')
Ken Takataeccc9272024-09-03 23:01:55 +02005039 call assert_equal(gettext("\n--- Autocommands ---"), result)
Christian Brabandt84e31752024-09-02 09:59:18 +02005040 exe ":lang" lng
5041 catch /E197:/
5042 " can't use Turkish locale
5043 throw 'Skipped: Turkish locale not available'
5044 endtry
5045endfunc
Christian Brabandtfb3f9692024-08-11 20:09:17 +02005046
Christian Brabandt51b62382024-10-06 17:31:10 +02005047" This was using freed memory
5048func Test_autocmd_BufWinLeave_with_vsp()
5049 new
5050 let fname = 'XXXBufWinLeaveUAF.txt'
5051 let dummy = 'XXXDummy.txt'
5052 call writefile([], fname)
5053 call writefile([], dummy)
5054 defer delete(fname)
5055 defer delete(dummy)
5056 exe "e " fname
5057 vsp
5058 augroup testing
Sean Dewar6cb1c822025-05-03 18:37:27 +02005059 exe 'au BufWinLeave' fname 'e' dummy
5060 \ '| call assert_fails(''vsp' fname ''', ''E1546:'')'
Christian Brabandt51b62382024-10-06 17:31:10 +02005061 augroup END
5062 bw
5063 call CleanUpTestAuGroup()
5064 exe "bw! " .. dummy
5065endfunc
5066
Luuk van Baale15cbc12025-01-04 17:18:08 +01005067func Test_OptionSet_cmdheight()
5068 set mouse=a laststatus=2
5069 au OptionSet cmdheight :let &l:ch = v:option_new
5070
5071 resize -1
5072 call assert_equal(2, &l:ch)
5073 resize +1
5074 call assert_equal(1, &l:ch)
5075
5076 call test_setmouse(&lines - 1, 1)
5077 call feedkeys("\<LeftMouse>", 'xt')
5078 call test_setmouse(&lines - 2, 1)
5079 call feedkeys("\<LeftDrag>", 'xt')
5080 call assert_equal(2, &l:ch)
5081
5082 tabnew | resize +1
5083 call assert_equal(1, &l:ch)
5084 tabfirst
5085 call assert_equal(2, &l:ch)
5086
5087 tabonly
5088 set cmdheight& mouse& laststatus&
5089endfunc
5090
Luuk van Baalb7147f82025-02-08 18:52:39 +01005091func Test_eventignorewin()
5092 defer CleanUpTestAuGroup()
5093 augroup testing
5094 au WinEnter * :call add(g:evs, ["WinEnter", expand("<afile>")])
5095 au WinLeave * :call add(g:evs, ["WinLeave", expand("<afile>")])
5096 au BufWinEnter * :call add(g:evs, ["BufWinEnter", expand("<afile>")])
5097 augroup END
5098
5099 let g:evs = []
5100 set eventignorewin=WinLeave,WinEnter
5101 split foo
5102 call assert_equal([['BufWinEnter', 'foo']], g:evs)
5103 set eventignorewin=all
5104 edit bar
5105 call assert_equal([['BufWinEnter', 'foo']], g:evs)
5106 set eventignorewin=
5107 wincmd w
5108 call assert_equal([['BufWinEnter', 'foo'], ['WinLeave', 'bar']], g:evs)
5109
5110 only!
5111 %bwipe!
5112 set eventignorewin&
5113 unlet g:evs
5114endfunc
5115
5116func Test_WinScrolled_Resized_eiw()
5117 CheckRunVimInTerminal
5118
5119 let lines =<< trim END
5120 call setline(1, ['foo']->repeat(32))
5121 set eventignorewin=WinScrolled,WinResized
5122 split
5123 let [g:afile,g:resized,g:scrolled] = ['none',0,0]
5124 au WinScrolled * let [g:afile,g:scrolled] = [expand('<afile>'),g:scrolled+1]
5125 au WinResized * let [g:afile,g:resized] = [expand('<afile>'),g:resized+1]
5126 END
Christian Brabandtbfc77192025-02-11 20:03:10 +01005127 call writefile(lines, 'Xtest_winscrolled_eiw', 'D')
5128 let buf = RunVimInTerminal('-S Xtest_winscrolled_eiw', {'rows': 10})
Luuk van Baalb7147f82025-02-08 18:52:39 +01005129
5130 " Both windows are ignoring resize events
5131 call term_sendkeys(buf, "\<C-W>-")
5132 call TermWait(buf)
5133 call term_sendkeys(buf, ":echo g:afile g:resized g:scrolled\<CR>")
5134 call WaitForAssert({-> assert_equal('none 0 0', term_getline(buf, 10))}, 1000)
5135
5136 " And scroll events
5137 call term_sendkeys(buf, "Ggg")
5138 call TermWait(buf)
5139 call term_sendkeys(buf, ":echo g:afile g:resized g:scrolled\<CR>")
5140 call WaitForAssert({-> assert_equal('none 0 0', term_getline(buf, 10))}, 1000)
5141
5142 " Un-ignore events in second window, make first window current and resize
5143 call term_sendkeys(buf, ":set eventignorewin=\<CR>\<C-W>w\<C-W>+")
5144 call TermWait(buf)
5145 call term_sendkeys(buf, ":echo win_getid() g:afile g:resized g:scrolled\<CR>")
5146 call WaitForAssert({-> assert_equal('1000 1001 1 1', term_getline(buf, 10))}, 1000)
5147
5148 call StopVimInTerminal(buf)
5149endfunc
5150
Jim Zhou5606ca52025-03-13 21:58:25 +01005151" Test that TabClosedPre and TabClosed are triggered when closing a tab.
5152func Test_autocmd_tabclosedpre()
5153 augroup testing
5154 au TabClosedPre * call add(g:tabpagenr_pre, t:testvar)
5155 au TabClosed * call add(g:tabpagenr_post, t:testvar)
5156 augroup END
5157
5158 " Test 'tabclose' triggering
5159 let g:tabpagenr_pre = []
5160 let g:tabpagenr_post = []
5161 let t:testvar = 1
5162 tabnew
5163 let t:testvar = 2
5164 tabnew
5165 let t:testvar = 3
5166 tabnew
5167 let t:testvar = 4
5168 tabnext
5169 tabclose
5170 tabclose
5171 tabclose
5172 call assert_equal([1, 2, 3], g:tabpagenr_pre)
5173 call assert_equal([2, 3, 4], g:tabpagenr_post)
5174
5175 " Test 'tabclose {count}' triggering
5176 let g:tabpagenr_pre = []
5177 let g:tabpagenr_post = []
5178 let t:testvar = 1
5179 tabnew
5180 let t:testvar = 2
5181 tabnew
5182 let t:testvar = 3
5183 tabclose 2
5184 tabclose 2
5185 call assert_equal([2, 3], g:tabpagenr_pre)
5186 call assert_equal([3, 1], g:tabpagenr_post)
5187
5188 " Test 'tabonly' triggering
5189 let g:tabpagenr_pre = []
5190 let g:tabpagenr_post = []
5191 let t:testvar = 1
5192 tabnew
5193 let t:testvar = 2
5194 tabonly
5195 call assert_equal([1], g:tabpagenr_pre)
5196 call assert_equal([2], g:tabpagenr_post)
5197
5198 " Test 'q' and 'close' triggering (closing the last window in a tab)
5199 let g:tabpagenr_pre = []
5200 let g:tabpagenr_post = []
5201 split
5202 let t:testvar = 1
5203 tabnew
5204 let t:testvar = 2
5205 split
5206 vsplit
5207 tabnew
5208 let t:testvar = 3
5209 tabnext
5210 only
5211 quit
5212 quit
5213 close
5214 close
5215 call assert_equal([1, 2], g:tabpagenr_pre)
5216 call assert_equal([2, 3], g:tabpagenr_post)
5217
5218 func ClearAutomcdAndCreateTabs()
5219 au! TabClosedPre
5220 bw!
5221 e Z
5222 tabonly
5223 tabnew A
5224 tabnew B
5225 tabnew C
5226 endfunc
5227
5228 func GetTabs()
5229 redir => tabsout
5230 tabs
5231 redir END
5232 let tabsout = substitute(tabsout, '\n', '', 'g')
5233 let tabsout = substitute(tabsout, 'Tab page ', '', 'g')
5234 let tabsout = substitute(tabsout, ' ', '', 'g')
5235 return tabsout
5236 endfunc
5237
5238 call CleanUpTestAuGroup()
5239
5240 " Close tab in TabClosedPre autocmd
5241 call ClearAutomcdAndCreateTabs()
5242 au TabClosedPre * tabclose
zeertzjq67fe77d2025-04-20 10:21:18 +02005243 call assert_fails('tabclose', 'E1312:')
Jim Zhou5606ca52025-03-13 21:58:25 +01005244 call ClearAutomcdAndCreateTabs()
5245 au TabClosedPre * tabclose
zeertzjq67fe77d2025-04-20 10:21:18 +02005246 call assert_fails('tabclose 2', 'E1312:')
Jim Zhou5606ca52025-03-13 21:58:25 +01005247 call ClearAutomcdAndCreateTabs()
5248 au TabClosedPre * tabclose 1
zeertzjq67fe77d2025-04-20 10:21:18 +02005249 call assert_fails('tabclose', 'E1312:')
Jim Zhou5606ca52025-03-13 21:58:25 +01005250
5251 " Close other (all) tabs in TabClosedPre autocmd
5252 call ClearAutomcdAndCreateTabs()
5253 au TabClosedPre * tabonly
zeertzjq67fe77d2025-04-20 10:21:18 +02005254 call assert_fails('tabclose', 'E1312:')
Jim Zhou5606ca52025-03-13 21:58:25 +01005255 call ClearAutomcdAndCreateTabs()
5256 au TabClosedPre * tabonly
zeertzjq67fe77d2025-04-20 10:21:18 +02005257 call assert_fails('tabclose 2', 'E1312:')
Jim Zhou5606ca52025-03-13 21:58:25 +01005258 call ClearAutomcdAndCreateTabs()
5259 au TabClosedPre * tabclose 4
zeertzjq67fe77d2025-04-20 10:21:18 +02005260 call assert_fails('tabclose 2', 'E1312:')
Jim Zhou5606ca52025-03-13 21:58:25 +01005261
5262 " Open new tabs in TabClosedPre autocmd
5263 call ClearAutomcdAndCreateTabs()
5264 au TabClosedPre * tabnew D
zeertzjq67fe77d2025-04-20 10:21:18 +02005265 call assert_fails('tabclose', 'E1312:')
Jim Zhou5606ca52025-03-13 21:58:25 +01005266 call ClearAutomcdAndCreateTabs()
5267 au TabClosedPre * tabnew D
zeertzjq67fe77d2025-04-20 10:21:18 +02005268 call assert_fails('tabclose 1', 'E1312:')
Jim Zhou5606ca52025-03-13 21:58:25 +01005269
5270 " Moving the tab page in TabClosedPre autocmd
5271 call ClearAutomcdAndCreateTabs()
5272 au TabClosedPre * tabmove 0
5273 tabclose
Jim Zhoubcf66e02025-03-16 20:24:57 +01005274 call assert_equal('1>Z2A3B', GetTabs())
Jim Zhou5606ca52025-03-13 21:58:25 +01005275 call ClearAutomcdAndCreateTabs()
5276 au TabClosedPre * tabmove 0
5277 tabclose 1
5278 call assert_equal('1A2B3>C', GetTabs())
5279 tabonly
5280 call assert_equal('1>C', GetTabs())
5281
5282 " Switching tab page in TabClosedPre autocmd
5283 call ClearAutomcdAndCreateTabs()
5284 au TabClosedPre * tabnext | e Y
5285 tabclose
5286 call assert_equal('1Y2A3>B', GetTabs())
5287 call ClearAutomcdAndCreateTabs()
5288 au TabClosedPre * tabnext | e Y
5289 tabclose 1
5290 call assert_equal('1Y2B3>C', GetTabs())
5291 tabonly
5292 call assert_equal('1>Y', GetTabs())
5293
5294 " Create new windows in TabClosedPre autocmd
5295 call ClearAutomcdAndCreateTabs()
5296 au TabClosedPre * split | e X| vsplit | e Y | split | e Z
zeertzjq67fe77d2025-04-20 10:21:18 +02005297 call assert_fails('tabclose', 'E242:')
Jim Zhou5606ca52025-03-13 21:58:25 +01005298 call ClearAutomcdAndCreateTabs()
5299 au TabClosedPre * new X | new Y | new Z
zeertzjq67fe77d2025-04-20 10:21:18 +02005300 call assert_fails('tabclose 1', 'E242:')
Jim Zhou5606ca52025-03-13 21:58:25 +01005301
Jim Zhoubcf66e02025-03-16 20:24:57 +01005302 " Test directly closing the tab page with ':tabclose'
5303 au!
5304 tabonly
5305 bw!
5306 e Z
5307 au TabClosedPre * mksession!
5308 tabnew A
5309 sp
5310 tabclose
5311 source Session.vim
5312 call assert_equal('1Z2>AA', GetTabs())
5313
5314 " Test directly closing the tab page with ':tabonly'
5315 " Z is closed before A. Hence A overwrites the session.
5316 au!
5317 tabonly
5318 bw!
5319 e Z
5320 au TabClosedPre * mksession!
5321 tabnew A
5322 tabnew B
5323 tabonly
5324 source Session.vim
5325 call assert_equal('1>A2B', GetTabs())
5326
Jim Zhou5606ca52025-03-13 21:58:25 +01005327 " Clean up
Jim Zhoubcf66e02025-03-16 20:24:57 +01005328 call delete('Session.vim')
Jim Zhou5606ca52025-03-13 21:58:25 +01005329 au!
5330 only
5331 tabonly
5332 bw!
5333endfunc
5334
Sean Deward4110e02025-05-11 13:45:21 +02005335func Test_eventignorewin_non_current()
5336 defer CleanUpTestAuGroup()
5337 let s:triggered = ''
5338 augroup testing
5339 " Will set <abuf> to the buffer of the closing window.
5340 autocmd WinClosed * let s:triggered = 'WinClosed'
5341 augroup END
5342 let initial_win = win_getid()
5343
5344 new
5345 let new_buf = bufnr()
5346 " Only set for one of the windows into the new buffer.
5347 setlocal eventignorewin=all
5348 split
5349 setlocal eventignorewin=
5350 let close_winnr = winnr()
5351
5352 " Return to the window where the buffer is non-current. WinClosed should
5353 " trigger as not all windows into new_buf have 'eventignorewin' set for it.
5354 call win_gotoid(initial_win)
5355 call assert_notequal(new_buf, bufnr())
5356 execute close_winnr 'close'
5357 call assert_equal('WinClosed', s:triggered)
5358
5359 wincmd w
5360 call assert_equal(new_buf, bufnr())
5361 tab split
5362 setlocal eventignorewin=
5363 let close_winnr = win_getid()
5364
5365 " Ensure that new_buf's window in the other tabpage with 'eventignorewin'
5366 " unset allows WinClosed to run when new_buf is non-current.
5367 call win_gotoid(initial_win)
5368 call assert_notequal(new_buf, bufnr())
5369 let s:triggered = ''
5370 only!
5371 call assert_equal('WinClosed', s:triggered)
5372 call assert_equal(1, win_findbuf(new_buf)->len())
5373
5374 " Create an only window to new_buf with 'eventignorewin' set.
5375 tabonly!
5376 execute new_buf 'sbuffer'
5377 setlocal eventignorewin=all
5378 wincmd p
5379 call assert_equal(1, win_findbuf(new_buf)->len())
5380 call assert_notequal(new_buf, bufnr())
5381
5382 " Closing a window unrelated to new_buf should not block WinClosed.
5383 split
5384 let s:triggered = ''
5385 close
5386 call assert_equal('WinClosed', s:triggered)
5387 call assert_equal(1, win_findbuf(new_buf)->len())
5388
5389 " Check WinClosed is blocked when we close the only window to new_buf (that
5390 " has 'eventignorewin' set) while new_buf is non-current.
5391 call assert_notequal(new_buf, bufnr())
5392 let s:triggered = ''
5393 only!
5394 call assert_equal('', s:triggered)
5395 call assert_equal(0, win_findbuf(new_buf)->len())
5396
5397 augroup testing
5398 autocmd!
5399 autocmd BufNew * ++once let s:triggered = 'BufNew'
5400 augroup END
5401
5402 " Buffer not shown in a window, 'eventignorewin' should not block (and
5403 " can't even be set for it anyway in this case).
5404 badd foo
5405 call assert_equal('BufNew', s:triggered)
5406
5407 unlet! s:triggered
5408 %bw!
5409endfunc
5410
Sean Dewar00772822025-05-14 20:16:52 +02005411func Test_reuse_curbuf_leak()
5412 new bar
5413 let s:bar_buf = bufnr()
5414 augroup testing
5415 autocmd!
5416 autocmd BufDelete * ++once let s:triggered = 1 | execute s:bar_buf 'buffer'
5417 augroup END
5418 enew
5419 let empty_buf = bufnr()
5420
5421 " Old curbuf should be reused, firing BufDelete. As BufDelete changes curbuf,
5422 " reusing the buffer would fail and leak the ffname.
5423 edit foo
5424 call assert_equal(1, s:triggered)
5425 " Wasn't reused because the buffer changed, but buffer "foo" is still created.
5426 call assert_equal(1, bufexists(empty_buf))
5427 call assert_notequal(empty_buf, bufnr())
5428 call assert_equal('foo', bufname())
5429 call assert_equal('bar', bufname(s:bar_buf))
5430
5431 unlet! s:bar_buf s:triggered
5432 call CleanUpTestAuGroup()
5433 %bw!
5434endfunc
5435
Sean Dewar31be82e2025-05-15 19:59:37 +02005436func Test_reuse_curbuf_switch()
5437 edit asdf
5438 let s:asdf_win = win_getid()
5439 new
5440 let other_buf = bufnr()
5441 let other_win = win_getid()
5442 augroup testing
5443 autocmd!
5444 autocmd BufUnload * ++once let s:triggered = 1
5445 \| call assert_fails('split', 'E1159:')
5446 \| call win_gotoid(s:asdf_win)
5447 augroup END
5448
5449 " Check BufUnload changing curbuf does not cause buflist_new to create a new
5450 " buffer while leaving "other_buf" unloaded in a window.
5451 enew
5452 call assert_equal(1, s:triggered)
5453 call assert_equal(other_buf, bufnr())
5454 call assert_equal(other_win, win_getid())
5455 call assert_equal(1, win_findbuf(other_buf)->len())
5456 call assert_equal(1, bufloaded(other_buf))
5457
5458 unlet! s:asdf_win s:triggered
5459 call CleanUpTestAuGroup()
5460 %bw!
5461endfunc
5462
Luuk van Baal8cc6d8b2025-05-31 12:10:31 +02005463func Test_eventignore_subtract()
5464 set eventignore=all,-WinEnter
5465 augroup testing
5466 autocmd!
5467 autocmd WinEnter * ++once let s:triggered = 1
5468 augroup END
5469
5470 new
5471 call assert_equal(1, s:triggered)
5472
5473 set eventignore&
5474 unlet! s:triggered
5475 call CleanUpTestAuGroup()
5476 %bw!
5477endfunc
5478
Hirohito Higashi88be7a62025-07-06 10:34:48 +02005479func Test_VimResized_and_window_width_not_equalized()
5480 CheckRunVimInTerminal
5481
5482 let lines =<< trim END
5483 let g:vim_resized = 0
5484 autocmd VimResized * let g:vim_resized = 1
5485 10vsplit
5486 END
5487 call writefile(lines, 'XTest_VimResize', 'D')
5488 let buf = RunVimInTerminal('-S XTest_VimResize', {'rows': 10, 'cols': 30})
5489
5490 " redraw now to avoid a redraw after the :echo command
5491 call term_sendkeys(buf, ":redraw!\<CR>")
5492 call TermWait(buf)
5493
5494 call term_sendkeys(buf, ":set columns=40\<CR>")
5495 call term_sendkeys(buf, ":echo 'VimResized:' g:vim_resized\<CR>")
5496 call WaitForAssert({-> assert_match('^VimResized: 1$', term_getline(buf, 10))}, 1000)
5497 call term_sendkeys(buf, ":let window_width = getwininfo(win_getid())[0].width\<CR>")
5498 call term_sendkeys(buf, ":echo 'window_width:' window_width\<CR>")
5499 call WaitForAssert({-> assert_match('^window_width: 10$', term_getline(buf, 10))}, 1000)
5500
5501 call StopVimInTerminal(buf)
5502endfunc
5503
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01005504" vim: shiftwidth=2 sts=2 expandtab