blob: 328e1cae3ef18922c45f9b2b40f53d7fe6b8f40d [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 Moolenaar26d98212019-01-27 22:32:55 +01006
Bram Moolenaar2d1a2482016-08-14 15:32:11 +02007func Test_abbreviation()
8 " abbreviation with 0x80 should work
9 inoreab чкпр vim
10 call feedkeys("Goчкпр \<Esc>", "xt")
11 call assert_equal('vim ', getline('$'))
12 iunab чкпр
13 set nomodified
14endfunc
15
Bram Moolenaar8485be42019-04-23 16:36:05 +020016func Test_abclear()
17 abbrev foo foobar
18 iabbrev fooi foobari
19 cabbrev fooc foobarc
20 call assert_equal("\n\n"
21 \ .. "c fooc foobarc\n"
22 \ .. "i fooi foobari\n"
23 \ .. "! foo foobar", execute('abbrev'))
24
25 iabclear
26 call assert_equal("\n\n"
27 \ .. "c fooc foobarc\n"
28 \ .. "c foo foobar", execute('abbrev'))
29 abbrev foo foobar
30 iabbrev fooi foobari
31
32 cabclear
33 call assert_equal("\n\n"
34 \ .. "i fooi foobari\n"
35 \ .. "i foo foobar", execute('abbrev'))
36 abbrev foo foobar
37 cabbrev fooc foobarc
38
39 abclear
40 call assert_equal("\n\nNo abbreviation found", execute('abbrev'))
Bram Moolenaarf0cee192020-02-16 13:33:56 +010041 call assert_fails('%abclear', 'E481:')
Bram Moolenaar8485be42019-04-23 16:36:05 +020042endfunc
43
44func Test_abclear_buffer()
45 abbrev foo foobar
46 new X1
47 abbrev <buffer> foo1 foobar1
48 new X2
49 abbrev <buffer> foo2 foobar2
50
51 call assert_equal("\n\n"
52 \ .. "! foo2 @foobar2\n"
53 \ .. "! foo foobar", execute('abbrev'))
54
55 abclear <buffer>
56 call assert_equal("\n\n"
57 \ .. "! foo foobar", execute('abbrev'))
58
59 b X1
60 call assert_equal("\n\n"
61 \ .. "! foo1 @foobar1\n"
62 \ .. "! foo foobar", execute('abbrev'))
63 abclear <buffer>
64 call assert_equal("\n\n"
65 \ .. "! foo foobar", execute('abbrev'))
66
67 abclear
68 call assert_equal("\n\nNo abbreviation found", execute('abbrev'))
69
70 %bwipe
71endfunc
72
Bram Moolenaar2d1a2482016-08-14 15:32:11 +020073func Test_map_ctrl_c_insert()
74 " mapping of ctrl-c in Insert mode
75 set cpo-=< cpo-=k
76 inoremap <c-c> <ctrl-c>
77 cnoremap <c-c> dummy
78 cunmap <c-c>
Bram Moolenaarfccd93f2020-05-31 22:06:51 +020079 call feedkeys("GoTEST2: CTRL-C |\<*C-C>A|\<Esc>", "xt")
Bram Moolenaar2d1a2482016-08-14 15:32:11 +020080 call assert_equal('TEST2: CTRL-C |<ctrl-c>A|', getline('$'))
81 unmap! <c-c>
82 set nomodified
83endfunc
84
85func Test_map_ctrl_c_visual()
86 " mapping of ctrl-c in Visual mode
87 vnoremap <c-c> :<C-u>$put ='vmap works'
Bram Moolenaarfccd93f2020-05-31 22:06:51 +020088 call feedkeys("GV\<*C-C>\<CR>", "xt")
Bram Moolenaar2d1a2482016-08-14 15:32:11 +020089 call assert_equal('vmap works', getline('$'))
90 vunmap <c-c>
91 set nomodified
92endfunc
93
94func Test_map_langmap()
Bram Moolenaar920694c2016-08-21 17:45:02 +020095 if !has('langmap')
96 return
97 endif
98
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 Moolenaar26d98212019-01-27 22:32:55 +0100262 if !has('timers')
263 return
264 endif
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200265 nnoremap aaaa :let got_aaaa = 1<CR>
266 nnoremap bb :let got_bb = 1<CR>
267 nmap b aaa
268 new
269 func ExitInsert(timer)
270 let g:line = getline(1)
271 call feedkeys("\<Esc>", "t")
272 endfunc
273 set timeout timeoutlen=200
Bram Moolenaar26d98212019-01-27 22:32:55 +0100274 let timer = timer_start(300, 'ExitInsert')
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200275 " After the 'b' Vim waits for another character to see if it matches 'bb'.
276 " When it times out it is expanded to "aaa", but there is no wait for
277 " "aaaa". Can't check that reliably though.
278 call feedkeys("b", "xt!")
279 call assert_equal("aa", g:line)
280 call assert_false(exists('got_aaa'))
281 call assert_false(exists('got_bb'))
282
283 bwipe!
284 nunmap aaaa
285 nunmap bb
286 nunmap b
287 set timeoutlen&
288 delfunc ExitInsert
Bram Moolenaar26d98212019-01-27 22:32:55 +0100289 call timer_stop(timer)
290endfunc
291
292func Test_map_timeout_with_timer_interrupt()
293 if !has('job') || !has('timers')
294 return
295 endif
296
297 " Confirm the timer invoked in exit_cb of the job doesn't disturb mapped key
298 " sequence.
299 new
300 let g:val = 0
301 nnoremap \12 :let g:val = 1<CR>
302 nnoremap \123 :let g:val = 2<CR>
Bram Moolenaarea94c852019-08-16 21:47:27 +0200303 set timeout timeoutlen=200
Bram Moolenaar26d98212019-01-27 22:32:55 +0100304
305 func ExitCb(job, status)
Bram Moolenaar8d4ce562019-01-30 22:01:40 +0100306 let g:timer = timer_start(1, {-> feedkeys("3\<Esc>", 't')})
Bram Moolenaar26d98212019-01-27 22:32:55 +0100307 endfunc
308
309 call job_start([&shell, &shellcmdflag, 'echo'], {'exit_cb': 'ExitCb'})
310 call feedkeys('\12', 'xt!')
311 call assert_equal(2, g:val)
312
313 bwipe!
314 nunmap \12
315 nunmap \123
316 set timeoutlen&
317 call WaitFor({-> exists('g:timer')})
318 call timer_stop(g:timer)
319 unlet g:timer
320 unlet g:val
321 delfunc ExitCb
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200322endfunc
Bram Moolenaarc3c3e692018-04-26 22:30:33 +0200323
324func Test_abbreviation_CR()
325 new
326 func Eatchar(pat)
327 let c = nr2char(getchar(0))
328 return (c =~ a:pat) ? '' : c
329 endfunc
330 iabbrev <buffer><silent> ~~7 <c-r>=repeat('~', 7)<CR><c-r>=Eatchar('\s')<cr>
331 call feedkeys("GA~~7 \<esc>", 'xt')
332 call assert_equal('~~~~~~~', getline('$'))
333 %d
334 call feedkeys("GA~~7\<cr>\<esc>", 'xt')
335 call assert_equal(['~~~~~~~', ''], getline(1,'$'))
336 delfunc Eatchar
337 bw!
338endfunc
Bram Moolenaar5e3423d2018-05-13 18:36:27 +0200339
340func Test_cabbr_visual_mode()
341 cabbr s su
342 call feedkeys(":s \<c-B>\"\<CR>", 'itx')
343 call assert_equal('"su ', getreg(':'))
344 call feedkeys(":'<,'>s \<c-B>\"\<CR>", 'itx')
345 let expected = '"'. "'<,'>su "
346 call assert_equal(expected, getreg(':'))
347 call feedkeys(": '<,'>s \<c-B>\"\<CR>", 'itx')
348 let expected = '" '. "'<,'>su "
349 call assert_equal(expected, getreg(':'))
350 call feedkeys(":'a,'bs \<c-B>\"\<CR>", 'itx')
351 let expected = '"'. "'a,'bsu "
352 call assert_equal(expected, getreg(':'))
353 cunabbr s
354endfunc
Bram Moolenaar5976f8f2018-12-27 23:44:44 +0100355
356func Test_motionforce_omap()
357 func GetCommand()
358 let g:m=mode(1)
359 let [g:lnum1, g:col1] = searchpos('-', 'Wb')
360 if g:lnum1 == 0
361 return "\<Esc>"
362 endif
363 let [g:lnum2, g:col2] = searchpos('-', 'W')
364 if g:lnum2 == 0
365 return "\<Esc>"
366 endif
367 return ":call Select()\<CR>"
368 endfunc
369 func Select()
370 call cursor([g:lnum1, g:col1])
371 exe "normal! 1 ". (strlen(g:m) == 2 ? 'v' : g:m[2])
372 call cursor([g:lnum2, g:col2])
373 execute "normal! \<BS>"
374 endfunc
375 new
376 onoremap <buffer><expr> i- GetCommand()
377 " 1) default omap mapping
378 %d_
379 call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
380 call cursor(2, 1)
381 norm di-
382 call assert_equal('no', g:m)
383 call assert_equal(['aaa -- eee'], getline(1, '$'))
384 " 2) forced characterwise operation
385 %d_
386 call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
387 call cursor(2, 1)
388 norm dvi-
389 call assert_equal('nov', g:m)
390 call assert_equal(['aaa -- eee'], getline(1, '$'))
391 " 3) forced linewise operation
392 %d_
393 call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
394 call cursor(2, 1)
395 norm dVi-
396 call assert_equal('noV', g:m)
397 call assert_equal([''], getline(1, '$'))
398 " 4) forced blockwise operation
399 %d_
400 call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
401 call cursor(2, 1)
402 exe "norm d\<C-V>i-"
403 call assert_equal("no\<C-V>", g:m)
404 call assert_equal(['aaabbb', 'x', 'dddeee'], getline(1, '$'))
405 bwipe!
406 delfunc Select
407 delfunc GetCommand
408endfunc
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200409
410func Test_error_in_map_expr()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200411 " Unlike CheckRunVimInTerminal this does work in a win32 console
412 CheckFeature terminal
413 if has('win32') && has('gui_running')
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200414 throw 'Skipped: cannot run Vim in a terminal window'
415 endif
416
417 let lines =<< trim [CODE]
418 func Func()
419 " fail to create list
420 let x = [
421 endfunc
422 nmap <expr> ! Func()
423 set updatetime=50
424 [CODE]
425 call writefile(lines, 'Xtest.vim')
426
Bram Moolenaar0d702022019-07-04 14:20:41 +0200427 let buf = term_start(GetVimCommandCleanTerm() .. ' -S Xtest.vim', {'term_rows': 8})
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200428 let job = term_getjob(buf)
429 call WaitForAssert({-> assert_notequal('', term_getline(buf, 8))})
430
431 " GC must not run during map-expr processing, which can make Vim crash.
432 call term_sendkeys(buf, '!')
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200433 call TermWait(buf, 50)
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200434 call term_sendkeys(buf, "\<CR>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200435 call TermWait(buf, 50)
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200436 call assert_equal('run', job_status(job))
437
438 call term_sendkeys(buf, ":qall!\<CR>")
439 call WaitFor({-> job_status(job) ==# 'dead'})
440 if has('unix')
441 call assert_equal('', job_info(job).termsig)
442 endif
443
444 call delete('Xtest.vim')
445 exe buf .. 'bwipe!'
446endfunc
Bram Moolenaarfafb4b12019-10-16 18:34:57 +0200447
448func Test_list_mappings()
Bram Moolenaar2559a472019-10-16 23:33:12 +0200449 " Remove default mappings
450 imapclear
Bram Moolenaar4f2f61a2019-10-16 22:27:49 +0200451
Bram Moolenaarfafb4b12019-10-16 18:34:57 +0200452 inoremap <C-M> CtrlM
453 inoremap <A-S> AltS
454 inoremap <S-/> ShiftSlash
455 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
484 " map to CTRL-V
485 exe "nmap ,k \<C-V>"
486 call assert_equal(['n ,k <Nop>'],
487 \ execute('nmap ,k')->trim()->split("\n"))
488
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100489 nmapclear
Bram Moolenaarfafb4b12019-10-16 18:34:57 +0200490endfunc
Bram Moolenaar4ebe0e62019-11-22 20:55:40 +0100491
492func Test_expr_map_restore_cursor()
493 CheckScreendump
494
495 let lines =<< trim END
496 call setline(1, ['one', 'two', 'three'])
497 2
498 set ls=2
499 hi! link StatusLine ErrorMsg
500 noremap <expr> <C-B> Func()
501 func Func()
502 let g:on = !get(g:, 'on', 0)
503 redraws
504 return ''
505 endfunc
506 func Status()
507 return get(g:, 'on', 0) ? '[on]' : ''
508 endfunc
509 set stl=%{Status()}
510 END
511 call writefile(lines, 'XtestExprMap')
512 let buf = RunVimInTerminal('-S XtestExprMap', #{rows: 10})
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200513 call TermWait(buf)
Bram Moolenaar4ebe0e62019-11-22 20:55:40 +0100514 call term_sendkeys(buf, "\<C-B>")
515 call VerifyScreenDump(buf, 'Test_map_expr_1', {})
516
517 " clean up
518 call StopVimInTerminal(buf)
519 call delete('XtestExprMap')
520endfunc
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100521
522" Test for mapping errors
523func Test_map_error()
524 call assert_fails('unmap', 'E474:')
525 call assert_fails("exe 'map ' .. repeat('a', 51) .. ' :ls'", 'E474:')
526 call assert_fails('unmap abc', 'E31:')
527 call assert_fails('unabbr abc', 'E24:')
528 call assert_equal('', maparg(''))
529 call assert_fails('echo maparg("abc", [])', 'E730:')
530
531 " unique map
532 map ,w /[#&!]<CR>
533 call assert_fails("map <unique> ,w /[#&!]<CR>", 'E227:')
534 " unique buffer-local map
535 call assert_fails("map <buffer> <unique> ,w /[.,;]<CR>", 'E225:')
536 unmap ,w
537
538 " unique abbreviation
539 abbr SP special
540 call assert_fails("abbr <unique> SP special", 'E226:')
541 " unique buffer-local map
542 call assert_fails("abbr <buffer> <unique> SP special", 'E224:')
543 unabbr SP
544
545 call assert_fails('mapclear abc', 'E474:')
546 call assert_fails('abclear abc', 'E474:')
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100547 call assert_fails('abbr $xyz abc', 'E474:')
548
549 " space character in an abbreviation
550 call assert_fails('abbr ab<space> ABC', 'E474:')
551
552 " invalid <expr> map
553 map <expr> ,f abc
554 call assert_fails('normal ,f', 'E121:')
555 unmap <expr> ,f
Bram Moolenaar9f6277b2020-02-11 22:04:02 +0100556
557 " Recursive use of :normal in a map
558 set maxmapdepth=100
559 map gq :normal gq<CR>
560 call assert_fails('normal gq', 'E192:')
561 unmap gq
562 set maxmapdepth&
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100563endfunc
564
565" Test for <special> key mapping
566func Test_map_special()
567 new
568 let old_cpo = &cpo
569 set cpo+=<
570 imap <F12> Blue
571 call feedkeys("i\<F12>", "x")
572 call assert_equal("<F12>", getline(1))
573 call feedkeys("ddi<F12>", "x")
574 call assert_equal("Blue", getline(1))
575 iunmap <F12>
576 imap <special> <F12> Green
577 call feedkeys("ddi\<F12>", "x")
578 call assert_equal("Green", getline(1))
579 call feedkeys("ddi<F12>", "x")
580 call assert_equal("<F12>", getline(1))
581 iunmap <special> <F12>
582 let &cpo = old_cpo
583 %bwipe!
584endfunc
585
586" Test for hasmapto()
587func Test_hasmapto()
588 call assert_equal(0, hasmapto('/^\k\+ ('))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100589 map ,f /^\k\+ (<CR>
590 call assert_equal(1, hasmapto('/^\k\+ ('))
591 unmap ,f
592
593 " Insert mode mapping
594 call assert_equal(0, hasmapto('/^\k\+ (', 'i'))
595 imap ,f /^\k\+ (<CR>
596 call assert_equal(1, hasmapto('/^\k\+ (', 'i'))
597 iunmap ,f
598
599 " Normal mode mapping
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100600 call assert_equal(0, hasmapto('/^\k\+ (', 'n'))
601 nmap ,f /^\k\+ (<CR>
602 call assert_equal(1, hasmapto('/^\k\+ ('))
603 call assert_equal(1, hasmapto('/^\k\+ (', 'n'))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100604 nunmap ,f
605
606 " Visual and Select mode mapping
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100607 call assert_equal(0, hasmapto('/^\k\+ (', 'v'))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100608 call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
609 call assert_equal(0, hasmapto('/^\k\+ (', 's'))
610 vmap ,f /^\k\+ (<CR>
611 call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
612 call assert_equal(1, hasmapto('/^\k\+ (', 'x'))
613 call assert_equal(1, hasmapto('/^\k\+ (', 's'))
614 vunmap ,f
615
616 " Visual mode mapping
617 call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
618 xmap ,f /^\k\+ (<CR>
619 call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
620 call assert_equal(1, hasmapto('/^\k\+ (', 'x'))
621 call assert_equal(0, hasmapto('/^\k\+ (', 's'))
622 xunmap ,f
623
624 " Select mode mapping
625 call assert_equal(0, hasmapto('/^\k\+ (', 's'))
626 smap ,f /^\k\+ (<CR>
627 call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
628 call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
629 call assert_equal(1, hasmapto('/^\k\+ (', 's'))
630 sunmap ,f
631
632 " Operator-pending mode mapping
633 call assert_equal(0, hasmapto('/^\k\+ (', 'o'))
634 omap ,f /^\k\+ (<CR>
635 call assert_equal(1, hasmapto('/^\k\+ (', 'o'))
636 ounmap ,f
637
638 " Language mapping
639 call assert_equal(0, hasmapto('/^\k\+ (', 'l'))
640 lmap ,f /^\k\+ (<CR>
641 call assert_equal(1, hasmapto('/^\k\+ (', 'l'))
642 lunmap ,f
643
644 " Cmdline mode mapping
645 call assert_equal(0, hasmapto('/^\k\+ (', 'c'))
646 cmap ,f /^\k\+ (<CR>
647 call assert_equal(1, hasmapto('/^\k\+ (', 'c'))
648 cunmap ,f
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100649
650 call assert_equal(0, hasmapto('/^\k\+ (', 'n', 1))
651endfunc
652
653" Test for command-line completion of maps
654func Test_mapcomplete()
655 call assert_equal(['<buffer>', '<expr>', '<nowait>', '<script>',
656 \ '<silent>', '<special>', '<unique>'],
657 \ getcompletion('', 'mapping'))
658 call assert_equal([], getcompletion(',d', 'mapping'))
659
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100660 call feedkeys(":unmap <buf\<C-A>\<C-B>\"\<CR>", 'tx')
661 call assert_equal('"unmap <buffer>', @:)
662
663 call feedkeys(":unabbr <buf\<C-A>\<C-B>\"\<CR>", 'tx')
664 call assert_equal('"unabbr <buffer>', @:)
665
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100666 call feedkeys(":abbr! \<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100667 call assert_equal("\"abbr! \x01", @:)
668
669 " Multiple matches for a map
670 nmap ,f /H<CR>
671 omap ,f /H<CR>
672 call feedkeys(":map ,\<C-A>\<C-B>\"\<CR>", 'tx')
673 call assert_equal('"map ,f', @:)
674 mapclear
675endfunc
676
677" Test for <expr> in abbreviation
678func Test_expr_abbr()
679 new
680 iabbr <expr> teh "the"
681 call feedkeys("iteh ", "tx")
682 call assert_equal('the ', getline(1))
683 iabclear
684 call setline(1, '')
685
686 " invalid <expr> abbreviation
687 abbr <expr> hte GetAbbr()
688 call assert_fails('normal ihte ', 'E117:')
689 call assert_equal(' ', getline(1))
690 unabbr <expr> hte
691
692 close!
693endfunc
694
695" Test for storing mappings in different modes in a vimrc file
696func Test_mkvimrc_mapmodes()
697 map a1 /a1
698 nmap a2 /a2
699 vmap a3 /a3
700 smap a4 /a4
701 xmap a5 /a5
702 omap a6 /a6
703 map! a7 /a7
704 imap a8 /a8
705 lmap a9 /a9
706 cmap a10 /a10
707 tmap a11 /a11
708 " Normal + Visual map
709 map a12 /a12
710 sunmap a12
711 ounmap a12
712 " Normal + Selectmode map
713 map a13 /a13
714 xunmap a13
715 ounmap a13
716 " Normal + OpPending map
717 map a14 /a14
718 vunmap a14
719 " Visual + Selectmode map
720 map a15 /a15
721 nunmap a15
722 ounmap a15
723 " Visual + OpPending map
724 map a16 /a16
725 nunmap a16
726 sunmap a16
727 " Selectmode + OpPending map
728 map a17 /a17
729 nunmap a17
730 xunmap a17
731 " Normal + Visual + Selectmode map
732 map a18 /a18
733 ounmap a18
734 " Normal + Visual + OpPending map
735 map a19 /a19
736 sunmap a19
737 " Normal + Selectmode + OpPending map
738 map a20 /a20
739 xunmap a20
740 " Visual + Selectmode + OpPending map
741 map a21 /a21
742 nunmap a21
743 " Mapping to Nop
744 map a22 <Nop>
745 " Script local mapping
746 map <script> a23 /a23
747
748 " Newline in {lhs} and {rhs} of a map
749 exe "map a24\<C-V>\<C-J> ia24\<C-V>\<C-J><Esc>"
750
751 " Abbreviation
752 abbr a25 A25
753 cabbr a26 A26
754 iabbr a27 A27
755
756 mkvimrc! Xvimrc
757 let l = readfile('Xvimrc')
758 call assert_equal(['map a1 /a1'], filter(copy(l), 'v:val =~ " a1 "'))
759 call assert_equal(['nmap a2 /a2'], filter(copy(l), 'v:val =~ " a2 "'))
760 call assert_equal(['vmap a3 /a3'], filter(copy(l), 'v:val =~ " a3 "'))
761 call assert_equal(['smap a4 /a4'], filter(copy(l), 'v:val =~ " a4 "'))
762 call assert_equal(['xmap a5 /a5'], filter(copy(l), 'v:val =~ " a5 "'))
763 call assert_equal(['omap a6 /a6'], filter(copy(l), 'v:val =~ " a6 "'))
764 call assert_equal(['map! a7 /a7'], filter(copy(l), 'v:val =~ " a7 "'))
765 call assert_equal(['imap a8 /a8'], filter(copy(l), 'v:val =~ " a8 "'))
766 call assert_equal(['lmap a9 /a9'], filter(copy(l), 'v:val =~ " a9 "'))
767 call assert_equal(['cmap a10 /a10'], filter(copy(l), 'v:val =~ " a10 "'))
768 call assert_equal(['tmap a11 /a11'], filter(copy(l), 'v:val =~ " a11 "'))
769 call assert_equal(['nmap a12 /a12', 'xmap a12 /a12'],
770 \ filter(copy(l), 'v:val =~ " a12 "'))
771 call assert_equal(['nmap a13 /a13', 'smap a13 /a13'],
772 \ filter(copy(l), 'v:val =~ " a13 "'))
773 call assert_equal(['nmap a14 /a14', 'omap a14 /a14'],
774 \ filter(copy(l), 'v:val =~ " a14 "'))
775 call assert_equal(['vmap a15 /a15'], filter(copy(l), 'v:val =~ " a15 "'))
776 call assert_equal(['xmap a16 /a16', 'omap a16 /a16'],
777 \ filter(copy(l), 'v:val =~ " a16 "'))
778 call assert_equal(['smap a17 /a17', 'omap a17 /a17'],
779 \ filter(copy(l), 'v:val =~ " a17 "'))
780 call assert_equal(['nmap a18 /a18', 'vmap a18 /a18'],
781 \ filter(copy(l), 'v:val =~ " a18 "'))
782 call assert_equal(['nmap a19 /a19', 'xmap a19 /a19', 'omap a19 /a19'],
783 \ filter(copy(l), 'v:val =~ " a19 "'))
784 call assert_equal(['nmap a20 /a20', 'smap a20 /a20', 'omap a20 /a20'],
785 \ filter(copy(l), 'v:val =~ " a20 "'))
786 call assert_equal(['vmap a21 /a21', 'omap a21 /a21'],
787 \ filter(copy(l), 'v:val =~ " a21 "'))
788 call assert_equal(['map a22 <Nop>'], filter(copy(l), 'v:val =~ " a22 "'))
789 call assert_equal([], filter(copy(l), 'v:val =~ " a23 "'))
790 call assert_equal(["map a24<NL> ia24<NL>\x16\e"],
791 \ filter(copy(l), 'v:val =~ " a24"'))
792
793 call assert_equal(['abbr a25 A25'], filter(copy(l), 'v:val =~ " a25 "'))
794 call assert_equal(['cabbr a26 A26'], filter(copy(l), 'v:val =~ " a26 "'))
795 call assert_equal(['iabbr a27 A27'], filter(copy(l), 'v:val =~ " a27 "'))
796 call delete('Xvimrc')
797
798 mapclear
799 nmapclear
800 vmapclear
801 xmapclear
802 smapclear
803 omapclear
804 imapclear
805 lmapclear
806 cmapclear
807 tmapclear
808endfunc
809
810" Test for recursive mapping ('maxmapdepth')
811func Test_map_recursive()
812 map x y
813 map y x
814 call assert_fails('normal x', 'E223:')
815 unmap x
816 unmap y
817endfunc
818
819" Test for removing an abbreviation using {rhs} and with space after {lhs}
820func Test_abbr_remove()
821 abbr foo bar
822 let d = maparg('foo', 'i', 1, 1)
823 call assert_equal(['foo', 'bar', '!'], [d.lhs, d.rhs, d.mode])
824 unabbr bar
825 call assert_equal({}, maparg('foo', 'i', 1, 1))
826
827 abbr foo bar
828 unabbr foo<space><tab>
829 call assert_equal({}, maparg('foo', 'i', 1, 1))
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100830endfunc
831
Bram Moolenaar7f51bbe2020-01-24 20:21:19 +0100832" Trigger an abbreviation using a special key
833func Test_abbr_trigger_special()
834 new
835 iabbr teh the
836 call feedkeys("iteh\<F2>\<Esc>", 'xt')
837 call assert_equal('the<F2>', getline(1))
838 iunab teh
839 close!
840endfunc
841
842" Test for '<' in 'cpoptions'
843func Test_map_cpo_special_keycode()
844 set cpo-=<
845 imap x<Bslash>k Test
846 let d = maparg('x<Bslash>k', 'i', 0, 1)
847 call assert_equal(['x\k', 'Test', 'i'], [d.lhs, d.rhs, d.mode])
848 call feedkeys(":imap x\<C-A>\<C-B>\"\<CR>", 'tx')
849 call assert_equal('"imap x\k', @:)
850 iunmap x<Bslash>k
851 set cpo+=<
852 imap x<Bslash>k Test
853 let d = maparg('x<Bslash>k', 'i', 0, 1)
854 call assert_equal(['x<Bslash>k', 'Test', 'i'], [d.lhs, d.rhs, d.mode])
855 call feedkeys(":imap x\<C-A>\<C-B>\"\<CR>", 'tx')
856 call assert_equal('"imap x<Bslash>k', @:)
857 iunmap x<Bslash>k
858 set cpo-=<
859 " Modifying 'cpo' above adds some default mappings, remove them
860 mapclear
861 mapclear!
862endfunc
863
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100864" vim: shiftwidth=2 sts=2 expandtab