blob: 58a5d959010e73770f10b4fb401239b111110cd1 [file] [log] [blame]
Bram Moolenaar2d1a2482016-08-14 15:32:11 +02001" Tests for mappings and abbreviations
2
Bram Moolenaar26d98212019-01-27 22:32:55 +01003source shared.vim
Bram Moolenaar8c5a2782019-08-07 23:07:07 +02004source check.vim
Bram Moolenaar4ebe0e62019-11-22 20:55:40 +01005source screendump.vim
Bram Moolenaar957cf672020-11-12 14:21:06 +01006source term_util.vim
Bram Moolenaar62aec932022-01-29 21:45:34 +00007import './vim9.vim' as v9
Bram Moolenaar26d98212019-01-27 22:32:55 +01008
Bram Moolenaar2d1a2482016-08-14 15:32:11 +02009func Test_abbreviation()
10 " abbreviation with 0x80 should work
11 inoreab чкпр vim
12 call feedkeys("Goчкпр \<Esc>", "xt")
13 call assert_equal('vim ', getline('$'))
14 iunab чкпр
15 set nomodified
16endfunc
17
Bram Moolenaar8485be42019-04-23 16:36:05 +020018func Test_abclear()
19 abbrev foo foobar
20 iabbrev fooi foobari
21 cabbrev fooc foobarc
22 call assert_equal("\n\n"
23 \ .. "c fooc foobarc\n"
24 \ .. "i fooi foobari\n"
25 \ .. "! foo foobar", execute('abbrev'))
26
27 iabclear
28 call assert_equal("\n\n"
29 \ .. "c fooc foobarc\n"
30 \ .. "c foo foobar", execute('abbrev'))
31 abbrev foo foobar
32 iabbrev fooi foobari
33
34 cabclear
35 call assert_equal("\n\n"
36 \ .. "i fooi foobari\n"
37 \ .. "i foo foobar", execute('abbrev'))
38 abbrev foo foobar
39 cabbrev fooc foobarc
40
41 abclear
42 call assert_equal("\n\nNo abbreviation found", execute('abbrev'))
Bram Moolenaarf0cee192020-02-16 13:33:56 +010043 call assert_fails('%abclear', 'E481:')
Bram Moolenaar8485be42019-04-23 16:36:05 +020044endfunc
45
46func Test_abclear_buffer()
47 abbrev foo foobar
48 new X1
49 abbrev <buffer> foo1 foobar1
50 new X2
51 abbrev <buffer> foo2 foobar2
52
53 call assert_equal("\n\n"
54 \ .. "! foo2 @foobar2\n"
55 \ .. "! foo foobar", execute('abbrev'))
56
57 abclear <buffer>
58 call assert_equal("\n\n"
59 \ .. "! foo foobar", execute('abbrev'))
60
61 b X1
62 call assert_equal("\n\n"
63 \ .. "! foo1 @foobar1\n"
64 \ .. "! foo foobar", execute('abbrev'))
65 abclear <buffer>
66 call assert_equal("\n\n"
67 \ .. "! foo foobar", execute('abbrev'))
68
69 abclear
70 call assert_equal("\n\nNo abbreviation found", execute('abbrev'))
71
72 %bwipe
73endfunc
74
Bram Moolenaar2d1a2482016-08-14 15:32:11 +020075func Test_map_ctrl_c_insert()
76 " mapping of ctrl-c in Insert mode
77 set cpo-=< cpo-=k
78 inoremap <c-c> <ctrl-c>
79 cnoremap <c-c> dummy
80 cunmap <c-c>
Bram Moolenaarfccd93f2020-05-31 22:06:51 +020081 call feedkeys("GoTEST2: CTRL-C |\<*C-C>A|\<Esc>", "xt")
Bram Moolenaar2d1a2482016-08-14 15:32:11 +020082 call assert_equal('TEST2: CTRL-C |<ctrl-c>A|', getline('$'))
83 unmap! <c-c>
84 set nomodified
85endfunc
86
87func Test_map_ctrl_c_visual()
88 " mapping of ctrl-c in Visual mode
89 vnoremap <c-c> :<C-u>$put ='vmap works'
Bram Moolenaarfccd93f2020-05-31 22:06:51 +020090 call feedkeys("GV\<*C-C>\<CR>", "xt")
Bram Moolenaar2d1a2482016-08-14 15:32:11 +020091 call assert_equal('vmap works', getline('$'))
92 vunmap <c-c>
93 set nomodified
94endfunc
95
96func Test_map_langmap()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +020097 CheckFeature langmap
Bram Moolenaar920694c2016-08-21 17:45:02 +020098
99 " check langmap applies in normal mode
100 set langmap=+- nolangremap
101 new
102 call setline(1, ['a', 'b', 'c'])
103 2
104 call assert_equal('b', getline('.'))
105 call feedkeys("+", "xt")
106 call assert_equal('a', getline('.'))
107
108 " check no remapping
109 map x +
110 2
111 call feedkeys("x", "xt")
112 call assert_equal('c', getline('.'))
113
114 " check with remapping
115 set langremap
116 2
117 call feedkeys("x", "xt")
118 call assert_equal('a', getline('.'))
119
120 unmap x
121 bwipe!
122
123 " 'langnoremap' follows 'langremap' and vise versa
124 set langremap
125 set langnoremap
126 call assert_equal(0, &langremap)
127 set langremap
128 call assert_equal(0, &langnoremap)
129 set nolangremap
130 call assert_equal(1, &langnoremap)
131
Bram Moolenaarda9ce2c2016-09-02 19:34:10 +0200132 " check default values
133 set langnoremap&
134 call assert_equal(0, &langnoremap)
135 call assert_equal(1, &langremap)
136 set langremap&
137 call assert_equal(0, &langnoremap)
138 call assert_equal(1, &langremap)
139
Bram Moolenaar920694c2016-08-21 17:45:02 +0200140 " langmap should not apply in insert mode, 'langremap' doesn't matter
141 set langmap=+{ nolangremap
142 call feedkeys("Go+\<Esc>", "xt")
143 call assert_equal('+', getline('$'))
144 set langmap=+{ langremap
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200145 call feedkeys("Go+\<Esc>", "xt")
146 call assert_equal('+', getline('$'))
147
Bram Moolenaar920694c2016-08-21 17:45:02 +0200148 " langmap used for register name in insert mode.
149 call setreg('a', 'aaaa')
150 call setreg('b', 'bbbb')
151 call setreg('c', 'cccc')
152 set langmap=ab langremap
153 call feedkeys("Go\<C-R>a\<Esc>", "xt")
154 call assert_equal('bbbb', getline('$'))
155 call feedkeys("Go\<C-R>\<C-R>a\<Esc>", "xt")
156 call assert_equal('bbbb', getline('$'))
157 " mapping does not apply
158 imap c a
159 call feedkeys("Go\<C-R>c\<Esc>", "xt")
160 call assert_equal('cccc', getline('$'))
161 imap a c
162 call feedkeys("Go\<C-R>a\<Esc>", "xt")
163 call assert_equal('bbbb', getline('$'))
164
165 " langmap should not apply in Command-line mode
166 set langmap=+{ nolangremap
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200167 call feedkeys(":call append(line('$'), '+')\<CR>", "xt")
168 call assert_equal('+', getline('$'))
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200169
Bram Moolenaare90858d2017-02-01 17:24:34 +0100170 iunmap a
171 iunmap c
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200172 set nomodified
173endfunc
174
175func Test_map_feedkeys()
176 " issue #212 (feedkeys insert mapping at current position)
177 nnoremap . :call feedkeys(".", "in")<cr>
178 call setline('$', ['a b c d', 'a b c d'])
179 $-1
180 call feedkeys("0qqdw.ifoo\<Esc>qj0@q\<Esc>", "xt")
181 call assert_equal(['fooc d', 'fooc d'], getline(line('$') - 1, line('$')))
Bram Moolenaare90858d2017-02-01 17:24:34 +0100182 nunmap .
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200183 set nomodified
184endfunc
185
186func Test_map_cursor()
187 " <c-g>U<cursor> works only within a single line
188 imapclear
189 imap ( ()<c-g>U<left>
190 call feedkeys("G2o\<Esc>ki\<CR>Test1: text with a (here some more text\<Esc>k.", "xt")
191 call assert_equal('Test1: text with a (here some more text)', getline(line('$') - 2))
192 call assert_equal('Test1: text with a (here some more text)', getline(line('$') - 1))
193
194 " test undo
195 call feedkeys("G2o\<Esc>ki\<CR>Test2: text wit a (here some more text [und undo]\<C-G>u\<Esc>k.u", "xt")
196 call assert_equal('', getline(line('$') - 2))
197 call assert_equal('Test2: text wit a (here some more text [und undo])', getline(line('$') - 1))
198 set nomodified
199 imapclear
200endfunc
201
Bram Moolenaar75bf3d22019-03-26 22:46:05 +0100202func Test_map_cursor_ctrl_gU()
203 " <c-g>U<cursor> works only within a single line
204 nnoremap c<* *Ncgn<C-r>"<C-G>U<S-Left>
205 call setline(1, ['foo', 'foobar', '', 'foo'])
206 call cursor(1,2)
207 call feedkeys("c<*PREFIX\<esc>.", 'xt')
208 call assert_equal(['PREFIXfoo', 'foobar', '', 'PREFIXfoo'], getline(1,'$'))
209 " break undo manually
210 set ul=1000
211 exe ":norm! uu"
212 call assert_equal(['foo', 'foobar', '', 'foo'], getline(1,'$'))
213
214 " Test that it does not work if the cursor moves to the previous line
215 " 2 times <S-Left> move to the previous line
216 nnoremap c<* *Ncgn<C-r>"<C-G>U<S-Left><C-G>U<S-Left>
217 call setline(1, ['', ' foo', 'foobar', '', 'foo'])
218 call cursor(2,3)
219 call feedkeys("c<*PREFIX\<esc>.", 'xt')
220 call assert_equal(['PREFIXPREFIX', ' foo', 'foobar', '', 'foo'], getline(1,'$'))
221 nmapclear
222endfunc
223
224
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200225" This isn't actually testing a mapping, but similar use of CTRL-G U as above.
226func Test_break_undo()
Bram Moolenaar75bf3d22019-03-26 22:46:05 +0100227 set whichwrap=<,>,[,]
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200228 call feedkeys("G4o2k", "xt")
229 exe ":norm! iTest3: text with a (parenthesis here\<C-G>U\<Right>new line here\<esc>\<up>\<up>."
230 call assert_equal('new line here', getline(line('$') - 3))
231 call assert_equal('Test3: text with a (parenthesis here', getline(line('$') - 2))
232 call assert_equal('new line here', getline(line('$') - 1))
233 set nomodified
234endfunc
Bram Moolenaar35a4cfa2016-08-14 16:07:48 +0200235
236func Test_map_meta_quotes()
237 imap <M-"> foo
Bram Moolenaarfccd93f2020-05-31 22:06:51 +0200238 call feedkeys("Go-\<*M-\">-\<Esc>", "xt")
Bram Moolenaar35a4cfa2016-08-14 16:07:48 +0200239 call assert_equal("-foo-", getline('$'))
240 set nomodified
241 iunmap <M-">
242endfunc
Bram Moolenaar878c2632017-04-01 15:15:52 +0200243
Bram Moolenaarc8fd33d2019-08-16 20:33:05 +0200244func Test_map_meta_multibyte()
245 imap <M-á> foo
Bram Moolenaar2f710af2019-08-16 20:56:03 +0200246 call assert_match('i <M-á>\s*foo', execute('imap'))
Bram Moolenaarc8fd33d2019-08-16 20:33:05 +0200247 iunmap <M-á>
248endfunc
249
Bram Moolenaar878c2632017-04-01 15:15:52 +0200250func Test_abbr_after_line_join()
251 new
252 abbr foo bar
253 set backspace=indent,eol,start
254 exe "normal o\<BS>foo "
255 call assert_equal("bar ", getline(1))
256 bwipe!
257 unabbr foo
258 set backspace&
259endfunc
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200260
261func Test_map_timeout()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200262 CheckFeature timers
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200263 nnoremap aaaa :let got_aaaa = 1<CR>
264 nnoremap bb :let got_bb = 1<CR>
265 nmap b aaa
266 new
267 func ExitInsert(timer)
268 let g:line = getline(1)
269 call feedkeys("\<Esc>", "t")
270 endfunc
271 set timeout timeoutlen=200
Bram Moolenaar26d98212019-01-27 22:32:55 +0100272 let timer = timer_start(300, 'ExitInsert')
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200273 " After the 'b' Vim waits for another character to see if it matches 'bb'.
274 " When it times out it is expanded to "aaa", but there is no wait for
275 " "aaaa". Can't check that reliably though.
276 call feedkeys("b", "xt!")
277 call assert_equal("aa", g:line)
278 call assert_false(exists('got_aaa'))
279 call assert_false(exists('got_bb'))
280
281 bwipe!
282 nunmap aaaa
283 nunmap bb
284 nunmap b
285 set timeoutlen&
286 delfunc ExitInsert
Bram Moolenaar26d98212019-01-27 22:32:55 +0100287 call timer_stop(timer)
288endfunc
289
290func Test_map_timeout_with_timer_interrupt()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200291 CheckFeature job
292 CheckFeature timers
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +0100293 let g:test_is_flaky = 1
Bram Moolenaar26d98212019-01-27 22:32:55 +0100294
295 " Confirm the timer invoked in exit_cb of the job doesn't disturb mapped key
296 " sequence.
297 new
298 let g:val = 0
299 nnoremap \12 :let g:val = 1<CR>
300 nnoremap \123 :let g:val = 2<CR>
Bram Moolenaarea94c852019-08-16 21:47:27 +0200301 set timeout timeoutlen=200
Bram Moolenaar26d98212019-01-27 22:32:55 +0100302
303 func ExitCb(job, status)
Bram Moolenaar8d4ce562019-01-30 22:01:40 +0100304 let g:timer = timer_start(1, {-> feedkeys("3\<Esc>", 't')})
Bram Moolenaar26d98212019-01-27 22:32:55 +0100305 endfunc
306
307 call job_start([&shell, &shellcmdflag, 'echo'], {'exit_cb': 'ExitCb'})
308 call feedkeys('\12', 'xt!')
309 call assert_equal(2, g:val)
310
311 bwipe!
312 nunmap \12
313 nunmap \123
314 set timeoutlen&
315 call WaitFor({-> exists('g:timer')})
316 call timer_stop(g:timer)
317 unlet g:timer
318 unlet g:val
319 delfunc ExitCb
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200320endfunc
Bram Moolenaarc3c3e692018-04-26 22:30:33 +0200321
322func Test_abbreviation_CR()
323 new
324 func Eatchar(pat)
325 let c = nr2char(getchar(0))
326 return (c =~ a:pat) ? '' : c
327 endfunc
328 iabbrev <buffer><silent> ~~7 <c-r>=repeat('~', 7)<CR><c-r>=Eatchar('\s')<cr>
329 call feedkeys("GA~~7 \<esc>", 'xt')
330 call assert_equal('~~~~~~~', getline('$'))
331 %d
332 call feedkeys("GA~~7\<cr>\<esc>", 'xt')
333 call assert_equal(['~~~~~~~', ''], getline(1,'$'))
334 delfunc Eatchar
335 bw!
336endfunc
Bram Moolenaar5e3423d2018-05-13 18:36:27 +0200337
338func Test_cabbr_visual_mode()
339 cabbr s su
340 call feedkeys(":s \<c-B>\"\<CR>", 'itx')
341 call assert_equal('"su ', getreg(':'))
342 call feedkeys(":'<,'>s \<c-B>\"\<CR>", 'itx')
343 let expected = '"'. "'<,'>su "
344 call assert_equal(expected, getreg(':'))
345 call feedkeys(": '<,'>s \<c-B>\"\<CR>", 'itx')
346 let expected = '" '. "'<,'>su "
347 call assert_equal(expected, getreg(':'))
348 call feedkeys(":'a,'bs \<c-B>\"\<CR>", 'itx')
349 let expected = '"'. "'a,'bsu "
350 call assert_equal(expected, getreg(':'))
351 cunabbr s
352endfunc
Bram Moolenaar5976f8f2018-12-27 23:44:44 +0100353
354func Test_motionforce_omap()
355 func GetCommand()
356 let g:m=mode(1)
357 let [g:lnum1, g:col1] = searchpos('-', 'Wb')
358 if g:lnum1 == 0
359 return "\<Esc>"
360 endif
361 let [g:lnum2, g:col2] = searchpos('-', 'W')
362 if g:lnum2 == 0
363 return "\<Esc>"
364 endif
365 return ":call Select()\<CR>"
366 endfunc
367 func Select()
368 call cursor([g:lnum1, g:col1])
369 exe "normal! 1 ". (strlen(g:m) == 2 ? 'v' : g:m[2])
370 call cursor([g:lnum2, g:col2])
371 execute "normal! \<BS>"
372 endfunc
373 new
374 onoremap <buffer><expr> i- GetCommand()
375 " 1) default omap mapping
376 %d_
377 call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
378 call cursor(2, 1)
379 norm di-
380 call assert_equal('no', g:m)
381 call assert_equal(['aaa -- eee'], getline(1, '$'))
382 " 2) forced characterwise operation
383 %d_
384 call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
385 call cursor(2, 1)
386 norm dvi-
387 call assert_equal('nov', g:m)
388 call assert_equal(['aaa -- eee'], getline(1, '$'))
389 " 3) forced linewise operation
390 %d_
391 call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
392 call cursor(2, 1)
393 norm dVi-
394 call assert_equal('noV', g:m)
395 call assert_equal([''], getline(1, '$'))
396 " 4) forced blockwise operation
397 %d_
398 call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
399 call cursor(2, 1)
400 exe "norm d\<C-V>i-"
401 call assert_equal("no\<C-V>", g:m)
402 call assert_equal(['aaabbb', 'x', 'dddeee'], getline(1, '$'))
403 bwipe!
404 delfunc Select
405 delfunc GetCommand
406endfunc
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200407
408func Test_error_in_map_expr()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200409 " Unlike CheckRunVimInTerminal this does work in a win32 console
410 CheckFeature terminal
411 if has('win32') && has('gui_running')
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200412 throw 'Skipped: cannot run Vim in a terminal window'
413 endif
414
415 let lines =<< trim [CODE]
416 func Func()
417 " fail to create list
418 let x = [
419 endfunc
420 nmap <expr> ! Func()
421 set updatetime=50
422 [CODE]
Bram Moolenaarb152b6a2022-09-29 21:37:33 +0100423 call writefile(lines, 'Xtest.vim', 'D')
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200424
Bram Moolenaar0d702022019-07-04 14:20:41 +0200425 let buf = term_start(GetVimCommandCleanTerm() .. ' -S Xtest.vim', {'term_rows': 8})
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200426 let job = term_getjob(buf)
427 call WaitForAssert({-> assert_notequal('', term_getline(buf, 8))})
428
429 " GC must not run during map-expr processing, which can make Vim crash.
430 call term_sendkeys(buf, '!')
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200431 call TermWait(buf, 50)
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200432 call term_sendkeys(buf, "\<CR>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200433 call TermWait(buf, 50)
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200434 call assert_equal('run', job_status(job))
435
436 call term_sendkeys(buf, ":qall!\<CR>")
437 call WaitFor({-> job_status(job) ==# 'dead'})
438 if has('unix')
439 call assert_equal('', job_info(job).termsig)
440 endif
441
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200442 exe buf .. 'bwipe!'
443endfunc
Bram Moolenaarfafb4b12019-10-16 18:34:57 +0200444
445func Test_list_mappings()
Bram Moolenaar2559a472019-10-16 23:33:12 +0200446 " Remove default mappings
447 imapclear
Bram Moolenaar4f2f61a2019-10-16 22:27:49 +0200448
Bram Moolenaare3d1f4c2021-04-06 20:21:59 +0200449 " reset 'isident' to check it isn't used
450 set isident=
451 inoremap <C-m> CtrlM
Bram Moolenaarfafb4b12019-10-16 18:34:57 +0200452 inoremap <A-S> AltS
453 inoremap <S-/> ShiftSlash
Bram Moolenaare3d1f4c2021-04-06 20:21:59 +0200454 set isident&
Bram Moolenaarfafb4b12019-10-16 18:34:57 +0200455 call assert_equal([
456 \ 'i <S-/> * ShiftSlash',
457 \ 'i <M-S> * AltS',
458 \ 'i <C-M> * CtrlM',
459 \], execute('imap')->trim()->split("\n"))
460 iunmap <C-M>
461 iunmap <A-S>
462 call assert_equal(['i <S-/> * ShiftSlash'], execute('imap')->trim()->split("\n"))
463 iunmap <S-/>
464 call assert_equal(['No mapping found'], execute('imap')->trim()->split("\n"))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100465
466 " List global, buffer local and script local mappings
467 nmap ,f /^\k\+ (<CR>
468 nmap <buffer> ,f /^\k\+ (<CR>
469 nmap <script> ,fs /^\k\+ (<CR>
470 call assert_equal(['n ,f @/^\k\+ (<CR>',
471 \ 'n ,fs & /^\k\+ (<CR>',
472 \ 'n ,f /^\k\+ (<CR>'],
473 \ execute('nmap ,f')->trim()->split("\n"))
474
475 " List <Nop> mapping
476 nmap ,n <Nop>
477 call assert_equal(['n ,n <Nop>'],
478 \ execute('nmap ,n')->trim()->split("\n"))
479
Bram Moolenaar7f51bbe2020-01-24 20:21:19 +0100480 " verbose map
481 call assert_match("\tLast set from .*/test_mapping.vim line \\d\\+$",
482 \ execute('verbose map ,n')->trim()->split("\n")[1])
483
zeertzjqac402f42022-05-04 18:51:43 +0100484 " character with K_SPECIAL byte in rhs
485 nmap foo
486 call assert_equal(['n foo …'],
487 \ execute('nmap foo')->trim()->split("\n"))
488
489 " modified character with K_SPECIAL byte in rhs
490 nmap foo <M-…>
491 call assert_equal(['n foo <M-…>'],
492 \ execute('nmap foo')->trim()->split("\n"))
493
494 " character with K_SPECIAL byte in lhs
495 nmap foo
496 call assert_equal(['n … foo'],
497 \ execute('nmap …')->trim()->split("\n"))
498
499 " modified character with K_SPECIAL byte in lhs
500 nmap <M-…> foo
501 call assert_equal(['n <M-…> foo'],
502 \ execute('nmap <M-…>')->trim()->split("\n"))
503
zeertzjq0519ce02022-05-09 12:16:19 +0100504 " illegal bytes
505 let str = ":\x7f:\x80:\x90:\xd0:"
506 exe 'nmap foo ' .. str
507 call assert_equal(['n foo ' .. strtrans(str)],
508 \ execute('nmap foo')->trim()->split("\n"))
509 unlet str
510
Bram Moolenaar7f51bbe2020-01-24 20:21:19 +0100511 " map to CTRL-V
512 exe "nmap ,k \<C-V>"
513 call assert_equal(['n ,k <Nop>'],
514 \ execute('nmap ,k')->trim()->split("\n"))
515
Yegappan Lakshmanan2d6d7182021-06-13 21:52:48 +0200516 " map with space at the beginning
517 exe "nmap \<C-V> w <Nop>"
518 call assert_equal(['n <Space>w <Nop>'],
519 \ execute("nmap \<C-V> w")->trim()->split("\n"))
520
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100521 nmapclear
Bram Moolenaarfafb4b12019-10-16 18:34:57 +0200522endfunc
Bram Moolenaar4ebe0e62019-11-22 20:55:40 +0100523
Bram Moolenaar18b7d862021-03-17 13:28:05 +0100524func Test_expr_map_gets_cursor()
525 new
526 call setline(1, ['one', 'some w!rd'])
527 func StoreColumn()
528 let g:exprLine = line('.')
529 let g:exprCol = col('.')
530 return 'x'
531 endfunc
532 nnoremap <expr> x StoreColumn()
533 2
534 nmap ! f!<Ignore>x
535 call feedkeys("!", 'xt')
536 call assert_equal('some wrd', getline(2))
537 call assert_equal(2, g:exprLine)
538 call assert_equal(7, g:exprCol)
539
540 bwipe!
541 unlet g:exprLine
542 unlet g:exprCol
Bram Moolenaar6ccfd992021-03-17 13:39:33 +0100543 delfunc StoreColumn
Bram Moolenaar18b7d862021-03-17 13:28:05 +0100544 nunmap x
545 nunmap !
546endfunc
547
Bram Moolenaar4ebe0e62019-11-22 20:55:40 +0100548func Test_expr_map_restore_cursor()
549 CheckScreendump
550
551 let lines =<< trim END
552 call setline(1, ['one', 'two', 'three'])
553 2
554 set ls=2
555 hi! link StatusLine ErrorMsg
556 noremap <expr> <C-B> Func()
557 func Func()
558 let g:on = !get(g:, 'on', 0)
559 redraws
560 return ''
561 endfunc
562 func Status()
563 return get(g:, 'on', 0) ? '[on]' : ''
564 endfunc
565 set stl=%{Status()}
566 END
Bram Moolenaarb152b6a2022-09-29 21:37:33 +0100567 call writefile(lines, 'XtestExprMap', 'D')
Bram Moolenaar4ebe0e62019-11-22 20:55:40 +0100568 let buf = RunVimInTerminal('-S XtestExprMap', #{rows: 10})
Bram Moolenaar4ebe0e62019-11-22 20:55:40 +0100569 call term_sendkeys(buf, "\<C-B>")
570 call VerifyScreenDump(buf, 'Test_map_expr_1', {})
571
572 " clean up
573 call StopVimInTerminal(buf)
Bram Moolenaar4ebe0e62019-11-22 20:55:40 +0100574endfunc
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100575
Bram Moolenaard288eaa2022-02-16 18:27:55 +0000576func Test_map_listing()
577 CheckScreendump
578
579 let lines =<< trim END
580 nmap a b
581 END
Bram Moolenaarb152b6a2022-09-29 21:37:33 +0100582 call writefile(lines, 'XtestMapList', 'D')
Bram Moolenaard288eaa2022-02-16 18:27:55 +0000583 let buf = RunVimInTerminal('-S XtestMapList', #{rows: 6})
584 call term_sendkeys(buf, ": nmap a\<CR>")
585 call VerifyScreenDump(buf, 'Test_map_list_1', {})
586
587 " clean up
588 call StopVimInTerminal(buf)
Bram Moolenaard288eaa2022-02-16 18:27:55 +0000589endfunc
590
Bram Moolenaar74a0a5b2022-02-10 14:07:41 +0000591func Test_expr_map_error()
592 CheckScreendump
593
594 let lines =<< trim END
595 func Func()
596 throw 'test'
597 return ''
598 endfunc
599
600 nnoremap <expr> <F2> Func()
601 cnoremap <expr> <F2> Func()
602
603 call test_override('ui_delay', 10)
604 END
Bram Moolenaarb152b6a2022-09-29 21:37:33 +0100605 call writefile(lines, 'XtestExprMap', 'D')
Bram Moolenaar74a0a5b2022-02-10 14:07:41 +0000606 let buf = RunVimInTerminal('-S XtestExprMap', #{rows: 10})
Bram Moolenaar74a0a5b2022-02-10 14:07:41 +0000607 call term_sendkeys(buf, "\<F2>")
608 call TermWait(buf)
609 call term_sendkeys(buf, "\<CR>")
610 call VerifyScreenDump(buf, 'Test_map_expr_2', {})
611
612 call term_sendkeys(buf, ":abc\<F2>")
613 call VerifyScreenDump(buf, 'Test_map_expr_3', {})
614 call term_sendkeys(buf, "\<Esc>0")
615 call VerifyScreenDump(buf, 'Test_map_expr_4', {})
616
617 " clean up
618 call StopVimInTerminal(buf)
Bram Moolenaar74a0a5b2022-02-10 14:07:41 +0000619endfunc
620
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100621" Test for mapping errors
622func Test_map_error()
623 call assert_fails('unmap', 'E474:')
624 call assert_fails("exe 'map ' .. repeat('a', 51) .. ' :ls'", 'E474:')
625 call assert_fails('unmap abc', 'E31:')
626 call assert_fails('unabbr abc', 'E24:')
627 call assert_equal('', maparg(''))
628 call assert_fails('echo maparg("abc", [])', 'E730:')
629
630 " unique map
631 map ,w /[#&!]<CR>
632 call assert_fails("map <unique> ,w /[#&!]<CR>", 'E227:')
633 " unique buffer-local map
634 call assert_fails("map <buffer> <unique> ,w /[.,;]<CR>", 'E225:')
635 unmap ,w
636
637 " unique abbreviation
638 abbr SP special
639 call assert_fails("abbr <unique> SP special", 'E226:')
640 " unique buffer-local map
641 call assert_fails("abbr <buffer> <unique> SP special", 'E224:')
642 unabbr SP
643
644 call assert_fails('mapclear abc', 'E474:')
645 call assert_fails('abclear abc', 'E474:')
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100646 call assert_fails('abbr $xyz abc', 'E474:')
647
648 " space character in an abbreviation
649 call assert_fails('abbr ab<space> ABC', 'E474:')
650
651 " invalid <expr> map
652 map <expr> ,f abc
653 call assert_fails('normal ,f', 'E121:')
654 unmap <expr> ,f
Bram Moolenaar9f6277b2020-02-11 22:04:02 +0100655
656 " Recursive use of :normal in a map
657 set maxmapdepth=100
658 map gq :normal gq<CR>
659 call assert_fails('normal gq', 'E192:')
660 unmap gq
661 set maxmapdepth&
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100662endfunc
663
664" Test for <special> key mapping
665func Test_map_special()
666 new
667 let old_cpo = &cpo
668 set cpo+=<
669 imap <F12> Blue
670 call feedkeys("i\<F12>", "x")
671 call assert_equal("<F12>", getline(1))
672 call feedkeys("ddi<F12>", "x")
673 call assert_equal("Blue", getline(1))
674 iunmap <F12>
675 imap <special> <F12> Green
676 call feedkeys("ddi\<F12>", "x")
677 call assert_equal("Green", getline(1))
678 call feedkeys("ddi<F12>", "x")
679 call assert_equal("<F12>", getline(1))
680 iunmap <special> <F12>
681 let &cpo = old_cpo
682 %bwipe!
683endfunc
684
685" Test for hasmapto()
686func Test_hasmapto()
687 call assert_equal(0, hasmapto('/^\k\+ ('))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100688 map ,f /^\k\+ (<CR>
689 call assert_equal(1, hasmapto('/^\k\+ ('))
690 unmap ,f
691
692 " Insert mode mapping
693 call assert_equal(0, hasmapto('/^\k\+ (', 'i'))
694 imap ,f /^\k\+ (<CR>
695 call assert_equal(1, hasmapto('/^\k\+ (', 'i'))
696 iunmap ,f
697
698 " Normal mode mapping
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100699 call assert_equal(0, hasmapto('/^\k\+ (', 'n'))
700 nmap ,f /^\k\+ (<CR>
701 call assert_equal(1, hasmapto('/^\k\+ ('))
702 call assert_equal(1, hasmapto('/^\k\+ (', 'n'))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100703 nunmap ,f
704
705 " Visual and Select mode mapping
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100706 call assert_equal(0, hasmapto('/^\k\+ (', 'v'))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100707 call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
708 call assert_equal(0, hasmapto('/^\k\+ (', 's'))
709 vmap ,f /^\k\+ (<CR>
710 call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
711 call assert_equal(1, hasmapto('/^\k\+ (', 'x'))
712 call assert_equal(1, hasmapto('/^\k\+ (', 's'))
713 vunmap ,f
714
715 " Visual mode mapping
716 call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
717 xmap ,f /^\k\+ (<CR>
718 call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
719 call assert_equal(1, hasmapto('/^\k\+ (', 'x'))
720 call assert_equal(0, hasmapto('/^\k\+ (', 's'))
721 xunmap ,f
722
723 " Select mode mapping
724 call assert_equal(0, hasmapto('/^\k\+ (', 's'))
725 smap ,f /^\k\+ (<CR>
726 call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
727 call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
728 call assert_equal(1, hasmapto('/^\k\+ (', 's'))
729 sunmap ,f
730
731 " Operator-pending mode mapping
732 call assert_equal(0, hasmapto('/^\k\+ (', 'o'))
733 omap ,f /^\k\+ (<CR>
734 call assert_equal(1, hasmapto('/^\k\+ (', 'o'))
735 ounmap ,f
736
737 " Language mapping
738 call assert_equal(0, hasmapto('/^\k\+ (', 'l'))
739 lmap ,f /^\k\+ (<CR>
740 call assert_equal(1, hasmapto('/^\k\+ (', 'l'))
741 lunmap ,f
742
743 " Cmdline mode mapping
744 call assert_equal(0, hasmapto('/^\k\+ (', 'c'))
745 cmap ,f /^\k\+ (<CR>
746 call assert_equal(1, hasmapto('/^\k\+ (', 'c'))
747 cunmap ,f
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100748
749 call assert_equal(0, hasmapto('/^\k\+ (', 'n', 1))
750endfunc
751
752" Test for command-line completion of maps
753func Test_mapcomplete()
754 call assert_equal(['<buffer>', '<expr>', '<nowait>', '<script>',
755 \ '<silent>', '<special>', '<unique>'],
756 \ getcompletion('', 'mapping'))
757 call assert_equal([], getcompletion(',d', 'mapping'))
758
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100759 call feedkeys(":unmap <buf\<C-A>\<C-B>\"\<CR>", 'tx')
760 call assert_equal('"unmap <buffer>', @:)
761
762 call feedkeys(":unabbr <buf\<C-A>\<C-B>\"\<CR>", 'tx')
763 call assert_equal('"unabbr <buffer>', @:)
764
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100765 call feedkeys(":abbr! \<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100766 call assert_equal("\"abbr! \x01", @:)
767
768 " Multiple matches for a map
769 nmap ,f /H<CR>
770 omap ,f /H<CR>
771 call feedkeys(":map ,\<C-A>\<C-B>\"\<CR>", 'tx')
772 call assert_equal('"map ,f', @:)
773 mapclear
774endfunc
775
Bram Moolenaar94075b22022-01-18 20:30:39 +0000776func GetAbbrText()
777 unabbr hola
778 return 'hello'
779endfunc
780
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100781" Test for <expr> in abbreviation
782func Test_expr_abbr()
783 new
784 iabbr <expr> teh "the"
785 call feedkeys("iteh ", "tx")
786 call assert_equal('the ', getline(1))
787 iabclear
788 call setline(1, '')
789
790 " invalid <expr> abbreviation
791 abbr <expr> hte GetAbbr()
792 call assert_fails('normal ihte ', 'E117:')
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100793 call assert_equal('', getline(1))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100794 unabbr <expr> hte
795
Bram Moolenaar94075b22022-01-18 20:30:39 +0000796 " evaluating the expression deletes the abbreviation
797 abbr <expr> hola GetAbbrText()
798 call assert_equal('GetAbbrText()', maparg('hola', 'i', '1'))
799 call feedkeys("ahola \<Esc>", 'xt')
800 call assert_equal('hello ', getline('.'))
801 call assert_equal('', maparg('hola', 'i', '1'))
802
803 bwipe!
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100804endfunc
805
806" Test for storing mappings in different modes in a vimrc file
807func Test_mkvimrc_mapmodes()
808 map a1 /a1
809 nmap a2 /a2
810 vmap a3 /a3
811 smap a4 /a4
812 xmap a5 /a5
813 omap a6 /a6
814 map! a7 /a7
815 imap a8 /a8
816 lmap a9 /a9
817 cmap a10 /a10
818 tmap a11 /a11
819 " Normal + Visual map
820 map a12 /a12
821 sunmap a12
822 ounmap a12
823 " Normal + Selectmode map
824 map a13 /a13
825 xunmap a13
826 ounmap a13
827 " Normal + OpPending map
828 map a14 /a14
829 vunmap a14
830 " Visual + Selectmode map
831 map a15 /a15
832 nunmap a15
833 ounmap a15
834 " Visual + OpPending map
835 map a16 /a16
836 nunmap a16
837 sunmap a16
838 " Selectmode + OpPending map
839 map a17 /a17
840 nunmap a17
841 xunmap a17
842 " Normal + Visual + Selectmode map
843 map a18 /a18
844 ounmap a18
845 " Normal + Visual + OpPending map
846 map a19 /a19
847 sunmap a19
848 " Normal + Selectmode + OpPending map
849 map a20 /a20
850 xunmap a20
851 " Visual + Selectmode + OpPending map
852 map a21 /a21
853 nunmap a21
854 " Mapping to Nop
855 map a22 <Nop>
856 " Script local mapping
857 map <script> a23 /a23
858
859 " Newline in {lhs} and {rhs} of a map
860 exe "map a24\<C-V>\<C-J> ia24\<C-V>\<C-J><Esc>"
861
862 " Abbreviation
863 abbr a25 A25
864 cabbr a26 A26
865 iabbr a27 A27
866
867 mkvimrc! Xvimrc
868 let l = readfile('Xvimrc')
869 call assert_equal(['map a1 /a1'], filter(copy(l), 'v:val =~ " a1 "'))
870 call assert_equal(['nmap a2 /a2'], filter(copy(l), 'v:val =~ " a2 "'))
871 call assert_equal(['vmap a3 /a3'], filter(copy(l), 'v:val =~ " a3 "'))
872 call assert_equal(['smap a4 /a4'], filter(copy(l), 'v:val =~ " a4 "'))
873 call assert_equal(['xmap a5 /a5'], filter(copy(l), 'v:val =~ " a5 "'))
874 call assert_equal(['omap a6 /a6'], filter(copy(l), 'v:val =~ " a6 "'))
875 call assert_equal(['map! a7 /a7'], filter(copy(l), 'v:val =~ " a7 "'))
876 call assert_equal(['imap a8 /a8'], filter(copy(l), 'v:val =~ " a8 "'))
877 call assert_equal(['lmap a9 /a9'], filter(copy(l), 'v:val =~ " a9 "'))
878 call assert_equal(['cmap a10 /a10'], filter(copy(l), 'v:val =~ " a10 "'))
879 call assert_equal(['tmap a11 /a11'], filter(copy(l), 'v:val =~ " a11 "'))
880 call assert_equal(['nmap a12 /a12', 'xmap a12 /a12'],
881 \ filter(copy(l), 'v:val =~ " a12 "'))
882 call assert_equal(['nmap a13 /a13', 'smap a13 /a13'],
883 \ filter(copy(l), 'v:val =~ " a13 "'))
884 call assert_equal(['nmap a14 /a14', 'omap a14 /a14'],
885 \ filter(copy(l), 'v:val =~ " a14 "'))
886 call assert_equal(['vmap a15 /a15'], filter(copy(l), 'v:val =~ " a15 "'))
887 call assert_equal(['xmap a16 /a16', 'omap a16 /a16'],
888 \ filter(copy(l), 'v:val =~ " a16 "'))
889 call assert_equal(['smap a17 /a17', 'omap a17 /a17'],
890 \ filter(copy(l), 'v:val =~ " a17 "'))
891 call assert_equal(['nmap a18 /a18', 'vmap a18 /a18'],
892 \ filter(copy(l), 'v:val =~ " a18 "'))
893 call assert_equal(['nmap a19 /a19', 'xmap a19 /a19', 'omap a19 /a19'],
894 \ filter(copy(l), 'v:val =~ " a19 "'))
895 call assert_equal(['nmap a20 /a20', 'smap a20 /a20', 'omap a20 /a20'],
896 \ filter(copy(l), 'v:val =~ " a20 "'))
897 call assert_equal(['vmap a21 /a21', 'omap a21 /a21'],
898 \ filter(copy(l), 'v:val =~ " a21 "'))
899 call assert_equal(['map a22 <Nop>'], filter(copy(l), 'v:val =~ " a22 "'))
900 call assert_equal([], filter(copy(l), 'v:val =~ " a23 "'))
901 call assert_equal(["map a24<NL> ia24<NL>\x16\e"],
902 \ filter(copy(l), 'v:val =~ " a24"'))
903
904 call assert_equal(['abbr a25 A25'], filter(copy(l), 'v:val =~ " a25 "'))
905 call assert_equal(['cabbr a26 A26'], filter(copy(l), 'v:val =~ " a26 "'))
906 call assert_equal(['iabbr a27 A27'], filter(copy(l), 'v:val =~ " a27 "'))
907 call delete('Xvimrc')
908
909 mapclear
910 nmapclear
911 vmapclear
912 xmapclear
913 smapclear
914 omapclear
915 imapclear
916 lmapclear
917 cmapclear
918 tmapclear
919endfunc
920
921" Test for recursive mapping ('maxmapdepth')
922func Test_map_recursive()
923 map x y
924 map y x
925 call assert_fails('normal x', 'E223:')
926 unmap x
927 unmap y
928endfunc
929
930" Test for removing an abbreviation using {rhs} and with space after {lhs}
931func Test_abbr_remove()
932 abbr foo bar
933 let d = maparg('foo', 'i', 1, 1)
934 call assert_equal(['foo', 'bar', '!'], [d.lhs, d.rhs, d.mode])
935 unabbr bar
936 call assert_equal({}, maparg('foo', 'i', 1, 1))
937
938 abbr foo bar
939 unabbr foo<space><tab>
940 call assert_equal({}, maparg('foo', 'i', 1, 1))
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100941endfunc
942
Bram Moolenaar7f51bbe2020-01-24 20:21:19 +0100943" Trigger an abbreviation using a special key
944func Test_abbr_trigger_special()
945 new
946 iabbr teh the
947 call feedkeys("iteh\<F2>\<Esc>", 'xt')
948 call assert_equal('the<F2>', getline(1))
949 iunab teh
950 close!
951endfunc
952
953" Test for '<' in 'cpoptions'
954func Test_map_cpo_special_keycode()
955 set cpo-=<
956 imap x<Bslash>k Test
957 let d = maparg('x<Bslash>k', 'i', 0, 1)
958 call assert_equal(['x\k', 'Test', 'i'], [d.lhs, d.rhs, d.mode])
959 call feedkeys(":imap x\<C-A>\<C-B>\"\<CR>", 'tx')
960 call assert_equal('"imap x\k', @:)
961 iunmap x<Bslash>k
962 set cpo+=<
963 imap x<Bslash>k Test
964 let d = maparg('x<Bslash>k', 'i', 0, 1)
965 call assert_equal(['x<Bslash>k', 'Test', 'i'], [d.lhs, d.rhs, d.mode])
966 call feedkeys(":imap x\<C-A>\<C-B>\"\<CR>", 'tx')
967 call assert_equal('"imap x<Bslash>k', @:)
968 iunmap x<Bslash>k
969 set cpo-=<
970 " Modifying 'cpo' above adds some default mappings, remove them
971 mapclear
972 mapclear!
973endfunc
974
Bram Moolenaar957cf672020-11-12 14:21:06 +0100975" Test for <Cmd> key in maps to execute commands
976func Test_map_cmdkey()
977 new
978
979 " Error cases
980 let x = 0
981 noremap <F3> <Cmd><Cmd>let x = 1<CR>
982 call assert_fails('call feedkeys("\<F3>", "xt")', 'E1136:')
983 call assert_equal(0, x)
984
985 noremap <F3> <Cmd><F3>let x = 2<CR>
986 call assert_fails('call feedkeys("\<F3>", "xt")', 'E1137:')
987 call assert_equal(0, x)
988
989 noremap <F3> <Cmd>let x = 3
Bram Moolenaar806da512021-12-24 19:54:52 +0000990 call assert_fails('call feedkeys("\<F3>", "xt!")', 'E1255:')
Bram Moolenaar957cf672020-11-12 14:21:06 +0100991 call assert_equal(0, x)
992
993 " works in various modes and sees the correct mode()
994 noremap <F3> <Cmd>let m = mode(1)<CR>
995 noremap! <F3> <Cmd>let m = mode(1)<CR>
996
997 " normal mode
998 call feedkeys("\<F3>", 'xt')
999 call assert_equal('n', m)
1000
1001 " visual mode
1002 call feedkeys("v\<F3>", 'xt!')
1003 call assert_equal('v', m)
1004 " shouldn't leave the visual mode
1005 call assert_equal('v', mode(1))
1006 call feedkeys("\<Esc>", 'xt')
1007 call assert_equal('n', mode(1))
1008
1009 " visual mapping in select mode
1010 call feedkeys("gh\<F3>", 'xt!')
1011 call assert_equal('v', m)
1012 " shouldn't leave select mode
1013 call assert_equal('s', mode(1))
1014 call feedkeys("\<Esc>", 'xt')
1015 call assert_equal('n', mode(1))
1016
1017 " select mode mapping
1018 snoremap <F3> <Cmd>let m = mode(1)<cr>
1019 call feedkeys("gh\<F3>", 'xt!')
1020 call assert_equal('s', m)
1021 " shouldn't leave select mode
1022 call assert_equal('s', mode(1))
1023 call feedkeys("\<Esc>", 'xt')
1024 call assert_equal('n', mode(1))
1025
1026 " operator-pending mode
1027 call feedkeys("d\<F3>", 'xt!')
1028 call assert_equal('no', m)
1029 " leaves the operator-pending mode
1030 call assert_equal('n', mode(1))
1031
1032 " insert mode
1033 call feedkeys("i\<F3>abc", 'xt')
1034 call assert_equal('i', m)
1035 call assert_equal('abc', getline('.'))
1036
1037 " replace mode
1038 call feedkeys("0R\<F3>two", 'xt')
1039 call assert_equal('R', m)
1040 call assert_equal('two', getline('.'))
1041
1042 " virtual replace mode
1043 call setline('.', "one\ttwo")
1044 call feedkeys("4|gR\<F3>xxx", 'xt')
1045 call assert_equal('Rv', m)
1046 call assert_equal("onexxx\ttwo", getline('.'))
1047
1048 " cmdline mode
1049 call feedkeys(":\<F3>\"xxx\<CR>", 'xt!')
1050 call assert_equal('c', m)
1051 call assert_equal('"xxx', @:)
1052
1053 " terminal mode
1054 if CanRunVimInTerminal()
1055 tnoremap <F3> <Cmd>let m = mode(1)<CR>
1056 let buf = Run_shell_in_terminal({})
1057 call feedkeys("\<F3>", 'xt')
1058 call assert_equal('t', m)
1059 call assert_equal('t', mode(1))
1060 call StopShellInTerminal(buf)
Bram Moolenaar957cf672020-11-12 14:21:06 +01001061 close!
1062 tunmap <F3>
1063 endif
1064
1065 " invoke cmdline mode recursively
1066 noremap! <F2> <Cmd>norm! :foo<CR>
1067 %d
1068 call setline(1, ['some short lines', 'of test text'])
1069 call feedkeys(":bar\<F2>x\<C-B>\"\r", 'xt')
1070 call assert_equal('"barx', @:)
1071 unmap! <F2>
1072
1073 " test for calling a <SID> function
1074 let lines =<< trim END
1075 map <F2> <Cmd>call <SID>do_it()<CR>
1076 func s:do_it()
1077 let g:x = 32
1078 endfunc
1079 END
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001080 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar957cf672020-11-12 14:21:06 +01001081 source Xscript
1082 call feedkeys("\<F2>", 'xt')
1083 call assert_equal(32, g:x)
Bram Moolenaar957cf672020-11-12 14:21:06 +01001084
1085 unmap <F3>
1086 unmap! <F3>
1087 %bw!
Bram Moolenaar4a441202020-11-28 14:43:26 +01001088
1089 " command line ending in "0" is handled without errors
1090 onoremap ix <cmd>eval 0<cr>
1091 call feedkeys('dix.', 'xt')
1092 ounmap ix
Bram Moolenaar957cf672020-11-12 14:21:06 +01001093endfunc
1094
1095" text object enters visual mode
1096func TextObj()
1097 if mode() !=# "v"
1098 normal! v
1099 end
1100 call cursor(1, 3)
1101 normal! o
1102 call cursor(2, 4)
1103endfunc
1104
1105func s:cmdmap(lhs, rhs)
1106 exe 'noremap ' .. a:lhs .. ' <Cmd>' .. a:rhs .. '<CR>'
1107 exe 'noremap! ' .. a:lhs .. ' <Cmd>' .. a:rhs .. '<CR>'
1108endfunc
1109
1110func s:cmdunmap(lhs)
1111 exe 'unmap ' .. a:lhs
1112 exe 'unmap! ' .. a:lhs
1113endfunc
1114
1115" Map various <Fx> keys used by the <Cmd> key tests
1116func s:setupMaps()
1117 call s:cmdmap('<F3>', 'let m = mode(1)')
1118 call s:cmdmap('<F4>', 'normal! ww')
1119 call s:cmdmap('<F5>', 'normal! "ay')
1120 call s:cmdmap('<F6>', 'throw "very error"')
1121 call s:cmdmap('<F7>', 'call TextObj()')
1122 call s:cmdmap('<F8>', 'startinsert')
1123 call s:cmdmap('<F9>', 'stopinsert')
1124endfunc
1125
1126" Remove the mappings setup by setupMaps()
1127func s:cleanupMaps()
1128 call s:cmdunmap('<F3>')
1129 call s:cmdunmap('<F4>')
1130 call s:cmdunmap('<F5>')
1131 call s:cmdunmap('<F6>')
1132 call s:cmdunmap('<F7>')
1133 call s:cmdunmap('<F8>')
1134 call s:cmdunmap('<F9>')
1135endfunc
1136
1137" Test for <Cmd> mapping in normal mode
1138func Test_map_cmdkey_normal_mode()
1139 new
1140 call s:setupMaps()
1141
1142 " check v:count and v:register works
1143 call s:cmdmap('<F2>', 'let s = [mode(1), v:count, v:register]')
1144 call feedkeys("\<F2>", 'xt')
1145 call assert_equal(['n', 0, '"'], s)
1146 call feedkeys("7\<F2>", 'xt')
1147 call assert_equal(['n', 7, '"'], s)
1148 call feedkeys("\"e\<F2>", 'xt')
1149 call assert_equal(['n', 0, 'e'], s)
1150 call feedkeys("5\"k\<F2>", 'xt')
1151 call assert_equal(['n', 5, 'k'], s)
1152 call s:cmdunmap('<F2>')
1153
1154 call setline(1, ['some short lines', 'of test text'])
1155 call feedkeys("\<F7>y", 'xt')
1156 call assert_equal("me short lines\nof t", @")
1157 call assert_equal('v', getregtype('"'))
1158 call assert_equal([0, 1, 3, 0], getpos("'<"))
1159 call assert_equal([0, 2, 4, 0], getpos("'>"))
1160
1161 " startinsert
1162 %d
1163 call feedkeys("\<F8>abc", 'xt')
1164 call assert_equal('abc', getline(1))
1165
1166 " feedkeys are not executed immediately
1167 noremap ,a <Cmd>call feedkeys("aalpha") \| let g:a = getline(2)<CR>
1168 %d
1169 call setline(1, ['some short lines', 'of test text'])
1170 call cursor(2, 3)
1171 call feedkeys(",a\<F3>", 'xt')
1172 call assert_equal('of test text', g:a)
1173 call assert_equal('n', m)
1174 call assert_equal(['some short lines', 'of alphatest text'], getline(1, '$'))
1175 nunmap ,a
1176
1177 " feedkeys(..., 'x') is executed immediately, but insert mode is aborted
1178 noremap ,b <Cmd>call feedkeys("abeta", 'x') \| let g:b = getline(2)<CR>
1179 call feedkeys(",b\<F3>", 'xt')
1180 call assert_equal('n', m)
1181 call assert_equal('of alphabetatest text', g:b)
1182 nunmap ,b
1183
1184 call s:cleanupMaps()
1185 %bw!
1186endfunc
1187
1188" Test for <Cmd> mapping with the :normal command
1189func Test_map_cmdkey_normal_cmd()
1190 new
1191 noremap ,x <Cmd>call append(1, "xx") \| call append(1, "aa")<CR>
1192 noremap ,f <Cmd>nosuchcommand<CR>
1193 noremap ,e <Cmd>throw "very error" \| call append(1, "yy")<CR>
1194 noremap ,m <Cmd>echoerr "The message." \| call append(1, "zz")<CR>
1195 noremap ,w <Cmd>for i in range(5) \| if i==1 \| echoerr "Err" \| endif \| call append(1, i) \| endfor<CR>
1196
1197 call setline(1, ['some short lines', 'of test text'])
1198 exe "norm ,x\r"
1199 call assert_equal(['some short lines', 'aa', 'xx', 'of test text'], getline(1, '$'))
1200
1201 call assert_fails('norm ,f', 'E492:')
1202 call assert_fails('norm ,e', 'very error')
1203 call assert_fails('norm ,m', 'The message.')
1204 call assert_equal(['some short lines', 'aa', 'xx', 'of test text'], getline(1, '$'))
1205
1206 %d
1207 let caught_err = 0
1208 try
1209 exe "normal ,w"
1210 catch /Vim(echoerr):Err/
1211 let caught_err = 1
1212 endtry
1213 call assert_equal(1, caught_err)
1214 call assert_equal(['', '0'], getline(1, '$'))
1215
1216 %d
1217 call assert_fails('normal ,w', 'Err')
1218 call assert_equal(['', '4', '3', '2' ,'1', '0'], getline(1, '$'))
1219 call assert_equal(1, line('.'))
1220
1221 nunmap ,x
1222 nunmap ,f
1223 nunmap ,e
1224 nunmap ,m
1225 nunmap ,w
1226 %bw!
1227endfunc
1228
1229" Test for <Cmd> mapping in visual mode
1230func Test_map_cmdkey_visual_mode()
1231 new
1232 set showmode
1233 call s:setupMaps()
1234
1235 call setline(1, ['some short lines', 'of test text'])
1236 call feedkeys("v\<F4>", 'xt!')
1237 call assert_equal(['v', 1, 12], [mode(1), col('v'), col('.')])
1238
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +01001239 " can invoke an operator, ending the visual mode
Bram Moolenaar957cf672020-11-12 14:21:06 +01001240 let @a = ''
1241 call feedkeys("\<F5>", 'xt!')
1242 call assert_equal('n', mode(1))
1243 call assert_equal('some short l', @a)
1244
1245 " error doesn't interrupt visual mode
1246 call assert_fails('call feedkeys("ggvw\<F6>", "xt!")', 'E605:')
1247 call assert_equal(['v', 1, 6], [mode(1), col('v'), col('.')])
1248 call feedkeys("\<F7>", 'xt!')
1249 call assert_equal(['v', 1, 3, 2, 4], [mode(1), line('v'), col('v'), line('.'), col('.')])
1250
1251 " startinsert gives "-- (insert) VISUAL --" mode
1252 call feedkeys("\<F8>", 'xt!')
1253 call assert_equal(['v', 1, 3, 2, 4], [mode(1), line('v'), col('v'), line('.'), col('.')])
1254 redraw!
1255 call assert_match('^-- (insert) VISUAL --', Screenline(&lines))
1256 call feedkeys("\<Esc>new ", 'x')
1257 call assert_equal(['some short lines', 'of new test text'], getline(1, '$'))
1258
1259 call s:cleanupMaps()
1260 set showmode&
1261 %bw!
1262endfunc
1263
1264" Test for <Cmd> mapping in select mode
1265func Test_map_cmdkey_select_mode()
1266 new
1267 set showmode
1268 call s:setupMaps()
1269
1270 snoremap <F1> <cmd>throw "very error"<CR>
1271 snoremap <F2> <cmd>normal! <c-g>"by<CR>
1272 call setline(1, ['some short lines', 'of test text'])
1273
1274 call feedkeys("gh\<F4>", "xt!")
1275 call assert_equal(['s', 1, 12], [mode(1), col('v'), col('.')])
1276 redraw!
1277 call assert_match('^-- SELECT --', Screenline(&lines))
1278
1279 " visual mapping in select mode restarts select mode after operator
1280 let @a = ''
1281 call feedkeys("\<F5>", 'xt!')
1282 call assert_equal('s', mode(1))
1283 call assert_equal('some short l', @a)
1284
1285 " select mode mapping works, and does not restart select mode
1286 let @b = ''
1287 call feedkeys("\<F2>", 'xt!')
1288 call assert_equal('n', mode(1))
1289 call assert_equal('some short l', @b)
1290
1291 " error doesn't interrupt temporary visual mode
1292 call assert_fails('call feedkeys("\<Esc>ggvw\<C-G>\<F6>", "xt!")', 'E605:')
1293 redraw!
1294 call assert_match('^-- VISUAL --', Screenline(&lines))
1295 " quirk: restoration of select mode is not performed
1296 call assert_equal(['v', 1, 6], [mode(1), col('v'), col('.')])
1297
1298 " error doesn't interrupt select mode
1299 call assert_fails('call feedkeys("\<Esc>ggvw\<C-G>\<F1>", "xt!")', 'E605:')
1300 redraw!
1301 call assert_match('^-- SELECT --', Screenline(&lines))
1302 call assert_equal(['s', 1, 6], [mode(1), col('v'), col('.')])
1303
1304 call feedkeys("\<F7>", 'xt!')
1305 redraw!
1306 call assert_match('^-- SELECT --', Screenline(&lines))
1307 call assert_equal(['s', 1, 3, 2, 4], [mode(1), line('v'), col('v'), line('.'), col('.')])
1308
1309 " startinsert gives "-- SELECT (insert) --" mode
1310 call feedkeys("\<F8>", 'xt!')
1311 redraw!
1312 call assert_match('^-- (insert) SELECT --', Screenline(&lines))
1313 call assert_equal(['s', 1, 3, 2, 4], [mode(1), line('v'), col('v'), line('.'), col('.')])
1314 call feedkeys("\<Esc>new ", 'x')
1315 call assert_equal(['some short lines', 'of new test text'], getline(1, '$'))
1316
1317 sunmap <F1>
1318 sunmap <F2>
1319 call s:cleanupMaps()
1320 set showmode&
1321 %bw!
1322endfunc
1323
1324" Test for <Cmd> mapping in operator-pending mode
1325func Test_map_cmdkey_op_pending_mode()
1326 new
1327 call s:setupMaps()
1328
1329 call setline(1, ['some short lines', 'of test text'])
1330 call feedkeys("d\<F4>", 'xt')
1331 call assert_equal(['lines', 'of test text'], getline(1, '$'))
1332 call assert_equal(['some short '], getreg('"', 1, 1))
1333 " create a new undo point
1334 let &undolevels = &undolevels
1335
1336 call feedkeys(".", 'xt')
1337 call assert_equal(['test text'], getline(1, '$'))
1338 call assert_equal(['lines', 'of '], getreg('"', 1, 1))
1339 " create a new undo point
1340 let &undolevels = &undolevels
1341
1342 call feedkeys("uu", 'xt')
1343 call assert_equal(['some short lines', 'of test text'], getline(1, '$'))
1344
1345 " error aborts operator-pending, operator not performed
1346 call assert_fails('call feedkeys("d\<F6>", "xt")', 'E605:')
1347 call assert_equal(['some short lines', 'of test text'], getline(1, '$'))
1348
1349 call feedkeys("\"bd\<F7>", 'xt')
1350 call assert_equal(['soest text'], getline(1, '$'))
1351 call assert_equal(['me short lines', 'of t'], getreg('b', 1, 1))
1352
1353 " startinsert aborts operator
1354 call feedkeys("d\<F8>cc", 'xt')
1355 call assert_equal(['soccest text'], getline(1, '$'))
1356
1357 call s:cleanupMaps()
1358 %bw!
1359endfunc
1360
1361" Test for <Cmd> mapping in insert mode
1362func Test_map_cmdkey_insert_mode()
1363 new
1364 call s:setupMaps()
1365
1366 call setline(1, ['some short lines', 'of test text'])
1367 " works the same as <C-O>w<C-O>w
1368 call feedkeys("iindeed \<F4>little ", 'xt')
1369 call assert_equal(['indeed some short little lines', 'of test text'], getline(1, '$'))
1370 call assert_fails('call feedkeys("i\<F6> 2", "xt")', 'E605:')
1371 call assert_equal(['indeed some short little 2 lines', 'of test text'], getline(1, '$'))
1372
1373 " Note when entering visual mode from InsertEnter autocmd, an async event,
1374 " or a <Cmd> mapping, vim ends up in undocumented "INSERT VISUAL" mode.
1375 call feedkeys("i\<F7>stuff ", 'xt')
1376 call assert_equal(['indeed some short little 2 lines', 'of stuff test text'], getline(1, '$'))
1377 call assert_equal(['v', 1, 3, 2, 9], [mode(1), line('v'), col('v'), line('.'), col('.')])
1378
1379 call feedkeys("\<F5>", 'xt')
1380 call assert_equal(['deed some short little 2 lines', 'of stuff '], getreg('a', 1, 1))
1381
1382 " also works as part of abbreviation
1383 abbr foo <Cmd>let g:y = 17<CR>bar
1384 exe "normal i\<space>foo "
1385 call assert_equal(17, g:y)
1386 call assert_equal('in bar deed some short little 2 lines', getline(1))
1387 unabbr foo
1388
1389 " :startinsert does nothing
1390 call setline(1, 'foo bar')
1391 call feedkeys("ggi\<F8>vim", 'xt')
1392 call assert_equal('vimfoo bar', getline(1))
1393
1394 " :stopinsert works
1395 call feedkeys("ggi\<F9>Abc", 'xt')
1396 call assert_equal('vimfoo barbc', getline(1))
1397
1398 call s:cleanupMaps()
1399 %bw!
1400endfunc
1401
1402" Test for <Cmd> mapping in insert-completion mode
1403func Test_map_cmdkey_insert_complete_mode()
1404 new
1405 call s:setupMaps()
1406
1407 call setline(1, 'some short lines')
1408 call feedkeys("os\<C-X>\<C-N>\<F3>\<C-N> ", 'xt')
1409 call assert_equal('ic', m)
1410 call assert_equal(['some short lines', 'short '], getline(1, '$'))
1411
1412 call s:cleanupMaps()
1413 %bw!
1414endfunc
1415
1416" Test for <Cmd> mapping in cmdline mode
1417func Test_map_cmdkey_cmdline_mode()
1418 new
1419 call s:setupMaps()
1420
1421 call setline(1, ['some short lines', 'of test text'])
1422 let x = 0
1423 call feedkeys(":let x\<F3>= 10\r", 'xt')
1424 call assert_equal('c', m)
1425 call assert_equal(10, x)
1426
1427 " exception doesn't leave cmdline mode
1428 call assert_fails('call feedkeys(":let x\<F6>= 20\r", "xt")', 'E605:')
1429 call assert_equal(20, x)
1430
1431 " move cursor in the buffer from cmdline mode
1432 call feedkeys(":let x\<F4>= 30\r", 'xt')
1433 call assert_equal(30, x)
1434 call assert_equal(12, col('.'))
1435
1436 " :startinsert takes effect after leaving cmdline mode
1437 call feedkeys(":let x\<F8>= 40\rnew ", 'xt')
1438 call assert_equal(40, x)
1439 call assert_equal('some short new lines', getline(1))
1440
1441 call s:cleanupMaps()
1442 %bw!
1443endfunc
1444
Bram Moolenaarc77534c2020-11-18 11:34:37 +01001445func Test_map_cmdkey_redo()
1446 func SelectDash()
1447 call search('^---\n\zs', 'bcW')
1448 norm! V
1449 call search('\n\ze---$', 'W')
1450 endfunc
1451
1452 let text =<< trim END
1453 ---
1454 aaa
1455 ---
1456 bbb
1457 bbb
1458 ---
1459 ccc
1460 ccc
1461 ccc
1462 ---
1463 END
1464 new Xcmdtext
1465 call setline(1, text)
1466
1467 onoremap <silent> i- <Cmd>call SelectDash()<CR>
1468 call feedkeys('2Gdi-', 'xt')
1469 call assert_equal(['---', '---'], getline(1, 2))
1470 call feedkeys('j.', 'xt')
1471 call assert_equal(['---', '---', '---'], getline(1, 3))
1472 call feedkeys('j.', 'xt')
1473 call assert_equal(['---', '---', '---', '---'], getline(1, 4))
1474
1475 bwipe!
1476 call delete('Xcmdtext')
1477 delfunc SelectDash
1478 ounmap i-
1479endfunc
1480
Bram Moolenaara9725222022-01-16 13:30:33 +00001481func Test_map_script_cmd_restore()
1482 let lines =<< trim END
1483 vim9script
1484 nnoremap <F3> <ScriptCmd>eval 1 + 2<CR>
1485 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001486 call v9.CheckScriptSuccess(lines)
Bram Moolenaara9725222022-01-16 13:30:33 +00001487 call feedkeys("\<F3>:let g:result = 3+4\<CR>", 'xtc')
1488 call assert_equal(7, g:result)
1489
1490 nunmap <F3>
1491 unlet g:result
1492endfunc
1493
Bram Moolenaardc987762022-01-16 15:52:35 +00001494func Test_map_script_cmd_finds_func()
1495 let lines =<< trim END
1496 vim9script
1497 onoremap <F3> <ScriptCmd>Func()<CR>
1498 def Func()
1499 g:func_called = 'yes'
1500 enddef
1501 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001502 call v9.CheckScriptSuccess(lines)
Bram Moolenaardc987762022-01-16 15:52:35 +00001503 call feedkeys("y\<F3>\<Esc>", 'xtc')
1504 call assert_equal('yes', g:func_called)
1505
1506 ounmap <F3>
1507 unlet g:func_called
1508endfunc
1509
Bram Moolenaarf61c89d2022-01-19 22:51:48 +00001510func Test_map_script_cmd_survives_unmap()
1511 let lines =<< trim END
1512 vim9script
1513 var n = 123
1514 nnoremap <F4> <ScriptCmd><CR>
1515 autocmd CmdlineEnter * silent! nunmap <F4>
1516 nnoremap <F3> :<ScriptCmd>eval setbufvar(bufnr(), "result", n)<CR>
1517 feedkeys("\<F3>\<CR>", 'xct')
1518 assert_equal(123, b:result)
1519 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001520 call v9.CheckScriptSuccess(lines)
Bram Moolenaarf61c89d2022-01-19 22:51:48 +00001521
1522 nunmap <F3>
1523 unlet b:result
Bram Moolenaarca34db32022-01-20 11:17:18 +00001524 autocmd! CmdlineEnter
Bram Moolenaarf61c89d2022-01-19 22:51:48 +00001525endfunc
1526
Bram Moolenaarddf7dba2022-09-05 16:53:21 +01001527func Test_map_script_cmd_redo()
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001528 call mkdir('Xmapcmd', 'R')
Bram Moolenaarddf7dba2022-09-05 16:53:21 +01001529 let lines =<< trim END
1530 vim9script
1531 import autoload './script.vim'
1532 onoremap <F3> <ScriptCmd>script.Func()<CR>
1533 END
1534 call writefile(lines, 'Xmapcmd/plugin.vim')
1535
1536 let lines =<< trim END
1537 vim9script
1538 export def Func()
1539 normal! dd
1540 enddef
1541 END
1542 call writefile(lines, 'Xmapcmd/script.vim')
1543 new
1544 call setline(1, ['one', 'two', 'three', 'four'])
1545 nnoremap j j
1546 source Xmapcmd/plugin.vim
1547 call feedkeys("d\<F3>j.", 'xt')
1548 call assert_equal(['two', 'four'], getline(1, '$'))
1549
1550 ounmap <F3>
1551 nunmap j
Bram Moolenaarddf7dba2022-09-05 16:53:21 +01001552 bwipe!
1553endfunc
1554
Bram Moolenaar1f448d92021-03-22 19:37:06 +01001555" Test for using <script> with a map to remap characters in rhs
1556func Test_script_local_remap()
1557 new
1558 inoremap <buffer> <SID>xyz mno
1559 inoremap <buffer> <script> abc st<SID>xyzre
1560 normal iabc
1561 call assert_equal('stmnore', getline(1))
1562 bwipe!
1563endfunc
1564
Bram Moolenaar4934ed32021-04-30 19:43:11 +02001565func Test_abbreviate_multi_byte()
1566 new
1567 iabbrev foo bar
1568 call feedkeys("ifoo…\<Esc>", 'xt')
1569 call assert_equal("bar…", getline(1))
1570 iunabbrev foo
1571 bwipe!
1572endfunc
1573
Yegappan Lakshmanan2d6d7182021-06-13 21:52:48 +02001574" Test for abbreviations with 'latin1' encoding
1575func Test_abbreviate_latin1_encoding()
1576 set encoding=latin1
1577 call assert_fails('abbr ab#$c ABC', 'E474:')
1578 new
1579 iabbr <buffer> #i #include
1580 iabbr <buffer> ## #enddef
1581 exe "normal i#i\<C-]>"
1582 call assert_equal('#include', getline(1))
1583 exe "normal 0Di##\<C-]>"
1584 call assert_equal('#enddef', getline(1))
1585 %bw!
1586 set encoding=utf-8
1587endfunc
1588
Bram Moolenaar1fc34222022-03-03 13:56:24 +00001589" Test for <Plug> always being mapped, even when used with "noremap".
1590func Test_plug_remap()
1591 let g:foo = 0
1592 nnoremap <Plug>(Increase_x) <Cmd>let g:foo += 1<CR>
1593 nmap <F2> <Plug>(Increase_x)
1594 nnoremap <F3> <Plug>(Increase_x)
1595 call feedkeys("\<F2>", 'xt')
1596 call assert_equal(1, g:foo)
1597 call feedkeys("\<F3>", 'xt')
1598 call assert_equal(2, g:foo)
1599 nnoremap x <Nop>
1600 nmap <F4> x<Plug>(Increase_x)x
1601 nnoremap <F5> x<Plug>(Increase_x)x
1602 call setline(1, 'Some text')
1603 normal! gg$
1604 call feedkeys("\<F4>", 'xt')
1605 call assert_equal(3, g:foo)
1606 call assert_equal('Some text', getline(1))
1607 call feedkeys("\<F5>", 'xt')
1608 call assert_equal(4, g:foo)
1609 call assert_equal('Some te', getline(1))
1610 nunmap <Plug>(Increase_x)
1611 nunmap <F2>
1612 nunmap <F3>
1613 nunmap <F4>
1614 nunmap <F5>
1615 unlet g:foo
1616 %bw!
1617endfunc
1618
zeertzjqac92ab72022-04-24 15:58:30 +01001619func Test_mouse_drag_mapped_start_select()
1620 set mouse=a
1621 set selectmode=key,mouse
1622 func ClickExpr()
1623 call test_setmouse(1, 1)
1624 return "\<LeftMouse>"
1625 endfunc
1626 func DragExpr()
1627 call test_setmouse(1, 2)
1628 return "\<LeftDrag>"
1629 endfunc
1630 nnoremap <expr> <F2> ClickExpr()
1631 nmap <expr> <F3> DragExpr()
1632
1633 nnoremap <LeftDrag> <LeftDrag><Cmd><CR>
1634 exe "normal \<F2>\<F3>"
1635 call assert_equal('s', mode())
1636 exe "normal! \<C-\>\<C-N>"
1637
1638 nunmap <LeftDrag>
1639 nunmap <F2>
1640 nunmap <F3>
1641 delfunc ClickExpr
1642 delfunc DragExpr
1643 set selectmode&
1644 set mouse&
1645endfunc
1646
zeertzjq0f68e6c2022-04-05 13:17:01 +01001647" Test for mapping <LeftDrag> in Insert mode
1648func Test_mouse_drag_insert_map()
1649 set mouse=a
1650 func ClickExpr()
1651 call test_setmouse(1, 1)
1652 return "\<LeftMouse>"
1653 endfunc
1654 func DragExpr()
1655 call test_setmouse(1, 2)
1656 return "\<LeftDrag>"
1657 endfunc
1658 inoremap <expr> <F2> ClickExpr()
1659 imap <expr> <F3> DragExpr()
1660
1661 inoremap <LeftDrag> <LeftDrag><Cmd>let g:dragged = 1<CR>
1662 exe "normal i\<F2>\<F3>"
1663 call assert_equal(1, g:dragged)
1664 call assert_equal('v', mode())
1665 exe "normal! \<C-\>\<C-N>"
1666 unlet g:dragged
1667
1668 inoremap <LeftDrag> <LeftDrag><C-\><C-N>
1669 exe "normal i\<F2>\<F3>"
1670 call assert_equal('n', mode())
1671
1672 iunmap <LeftDrag>
1673 iunmap <F2>
1674 iunmap <F3>
1675 delfunc ClickExpr
1676 delfunc DragExpr
1677 set mouse&
1678endfunc
1679
zeertzjqabeb09b2022-04-26 12:29:43 +01001680func Test_unmap_simplifiable()
zeertzjqa4e33322022-04-24 17:07:53 +01001681 map <C-I> foo
1682 map <Tab> bar
1683 call assert_equal('foo', maparg('<C-I>'))
1684 call assert_equal('bar', maparg('<Tab>'))
1685 unmap <C-I>
1686 call assert_equal('', maparg('<C-I>'))
1687 call assert_equal('bar', maparg('<Tab>'))
1688 unmap <Tab>
zeertzjqabeb09b2022-04-26 12:29:43 +01001689
1690 map <C-I> foo
1691 unmap <Tab>
1692 " This should not error
1693 unmap <C-I>
zeertzjqa4e33322022-04-24 17:07:53 +01001694endfunc
1695
zeertzjqdb088872022-05-02 22:53:45 +01001696func Test_expr_map_escape_special()
1697 nnoremap … <Cmd>let g:got_ellipsis += 1<CR>
1698 func Func()
1699 return '…'
1700 endfunc
1701 nmap <expr> <F2> Func()
1702 let g:got_ellipsis = 0
1703 call feedkeys("\<F2>", 'xt')
1704 call assert_equal(1, g:got_ellipsis)
1705 delfunc Func
1706 nunmap <F2>
1707 unlet g:got_ellipsis
1708 nunmap …
1709endfunc
1710
zeertzjq3760bfd2022-06-06 16:22:46 +01001711" Testing for mapping after an <Nop> mapping is triggered on timeout.
1712" Test for what patch 8.1.0052 fixes.
1713func Test_map_after_timed_out_nop()
1714 CheckRunVimInTerminal
1715
1716 let lines =<< trim END
1717 set timeout timeoutlen=400
1718 inoremap ab TEST
1719 inoremap a <Nop>
1720 END
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001721 call writefile(lines, 'Xtest_map_after_timed_out_nop', 'D')
zeertzjq3760bfd2022-06-06 16:22:46 +01001722 let buf = RunVimInTerminal('-S Xtest_map_after_timed_out_nop', #{rows: 6})
1723
1724 " Enter Insert mode
1725 call term_sendkeys(buf, 'i')
1726 " Wait for the "a" mapping to timeout
1727 call term_sendkeys(buf, 'a')
1728 call term_wait(buf, 500)
1729 " Send "a" and wait for a period shorter than 'timeoutlen'
1730 call term_sendkeys(buf, 'a')
1731 call term_wait(buf, 100)
1732 " Send "b", should trigger the "ab" mapping
1733 call term_sendkeys(buf, 'b')
1734 call WaitForAssert({-> assert_equal("TEST", term_getline(buf, 1))})
1735
1736 " clean up
1737 call StopVimInTerminal(buf)
zeertzjq3760bfd2022-06-06 16:22:46 +01001738endfunc
1739
Bram Moolenaar27efc622022-07-01 16:35:45 +01001740func Test_using_past_typeahead()
1741 nnoremap :00 0
1742 exe "norm :set \x80\xfb0=0\<CR>"
1743 exe "sil norm :0\x0f\<C-U>\<CR>"
1744
1745 exe "norm :set \x80\xfb0=\<CR>"
1746 nunmap :00
1747endfunc
1748
1749
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +01001750" vim: shiftwidth=2 sts=2 expandtab