blob: 67a908a5afec540fde9e6fa2745f67667f22c74f [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 Moolenaar6d91bcb2020-08-12 18:50:36 +020095 CheckFeature langmap
Bram Moolenaar920694c2016-08-21 17:45:02 +020096
97 " check langmap applies in normal mode
98 set langmap=+- nolangremap
99 new
100 call setline(1, ['a', 'b', 'c'])
101 2
102 call assert_equal('b', getline('.'))
103 call feedkeys("+", "xt")
104 call assert_equal('a', getline('.'))
105
106 " check no remapping
107 map x +
108 2
109 call feedkeys("x", "xt")
110 call assert_equal('c', getline('.'))
111
112 " check with remapping
113 set langremap
114 2
115 call feedkeys("x", "xt")
116 call assert_equal('a', getline('.'))
117
118 unmap x
119 bwipe!
120
121 " 'langnoremap' follows 'langremap' and vise versa
122 set langremap
123 set langnoremap
124 call assert_equal(0, &langremap)
125 set langremap
126 call assert_equal(0, &langnoremap)
127 set nolangremap
128 call assert_equal(1, &langnoremap)
129
Bram Moolenaarda9ce2c2016-09-02 19:34:10 +0200130 " check default values
131 set langnoremap&
132 call assert_equal(0, &langnoremap)
133 call assert_equal(1, &langremap)
134 set langremap&
135 call assert_equal(0, &langnoremap)
136 call assert_equal(1, &langremap)
137
Bram Moolenaar920694c2016-08-21 17:45:02 +0200138 " langmap should not apply in insert mode, 'langremap' doesn't matter
139 set langmap=+{ nolangremap
140 call feedkeys("Go+\<Esc>", "xt")
141 call assert_equal('+', getline('$'))
142 set langmap=+{ langremap
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200143 call feedkeys("Go+\<Esc>", "xt")
144 call assert_equal('+', getline('$'))
145
Bram Moolenaar920694c2016-08-21 17:45:02 +0200146 " langmap used for register name in insert mode.
147 call setreg('a', 'aaaa')
148 call setreg('b', 'bbbb')
149 call setreg('c', 'cccc')
150 set langmap=ab langremap
151 call feedkeys("Go\<C-R>a\<Esc>", "xt")
152 call assert_equal('bbbb', getline('$'))
153 call feedkeys("Go\<C-R>\<C-R>a\<Esc>", "xt")
154 call assert_equal('bbbb', getline('$'))
155 " mapping does not apply
156 imap c a
157 call feedkeys("Go\<C-R>c\<Esc>", "xt")
158 call assert_equal('cccc', getline('$'))
159 imap a c
160 call feedkeys("Go\<C-R>a\<Esc>", "xt")
161 call assert_equal('bbbb', getline('$'))
162
163 " langmap should not apply in Command-line mode
164 set langmap=+{ nolangremap
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200165 call feedkeys(":call append(line('$'), '+')\<CR>", "xt")
166 call assert_equal('+', getline('$'))
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200167
Bram Moolenaare90858d2017-02-01 17:24:34 +0100168 iunmap a
169 iunmap c
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200170 set nomodified
171endfunc
172
173func Test_map_feedkeys()
174 " issue #212 (feedkeys insert mapping at current position)
175 nnoremap . :call feedkeys(".", "in")<cr>
176 call setline('$', ['a b c d', 'a b c d'])
177 $-1
178 call feedkeys("0qqdw.ifoo\<Esc>qj0@q\<Esc>", "xt")
179 call assert_equal(['fooc d', 'fooc d'], getline(line('$') - 1, line('$')))
Bram Moolenaare90858d2017-02-01 17:24:34 +0100180 nunmap .
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200181 set nomodified
182endfunc
183
184func Test_map_cursor()
185 " <c-g>U<cursor> works only within a single line
186 imapclear
187 imap ( ()<c-g>U<left>
188 call feedkeys("G2o\<Esc>ki\<CR>Test1: text with a (here some more text\<Esc>k.", "xt")
189 call assert_equal('Test1: text with a (here some more text)', getline(line('$') - 2))
190 call assert_equal('Test1: text with a (here some more text)', getline(line('$') - 1))
191
192 " test undo
193 call feedkeys("G2o\<Esc>ki\<CR>Test2: text wit a (here some more text [und undo]\<C-G>u\<Esc>k.u", "xt")
194 call assert_equal('', getline(line('$') - 2))
195 call assert_equal('Test2: text wit a (here some more text [und undo])', getline(line('$') - 1))
196 set nomodified
197 imapclear
198endfunc
199
Bram Moolenaar75bf3d22019-03-26 22:46:05 +0100200func Test_map_cursor_ctrl_gU()
201 " <c-g>U<cursor> works only within a single line
202 nnoremap c<* *Ncgn<C-r>"<C-G>U<S-Left>
203 call setline(1, ['foo', 'foobar', '', 'foo'])
204 call cursor(1,2)
205 call feedkeys("c<*PREFIX\<esc>.", 'xt')
206 call assert_equal(['PREFIXfoo', 'foobar', '', 'PREFIXfoo'], getline(1,'$'))
207 " break undo manually
208 set ul=1000
209 exe ":norm! uu"
210 call assert_equal(['foo', 'foobar', '', 'foo'], getline(1,'$'))
211
212 " Test that it does not work if the cursor moves to the previous line
213 " 2 times <S-Left> move to the previous line
214 nnoremap c<* *Ncgn<C-r>"<C-G>U<S-Left><C-G>U<S-Left>
215 call setline(1, ['', ' foo', 'foobar', '', 'foo'])
216 call cursor(2,3)
217 call feedkeys("c<*PREFIX\<esc>.", 'xt')
218 call assert_equal(['PREFIXPREFIX', ' foo', 'foobar', '', 'foo'], getline(1,'$'))
219 nmapclear
220endfunc
221
222
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200223" This isn't actually testing a mapping, but similar use of CTRL-G U as above.
224func Test_break_undo()
Bram Moolenaar75bf3d22019-03-26 22:46:05 +0100225 set whichwrap=<,>,[,]
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200226 call feedkeys("G4o2k", "xt")
227 exe ":norm! iTest3: text with a (parenthesis here\<C-G>U\<Right>new line here\<esc>\<up>\<up>."
228 call assert_equal('new line here', getline(line('$') - 3))
229 call assert_equal('Test3: text with a (parenthesis here', getline(line('$') - 2))
230 call assert_equal('new line here', getline(line('$') - 1))
231 set nomodified
232endfunc
Bram Moolenaar35a4cfa2016-08-14 16:07:48 +0200233
234func Test_map_meta_quotes()
235 imap <M-"> foo
Bram Moolenaarfccd93f2020-05-31 22:06:51 +0200236 call feedkeys("Go-\<*M-\">-\<Esc>", "xt")
Bram Moolenaar35a4cfa2016-08-14 16:07:48 +0200237 call assert_equal("-foo-", getline('$'))
238 set nomodified
239 iunmap <M-">
240endfunc
Bram Moolenaar878c2632017-04-01 15:15:52 +0200241
Bram Moolenaarc8fd33d2019-08-16 20:33:05 +0200242func Test_map_meta_multibyte()
243 imap <M-á> foo
Bram Moolenaar2f710af2019-08-16 20:56:03 +0200244 call assert_match('i <M-á>\s*foo', execute('imap'))
Bram Moolenaarc8fd33d2019-08-16 20:33:05 +0200245 iunmap <M-á>
246endfunc
247
Bram Moolenaar878c2632017-04-01 15:15:52 +0200248func Test_abbr_after_line_join()
249 new
250 abbr foo bar
251 set backspace=indent,eol,start
252 exe "normal o\<BS>foo "
253 call assert_equal("bar ", getline(1))
254 bwipe!
255 unabbr foo
256 set backspace&
257endfunc
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200258
259func Test_map_timeout()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200260 CheckFeature timers
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200261 nnoremap aaaa :let got_aaaa = 1<CR>
262 nnoremap bb :let got_bb = 1<CR>
263 nmap b aaa
264 new
265 func ExitInsert(timer)
266 let g:line = getline(1)
267 call feedkeys("\<Esc>", "t")
268 endfunc
269 set timeout timeoutlen=200
Bram Moolenaar26d98212019-01-27 22:32:55 +0100270 let timer = timer_start(300, 'ExitInsert')
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200271 " After the 'b' Vim waits for another character to see if it matches 'bb'.
272 " When it times out it is expanded to "aaa", but there is no wait for
273 " "aaaa". Can't check that reliably though.
274 call feedkeys("b", "xt!")
275 call assert_equal("aa", g:line)
276 call assert_false(exists('got_aaa'))
277 call assert_false(exists('got_bb'))
278
279 bwipe!
280 nunmap aaaa
281 nunmap bb
282 nunmap b
283 set timeoutlen&
284 delfunc ExitInsert
Bram Moolenaar26d98212019-01-27 22:32:55 +0100285 call timer_stop(timer)
286endfunc
287
288func Test_map_timeout_with_timer_interrupt()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200289 CheckFeature job
290 CheckFeature timers
Bram Moolenaar26d98212019-01-27 22:32:55 +0100291
292 " Confirm the timer invoked in exit_cb of the job doesn't disturb mapped key
293 " sequence.
294 new
295 let g:val = 0
296 nnoremap \12 :let g:val = 1<CR>
297 nnoremap \123 :let g:val = 2<CR>
Bram Moolenaarea94c852019-08-16 21:47:27 +0200298 set timeout timeoutlen=200
Bram Moolenaar26d98212019-01-27 22:32:55 +0100299
300 func ExitCb(job, status)
Bram Moolenaar8d4ce562019-01-30 22:01:40 +0100301 let g:timer = timer_start(1, {-> feedkeys("3\<Esc>", 't')})
Bram Moolenaar26d98212019-01-27 22:32:55 +0100302 endfunc
303
304 call job_start([&shell, &shellcmdflag, 'echo'], {'exit_cb': 'ExitCb'})
305 call feedkeys('\12', 'xt!')
306 call assert_equal(2, g:val)
307
308 bwipe!
309 nunmap \12
310 nunmap \123
311 set timeoutlen&
312 call WaitFor({-> exists('g:timer')})
313 call timer_stop(g:timer)
314 unlet g:timer
315 unlet g:val
316 delfunc ExitCb
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200317endfunc
Bram Moolenaarc3c3e692018-04-26 22:30:33 +0200318
319func Test_abbreviation_CR()
320 new
321 func Eatchar(pat)
322 let c = nr2char(getchar(0))
323 return (c =~ a:pat) ? '' : c
324 endfunc
325 iabbrev <buffer><silent> ~~7 <c-r>=repeat('~', 7)<CR><c-r>=Eatchar('\s')<cr>
326 call feedkeys("GA~~7 \<esc>", 'xt')
327 call assert_equal('~~~~~~~', getline('$'))
328 %d
329 call feedkeys("GA~~7\<cr>\<esc>", 'xt')
330 call assert_equal(['~~~~~~~', ''], getline(1,'$'))
331 delfunc Eatchar
332 bw!
333endfunc
Bram Moolenaar5e3423d2018-05-13 18:36:27 +0200334
335func Test_cabbr_visual_mode()
336 cabbr s su
337 call feedkeys(":s \<c-B>\"\<CR>", 'itx')
338 call assert_equal('"su ', getreg(':'))
339 call feedkeys(":'<,'>s \<c-B>\"\<CR>", 'itx')
340 let expected = '"'. "'<,'>su "
341 call assert_equal(expected, getreg(':'))
342 call feedkeys(": '<,'>s \<c-B>\"\<CR>", 'itx')
343 let expected = '" '. "'<,'>su "
344 call assert_equal(expected, getreg(':'))
345 call feedkeys(":'a,'bs \<c-B>\"\<CR>", 'itx')
346 let expected = '"'. "'a,'bsu "
347 call assert_equal(expected, getreg(':'))
348 cunabbr s
349endfunc
Bram Moolenaar5976f8f2018-12-27 23:44:44 +0100350
351func Test_motionforce_omap()
352 func GetCommand()
353 let g:m=mode(1)
354 let [g:lnum1, g:col1] = searchpos('-', 'Wb')
355 if g:lnum1 == 0
356 return "\<Esc>"
357 endif
358 let [g:lnum2, g:col2] = searchpos('-', 'W')
359 if g:lnum2 == 0
360 return "\<Esc>"
361 endif
362 return ":call Select()\<CR>"
363 endfunc
364 func Select()
365 call cursor([g:lnum1, g:col1])
366 exe "normal! 1 ". (strlen(g:m) == 2 ? 'v' : g:m[2])
367 call cursor([g:lnum2, g:col2])
368 execute "normal! \<BS>"
369 endfunc
370 new
371 onoremap <buffer><expr> i- GetCommand()
372 " 1) default omap mapping
373 %d_
374 call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
375 call cursor(2, 1)
376 norm di-
377 call assert_equal('no', g:m)
378 call assert_equal(['aaa -- eee'], getline(1, '$'))
379 " 2) forced characterwise operation
380 %d_
381 call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
382 call cursor(2, 1)
383 norm dvi-
384 call assert_equal('nov', g:m)
385 call assert_equal(['aaa -- eee'], getline(1, '$'))
386 " 3) forced linewise operation
387 %d_
388 call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
389 call cursor(2, 1)
390 norm dVi-
391 call assert_equal('noV', g:m)
392 call assert_equal([''], getline(1, '$'))
393 " 4) forced blockwise operation
394 %d_
395 call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
396 call cursor(2, 1)
397 exe "norm d\<C-V>i-"
398 call assert_equal("no\<C-V>", g:m)
399 call assert_equal(['aaabbb', 'x', 'dddeee'], getline(1, '$'))
400 bwipe!
401 delfunc Select
402 delfunc GetCommand
403endfunc
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200404
405func Test_error_in_map_expr()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200406 " Unlike CheckRunVimInTerminal this does work in a win32 console
407 CheckFeature terminal
408 if has('win32') && has('gui_running')
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200409 throw 'Skipped: cannot run Vim in a terminal window'
410 endif
411
412 let lines =<< trim [CODE]
413 func Func()
414 " fail to create list
415 let x = [
416 endfunc
417 nmap <expr> ! Func()
418 set updatetime=50
419 [CODE]
420 call writefile(lines, 'Xtest.vim')
421
Bram Moolenaar0d702022019-07-04 14:20:41 +0200422 let buf = term_start(GetVimCommandCleanTerm() .. ' -S Xtest.vim', {'term_rows': 8})
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200423 let job = term_getjob(buf)
424 call WaitForAssert({-> assert_notequal('', term_getline(buf, 8))})
425
426 " GC must not run during map-expr processing, which can make Vim crash.
427 call term_sendkeys(buf, '!')
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200428 call TermWait(buf, 50)
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200429 call term_sendkeys(buf, "\<CR>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200430 call TermWait(buf, 50)
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200431 call assert_equal('run', job_status(job))
432
433 call term_sendkeys(buf, ":qall!\<CR>")
434 call WaitFor({-> job_status(job) ==# 'dead'})
435 if has('unix')
436 call assert_equal('', job_info(job).termsig)
437 endif
438
439 call delete('Xtest.vim')
440 exe buf .. 'bwipe!'
441endfunc
Bram Moolenaarfafb4b12019-10-16 18:34:57 +0200442
443func Test_list_mappings()
Bram Moolenaar2559a472019-10-16 23:33:12 +0200444 " Remove default mappings
445 imapclear
Bram Moolenaar4f2f61a2019-10-16 22:27:49 +0200446
Bram Moolenaarfafb4b12019-10-16 18:34:57 +0200447 inoremap <C-M> CtrlM
448 inoremap <A-S> AltS
449 inoremap <S-/> ShiftSlash
450 call assert_equal([
451 \ 'i <S-/> * ShiftSlash',
452 \ 'i <M-S> * AltS',
453 \ 'i <C-M> * CtrlM',
454 \], execute('imap')->trim()->split("\n"))
455 iunmap <C-M>
456 iunmap <A-S>
457 call assert_equal(['i <S-/> * ShiftSlash'], execute('imap')->trim()->split("\n"))
458 iunmap <S-/>
459 call assert_equal(['No mapping found'], execute('imap')->trim()->split("\n"))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100460
461 " List global, buffer local and script local mappings
462 nmap ,f /^\k\+ (<CR>
463 nmap <buffer> ,f /^\k\+ (<CR>
464 nmap <script> ,fs /^\k\+ (<CR>
465 call assert_equal(['n ,f @/^\k\+ (<CR>',
466 \ 'n ,fs & /^\k\+ (<CR>',
467 \ 'n ,f /^\k\+ (<CR>'],
468 \ execute('nmap ,f')->trim()->split("\n"))
469
470 " List <Nop> mapping
471 nmap ,n <Nop>
472 call assert_equal(['n ,n <Nop>'],
473 \ execute('nmap ,n')->trim()->split("\n"))
474
Bram Moolenaar7f51bbe2020-01-24 20:21:19 +0100475 " verbose map
476 call assert_match("\tLast set from .*/test_mapping.vim line \\d\\+$",
477 \ execute('verbose map ,n')->trim()->split("\n")[1])
478
479 " map to CTRL-V
480 exe "nmap ,k \<C-V>"
481 call assert_equal(['n ,k <Nop>'],
482 \ execute('nmap ,k')->trim()->split("\n"))
483
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100484 nmapclear
Bram Moolenaarfafb4b12019-10-16 18:34:57 +0200485endfunc
Bram Moolenaar4ebe0e62019-11-22 20:55:40 +0100486
487func Test_expr_map_restore_cursor()
488 CheckScreendump
489
490 let lines =<< trim END
491 call setline(1, ['one', 'two', 'three'])
492 2
493 set ls=2
494 hi! link StatusLine ErrorMsg
495 noremap <expr> <C-B> Func()
496 func Func()
497 let g:on = !get(g:, 'on', 0)
498 redraws
499 return ''
500 endfunc
501 func Status()
502 return get(g:, 'on', 0) ? '[on]' : ''
503 endfunc
504 set stl=%{Status()}
505 END
506 call writefile(lines, 'XtestExprMap')
507 let buf = RunVimInTerminal('-S XtestExprMap', #{rows: 10})
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200508 call TermWait(buf)
Bram Moolenaar4ebe0e62019-11-22 20:55:40 +0100509 call term_sendkeys(buf, "\<C-B>")
510 call VerifyScreenDump(buf, 'Test_map_expr_1', {})
511
512 " clean up
513 call StopVimInTerminal(buf)
514 call delete('XtestExprMap')
515endfunc
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100516
517" Test for mapping errors
518func Test_map_error()
519 call assert_fails('unmap', 'E474:')
520 call assert_fails("exe 'map ' .. repeat('a', 51) .. ' :ls'", 'E474:')
521 call assert_fails('unmap abc', 'E31:')
522 call assert_fails('unabbr abc', 'E24:')
523 call assert_equal('', maparg(''))
524 call assert_fails('echo maparg("abc", [])', 'E730:')
525
526 " unique map
527 map ,w /[#&!]<CR>
528 call assert_fails("map <unique> ,w /[#&!]<CR>", 'E227:')
529 " unique buffer-local map
530 call assert_fails("map <buffer> <unique> ,w /[.,;]<CR>", 'E225:')
531 unmap ,w
532
533 " unique abbreviation
534 abbr SP special
535 call assert_fails("abbr <unique> SP special", 'E226:')
536 " unique buffer-local map
537 call assert_fails("abbr <buffer> <unique> SP special", 'E224:')
538 unabbr SP
539
540 call assert_fails('mapclear abc', 'E474:')
541 call assert_fails('abclear abc', 'E474:')
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100542 call assert_fails('abbr $xyz abc', 'E474:')
543
544 " space character in an abbreviation
545 call assert_fails('abbr ab<space> ABC', 'E474:')
546
547 " invalid <expr> map
548 map <expr> ,f abc
549 call assert_fails('normal ,f', 'E121:')
550 unmap <expr> ,f
Bram Moolenaar9f6277b2020-02-11 22:04:02 +0100551
552 " Recursive use of :normal in a map
553 set maxmapdepth=100
554 map gq :normal gq<CR>
555 call assert_fails('normal gq', 'E192:')
556 unmap gq
557 set maxmapdepth&
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100558endfunc
559
560" Test for <special> key mapping
561func Test_map_special()
562 new
563 let old_cpo = &cpo
564 set cpo+=<
565 imap <F12> Blue
566 call feedkeys("i\<F12>", "x")
567 call assert_equal("<F12>", getline(1))
568 call feedkeys("ddi<F12>", "x")
569 call assert_equal("Blue", getline(1))
570 iunmap <F12>
571 imap <special> <F12> Green
572 call feedkeys("ddi\<F12>", "x")
573 call assert_equal("Green", getline(1))
574 call feedkeys("ddi<F12>", "x")
575 call assert_equal("<F12>", getline(1))
576 iunmap <special> <F12>
577 let &cpo = old_cpo
578 %bwipe!
579endfunc
580
581" Test for hasmapto()
582func Test_hasmapto()
583 call assert_equal(0, hasmapto('/^\k\+ ('))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100584 map ,f /^\k\+ (<CR>
585 call assert_equal(1, hasmapto('/^\k\+ ('))
586 unmap ,f
587
588 " Insert mode mapping
589 call assert_equal(0, hasmapto('/^\k\+ (', 'i'))
590 imap ,f /^\k\+ (<CR>
591 call assert_equal(1, hasmapto('/^\k\+ (', 'i'))
592 iunmap ,f
593
594 " Normal mode mapping
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100595 call assert_equal(0, hasmapto('/^\k\+ (', 'n'))
596 nmap ,f /^\k\+ (<CR>
597 call assert_equal(1, hasmapto('/^\k\+ ('))
598 call assert_equal(1, hasmapto('/^\k\+ (', 'n'))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100599 nunmap ,f
600
601 " Visual and Select mode mapping
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100602 call assert_equal(0, hasmapto('/^\k\+ (', 'v'))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100603 call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
604 call assert_equal(0, hasmapto('/^\k\+ (', 's'))
605 vmap ,f /^\k\+ (<CR>
606 call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
607 call assert_equal(1, hasmapto('/^\k\+ (', 'x'))
608 call assert_equal(1, hasmapto('/^\k\+ (', 's'))
609 vunmap ,f
610
611 " Visual mode mapping
612 call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
613 xmap ,f /^\k\+ (<CR>
614 call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
615 call assert_equal(1, hasmapto('/^\k\+ (', 'x'))
616 call assert_equal(0, hasmapto('/^\k\+ (', 's'))
617 xunmap ,f
618
619 " Select mode mapping
620 call assert_equal(0, hasmapto('/^\k\+ (', 's'))
621 smap ,f /^\k\+ (<CR>
622 call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
623 call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
624 call assert_equal(1, hasmapto('/^\k\+ (', 's'))
625 sunmap ,f
626
627 " Operator-pending mode mapping
628 call assert_equal(0, hasmapto('/^\k\+ (', 'o'))
629 omap ,f /^\k\+ (<CR>
630 call assert_equal(1, hasmapto('/^\k\+ (', 'o'))
631 ounmap ,f
632
633 " Language mapping
634 call assert_equal(0, hasmapto('/^\k\+ (', 'l'))
635 lmap ,f /^\k\+ (<CR>
636 call assert_equal(1, hasmapto('/^\k\+ (', 'l'))
637 lunmap ,f
638
639 " Cmdline mode mapping
640 call assert_equal(0, hasmapto('/^\k\+ (', 'c'))
641 cmap ,f /^\k\+ (<CR>
642 call assert_equal(1, hasmapto('/^\k\+ (', 'c'))
643 cunmap ,f
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100644
645 call assert_equal(0, hasmapto('/^\k\+ (', 'n', 1))
646endfunc
647
648" Test for command-line completion of maps
649func Test_mapcomplete()
650 call assert_equal(['<buffer>', '<expr>', '<nowait>', '<script>',
651 \ '<silent>', '<special>', '<unique>'],
652 \ getcompletion('', 'mapping'))
653 call assert_equal([], getcompletion(',d', 'mapping'))
654
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100655 call feedkeys(":unmap <buf\<C-A>\<C-B>\"\<CR>", 'tx')
656 call assert_equal('"unmap <buffer>', @:)
657
658 call feedkeys(":unabbr <buf\<C-A>\<C-B>\"\<CR>", 'tx')
659 call assert_equal('"unabbr <buffer>', @:)
660
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100661 call feedkeys(":abbr! \<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100662 call assert_equal("\"abbr! \x01", @:)
663
664 " Multiple matches for a map
665 nmap ,f /H<CR>
666 omap ,f /H<CR>
667 call feedkeys(":map ,\<C-A>\<C-B>\"\<CR>", 'tx')
668 call assert_equal('"map ,f', @:)
669 mapclear
670endfunc
671
672" Test for <expr> in abbreviation
673func Test_expr_abbr()
674 new
675 iabbr <expr> teh "the"
676 call feedkeys("iteh ", "tx")
677 call assert_equal('the ', getline(1))
678 iabclear
679 call setline(1, '')
680
681 " invalid <expr> abbreviation
682 abbr <expr> hte GetAbbr()
683 call assert_fails('normal ihte ', 'E117:')
684 call assert_equal(' ', getline(1))
685 unabbr <expr> hte
686
687 close!
688endfunc
689
690" Test for storing mappings in different modes in a vimrc file
691func Test_mkvimrc_mapmodes()
692 map a1 /a1
693 nmap a2 /a2
694 vmap a3 /a3
695 smap a4 /a4
696 xmap a5 /a5
697 omap a6 /a6
698 map! a7 /a7
699 imap a8 /a8
700 lmap a9 /a9
701 cmap a10 /a10
702 tmap a11 /a11
703 " Normal + Visual map
704 map a12 /a12
705 sunmap a12
706 ounmap a12
707 " Normal + Selectmode map
708 map a13 /a13
709 xunmap a13
710 ounmap a13
711 " Normal + OpPending map
712 map a14 /a14
713 vunmap a14
714 " Visual + Selectmode map
715 map a15 /a15
716 nunmap a15
717 ounmap a15
718 " Visual + OpPending map
719 map a16 /a16
720 nunmap a16
721 sunmap a16
722 " Selectmode + OpPending map
723 map a17 /a17
724 nunmap a17
725 xunmap a17
726 " Normal + Visual + Selectmode map
727 map a18 /a18
728 ounmap a18
729 " Normal + Visual + OpPending map
730 map a19 /a19
731 sunmap a19
732 " Normal + Selectmode + OpPending map
733 map a20 /a20
734 xunmap a20
735 " Visual + Selectmode + OpPending map
736 map a21 /a21
737 nunmap a21
738 " Mapping to Nop
739 map a22 <Nop>
740 " Script local mapping
741 map <script> a23 /a23
742
743 " Newline in {lhs} and {rhs} of a map
744 exe "map a24\<C-V>\<C-J> ia24\<C-V>\<C-J><Esc>"
745
746 " Abbreviation
747 abbr a25 A25
748 cabbr a26 A26
749 iabbr a27 A27
750
751 mkvimrc! Xvimrc
752 let l = readfile('Xvimrc')
753 call assert_equal(['map a1 /a1'], filter(copy(l), 'v:val =~ " a1 "'))
754 call assert_equal(['nmap a2 /a2'], filter(copy(l), 'v:val =~ " a2 "'))
755 call assert_equal(['vmap a3 /a3'], filter(copy(l), 'v:val =~ " a3 "'))
756 call assert_equal(['smap a4 /a4'], filter(copy(l), 'v:val =~ " a4 "'))
757 call assert_equal(['xmap a5 /a5'], filter(copy(l), 'v:val =~ " a5 "'))
758 call assert_equal(['omap a6 /a6'], filter(copy(l), 'v:val =~ " a6 "'))
759 call assert_equal(['map! a7 /a7'], filter(copy(l), 'v:val =~ " a7 "'))
760 call assert_equal(['imap a8 /a8'], filter(copy(l), 'v:val =~ " a8 "'))
761 call assert_equal(['lmap a9 /a9'], filter(copy(l), 'v:val =~ " a9 "'))
762 call assert_equal(['cmap a10 /a10'], filter(copy(l), 'v:val =~ " a10 "'))
763 call assert_equal(['tmap a11 /a11'], filter(copy(l), 'v:val =~ " a11 "'))
764 call assert_equal(['nmap a12 /a12', 'xmap a12 /a12'],
765 \ filter(copy(l), 'v:val =~ " a12 "'))
766 call assert_equal(['nmap a13 /a13', 'smap a13 /a13'],
767 \ filter(copy(l), 'v:val =~ " a13 "'))
768 call assert_equal(['nmap a14 /a14', 'omap a14 /a14'],
769 \ filter(copy(l), 'v:val =~ " a14 "'))
770 call assert_equal(['vmap a15 /a15'], filter(copy(l), 'v:val =~ " a15 "'))
771 call assert_equal(['xmap a16 /a16', 'omap a16 /a16'],
772 \ filter(copy(l), 'v:val =~ " a16 "'))
773 call assert_equal(['smap a17 /a17', 'omap a17 /a17'],
774 \ filter(copy(l), 'v:val =~ " a17 "'))
775 call assert_equal(['nmap a18 /a18', 'vmap a18 /a18'],
776 \ filter(copy(l), 'v:val =~ " a18 "'))
777 call assert_equal(['nmap a19 /a19', 'xmap a19 /a19', 'omap a19 /a19'],
778 \ filter(copy(l), 'v:val =~ " a19 "'))
779 call assert_equal(['nmap a20 /a20', 'smap a20 /a20', 'omap a20 /a20'],
780 \ filter(copy(l), 'v:val =~ " a20 "'))
781 call assert_equal(['vmap a21 /a21', 'omap a21 /a21'],
782 \ filter(copy(l), 'v:val =~ " a21 "'))
783 call assert_equal(['map a22 <Nop>'], filter(copy(l), 'v:val =~ " a22 "'))
784 call assert_equal([], filter(copy(l), 'v:val =~ " a23 "'))
785 call assert_equal(["map a24<NL> ia24<NL>\x16\e"],
786 \ filter(copy(l), 'v:val =~ " a24"'))
787
788 call assert_equal(['abbr a25 A25'], filter(copy(l), 'v:val =~ " a25 "'))
789 call assert_equal(['cabbr a26 A26'], filter(copy(l), 'v:val =~ " a26 "'))
790 call assert_equal(['iabbr a27 A27'], filter(copy(l), 'v:val =~ " a27 "'))
791 call delete('Xvimrc')
792
793 mapclear
794 nmapclear
795 vmapclear
796 xmapclear
797 smapclear
798 omapclear
799 imapclear
800 lmapclear
801 cmapclear
802 tmapclear
803endfunc
804
805" Test for recursive mapping ('maxmapdepth')
806func Test_map_recursive()
807 map x y
808 map y x
809 call assert_fails('normal x', 'E223:')
810 unmap x
811 unmap y
812endfunc
813
814" Test for removing an abbreviation using {rhs} and with space after {lhs}
815func Test_abbr_remove()
816 abbr foo bar
817 let d = maparg('foo', 'i', 1, 1)
818 call assert_equal(['foo', 'bar', '!'], [d.lhs, d.rhs, d.mode])
819 unabbr bar
820 call assert_equal({}, maparg('foo', 'i', 1, 1))
821
822 abbr foo bar
823 unabbr foo<space><tab>
824 call assert_equal({}, maparg('foo', 'i', 1, 1))
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100825endfunc
826
Bram Moolenaar7f51bbe2020-01-24 20:21:19 +0100827" Trigger an abbreviation using a special key
828func Test_abbr_trigger_special()
829 new
830 iabbr teh the
831 call feedkeys("iteh\<F2>\<Esc>", 'xt')
832 call assert_equal('the<F2>', getline(1))
833 iunab teh
834 close!
835endfunc
836
837" Test for '<' in 'cpoptions'
838func Test_map_cpo_special_keycode()
839 set cpo-=<
840 imap x<Bslash>k Test
841 let d = maparg('x<Bslash>k', 'i', 0, 1)
842 call assert_equal(['x\k', 'Test', 'i'], [d.lhs, d.rhs, d.mode])
843 call feedkeys(":imap x\<C-A>\<C-B>\"\<CR>", 'tx')
844 call assert_equal('"imap x\k', @:)
845 iunmap x<Bslash>k
846 set cpo+=<
847 imap x<Bslash>k Test
848 let d = maparg('x<Bslash>k', 'i', 0, 1)
849 call assert_equal(['x<Bslash>k', 'Test', 'i'], [d.lhs, d.rhs, d.mode])
850 call feedkeys(":imap x\<C-A>\<C-B>\"\<CR>", 'tx')
851 call assert_equal('"imap x<Bslash>k', @:)
852 iunmap x<Bslash>k
853 set cpo-=<
854 " Modifying 'cpo' above adds some default mappings, remove them
855 mapclear
856 mapclear!
857endfunc
858
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100859" vim: shiftwidth=2 sts=2 expandtab