xref: /vim-8.2.3635/src/testdir/test_mapping.vim (revision c2a60ae1)
1" Tests for mappings and abbreviations
2
3source shared.vim
4source check.vim
5source screendump.vim
6
7func 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
16func 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'))
41endfunc
42
43func Test_abclear_buffer()
44  abbrev foo foobar
45  new X1
46  abbrev <buffer> foo1 foobar1
47  new X2
48  abbrev <buffer> foo2 foobar2
49
50  call assert_equal("\n\n"
51        \        .. "!  foo2         @foobar2\n"
52        \        .. "!  foo           foobar", execute('abbrev'))
53
54  abclear <buffer>
55  call assert_equal("\n\n"
56        \        .. "!  foo           foobar", execute('abbrev'))
57
58  b X1
59  call assert_equal("\n\n"
60        \        .. "!  foo1         @foobar1\n"
61        \        .. "!  foo           foobar", execute('abbrev'))
62  abclear <buffer>
63  call assert_equal("\n\n"
64        \        .. "!  foo           foobar", execute('abbrev'))
65
66  abclear
67   call assert_equal("\n\nNo abbreviation found", execute('abbrev'))
68
69  %bwipe
70endfunc
71
72func Test_map_ctrl_c_insert()
73  " mapping of ctrl-c in Insert mode
74  set cpo-=< cpo-=k
75  inoremap <c-c> <ctrl-c>
76  cnoremap <c-c> dummy
77  cunmap <c-c>
78  call feedkeys("GoTEST2: CTRL-C |\<C-C>A|\<Esc>", "xt")
79  call assert_equal('TEST2: CTRL-C |<ctrl-c>A|', getline('$'))
80  unmap! <c-c>
81  set nomodified
82endfunc
83
84func Test_map_ctrl_c_visual()
85  " mapping of ctrl-c in Visual mode
86  vnoremap <c-c> :<C-u>$put ='vmap works'
87  call feedkeys("GV\<C-C>\<CR>", "xt")
88  call assert_equal('vmap works', getline('$'))
89  vunmap <c-c>
90  set nomodified
91endfunc
92
93func Test_map_langmap()
94  if !has('langmap')
95    return
96  endif
97
98  " check langmap applies in normal mode
99  set langmap=+- nolangremap
100  new
101  call setline(1, ['a', 'b', 'c'])
102  2
103  call assert_equal('b', getline('.'))
104  call feedkeys("+", "xt")
105  call assert_equal('a', getline('.'))
106
107  " check no remapping
108  map x +
109  2
110  call feedkeys("x", "xt")
111  call assert_equal('c', getline('.'))
112
113  " check with remapping
114  set langremap
115  2
116  call feedkeys("x", "xt")
117  call assert_equal('a', getline('.'))
118
119  unmap x
120  bwipe!
121
122  " 'langnoremap' follows 'langremap' and vise versa
123  set langremap
124  set langnoremap
125  call assert_equal(0, &langremap)
126  set langremap
127  call assert_equal(0, &langnoremap)
128  set nolangremap
129  call assert_equal(1, &langnoremap)
130
131  " check default values
132  set langnoremap&
133  call assert_equal(0, &langnoremap)
134  call assert_equal(1, &langremap)
135  set langremap&
136  call assert_equal(0, &langnoremap)
137  call assert_equal(1, &langremap)
138
139  " langmap should not apply in insert mode, 'langremap' doesn't matter
140  set langmap=+{ nolangremap
141  call feedkeys("Go+\<Esc>", "xt")
142  call assert_equal('+', getline('$'))
143  set langmap=+{ langremap
144  call feedkeys("Go+\<Esc>", "xt")
145  call assert_equal('+', getline('$'))
146
147  " langmap used for register name in insert mode.
148  call setreg('a', 'aaaa')
149  call setreg('b', 'bbbb')
150  call setreg('c', 'cccc')
151  set langmap=ab langremap
152  call feedkeys("Go\<C-R>a\<Esc>", "xt")
153  call assert_equal('bbbb', getline('$'))
154  call feedkeys("Go\<C-R>\<C-R>a\<Esc>", "xt")
155  call assert_equal('bbbb', getline('$'))
156  " mapping does not apply
157  imap c a
158  call feedkeys("Go\<C-R>c\<Esc>", "xt")
159  call assert_equal('cccc', getline('$'))
160  imap a c
161  call feedkeys("Go\<C-R>a\<Esc>", "xt")
162  call assert_equal('bbbb', getline('$'))
163
164  " langmap should not apply in Command-line mode
165  set langmap=+{ nolangremap
166  call feedkeys(":call append(line('$'), '+')\<CR>", "xt")
167  call assert_equal('+', getline('$'))
168
169  iunmap a
170  iunmap c
171  set nomodified
172endfunc
173
174func Test_map_feedkeys()
175  " issue #212 (feedkeys insert mapping at current position)
176  nnoremap . :call feedkeys(".", "in")<cr>
177  call setline('$', ['a b c d', 'a b c d'])
178  $-1
179  call feedkeys("0qqdw.ifoo\<Esc>qj0@q\<Esc>", "xt")
180  call assert_equal(['fooc d', 'fooc d'], getline(line('$') - 1, line('$')))
181  nunmap .
182  set nomodified
183endfunc
184
185func Test_map_cursor()
186  " <c-g>U<cursor> works only within a single line
187  imapclear
188  imap ( ()<c-g>U<left>
189  call feedkeys("G2o\<Esc>ki\<CR>Test1: text with a (here some more text\<Esc>k.", "xt")
190  call assert_equal('Test1: text with a (here some more text)', getline(line('$') - 2))
191  call assert_equal('Test1: text with a (here some more text)', getline(line('$') - 1))
192
193  " test undo
194  call feedkeys("G2o\<Esc>ki\<CR>Test2: text wit a (here some more text [und undo]\<C-G>u\<Esc>k.u", "xt")
195  call assert_equal('', getline(line('$') - 2))
196  call assert_equal('Test2: text wit a (here some more text [und undo])', getline(line('$') - 1))
197  set nomodified
198  imapclear
199endfunc
200
201func Test_map_cursor_ctrl_gU()
202  " <c-g>U<cursor> works only within a single line
203  nnoremap c<* *Ncgn<C-r>"<C-G>U<S-Left>
204  call setline(1, ['foo', 'foobar', '', 'foo'])
205  call cursor(1,2)
206  call feedkeys("c<*PREFIX\<esc>.", 'xt')
207  call assert_equal(['PREFIXfoo', 'foobar', '', 'PREFIXfoo'], getline(1,'$'))
208  " break undo manually
209  set ul=1000
210  exe ":norm! uu"
211  call assert_equal(['foo', 'foobar', '', 'foo'], getline(1,'$'))
212
213  " Test that it does not work if the cursor moves to the previous line
214  " 2 times <S-Left> move to the previous line
215  nnoremap c<* *Ncgn<C-r>"<C-G>U<S-Left><C-G>U<S-Left>
216  call setline(1, ['', ' foo', 'foobar', '', 'foo'])
217  call cursor(2,3)
218  call feedkeys("c<*PREFIX\<esc>.", 'xt')
219  call assert_equal(['PREFIXPREFIX', ' foo', 'foobar', '', 'foo'], getline(1,'$'))
220  nmapclear
221endfunc
222
223
224" This isn't actually testing a mapping, but similar use of CTRL-G U as above.
225func Test_break_undo()
226  set whichwrap=<,>,[,]
227  call feedkeys("G4o2k", "xt")
228  exe ":norm! iTest3: text with a (parenthesis here\<C-G>U\<Right>new line here\<esc>\<up>\<up>."
229  call assert_equal('new line here', getline(line('$') - 3))
230  call assert_equal('Test3: text with a (parenthesis here', getline(line('$') - 2))
231  call assert_equal('new line here', getline(line('$') - 1))
232  set nomodified
233endfunc
234
235func Test_map_meta_quotes()
236  imap <M-"> foo
237  call feedkeys("Go-\<M-\">-\<Esc>", "xt")
238  call assert_equal("-foo-", getline('$'))
239  set nomodified
240  iunmap <M-">
241endfunc
242
243func Test_map_meta_multibyte()
244  imap <M-á> foo
245  call assert_match('i  <M-á>\s*foo', execute('imap'))
246  iunmap <M-á>
247endfunc
248
249func Test_abbr_after_line_join()
250  new
251  abbr foo bar
252  set backspace=indent,eol,start
253  exe "normal o\<BS>foo "
254  call assert_equal("bar ", getline(1))
255  bwipe!
256  unabbr foo
257  set backspace&
258endfunc
259
260func Test_map_timeout()
261  if !has('timers')
262    return
263  endif
264  nnoremap aaaa :let got_aaaa = 1<CR>
265  nnoremap bb :let got_bb = 1<CR>
266  nmap b aaa
267  new
268  func ExitInsert(timer)
269    let g:line = getline(1)
270    call feedkeys("\<Esc>", "t")
271  endfunc
272  set timeout timeoutlen=200
273  let timer = timer_start(300, 'ExitInsert')
274  " After the 'b' Vim waits for another character to see if it matches 'bb'.
275  " When it times out it is expanded to "aaa", but there is no wait for
276  " "aaaa".  Can't check that reliably though.
277  call feedkeys("b", "xt!")
278  call assert_equal("aa", g:line)
279  call assert_false(exists('got_aaa'))
280  call assert_false(exists('got_bb'))
281
282  bwipe!
283  nunmap aaaa
284  nunmap bb
285  nunmap b
286  set timeoutlen&
287  delfunc ExitInsert
288  call timer_stop(timer)
289endfunc
290
291func Test_map_timeout_with_timer_interrupt()
292  if !has('job') || !has('timers')
293    return
294  endif
295
296  " Confirm the timer invoked in exit_cb of the job doesn't disturb mapped key
297  " sequence.
298  new
299  let g:val = 0
300  nnoremap \12 :let g:val = 1<CR>
301  nnoremap \123 :let g:val = 2<CR>
302  set timeout timeoutlen=200
303
304  func ExitCb(job, status)
305    let g:timer = timer_start(1, {-> feedkeys("3\<Esc>", 't')})
306  endfunc
307
308  call job_start([&shell, &shellcmdflag, 'echo'], {'exit_cb': 'ExitCb'})
309  call feedkeys('\12', 'xt!')
310  call assert_equal(2, g:val)
311
312  bwipe!
313  nunmap \12
314  nunmap \123
315  set timeoutlen&
316  call WaitFor({-> exists('g:timer')})
317  call timer_stop(g:timer)
318  unlet g:timer
319  unlet g:val
320  delfunc ExitCb
321endfunc
322
323func Test_abbreviation_CR()
324  new
325  func Eatchar(pat)
326    let c = nr2char(getchar(0))
327    return (c =~ a:pat) ? '' : c
328  endfunc
329  iabbrev <buffer><silent> ~~7 <c-r>=repeat('~', 7)<CR><c-r>=Eatchar('\s')<cr>
330  call feedkeys("GA~~7 \<esc>", 'xt')
331  call assert_equal('~~~~~~~', getline('$'))
332  %d
333  call feedkeys("GA~~7\<cr>\<esc>", 'xt')
334  call assert_equal(['~~~~~~~', ''], getline(1,'$'))
335  delfunc Eatchar
336  bw!
337endfunc
338
339func Test_cabbr_visual_mode()
340  cabbr s su
341  call feedkeys(":s \<c-B>\"\<CR>", 'itx')
342  call assert_equal('"su ', getreg(':'))
343  call feedkeys(":'<,'>s \<c-B>\"\<CR>", 'itx')
344  let expected = '"'. "'<,'>su "
345  call assert_equal(expected, getreg(':'))
346  call feedkeys(":  '<,'>s \<c-B>\"\<CR>", 'itx')
347  let expected = '"  '. "'<,'>su "
348  call assert_equal(expected, getreg(':'))
349  call feedkeys(":'a,'bs \<c-B>\"\<CR>", 'itx')
350  let expected = '"'. "'a,'bsu "
351  call assert_equal(expected, getreg(':'))
352  cunabbr s
353endfunc
354
355func Test_motionforce_omap()
356  func GetCommand()
357    let g:m=mode(1)
358    let [g:lnum1, g:col1] = searchpos('-', 'Wb')
359    if g:lnum1 == 0
360        return "\<Esc>"
361    endif
362    let [g:lnum2, g:col2] = searchpos('-', 'W')
363    if g:lnum2 == 0
364        return "\<Esc>"
365    endif
366    return ":call Select()\<CR>"
367  endfunc
368  func Select()
369    call cursor([g:lnum1, g:col1])
370    exe "normal! 1 ". (strlen(g:m) == 2 ? 'v' : g:m[2])
371    call cursor([g:lnum2, g:col2])
372    execute "normal! \<BS>"
373  endfunc
374  new
375  onoremap <buffer><expr> i- GetCommand()
376  " 1) default omap mapping
377  %d_
378  call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
379  call cursor(2, 1)
380  norm di-
381  call assert_equal('no', g:m)
382  call assert_equal(['aaa -- eee'], getline(1, '$'))
383  " 2) forced characterwise operation
384  %d_
385  call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
386  call cursor(2, 1)
387  norm dvi-
388  call assert_equal('nov', g:m)
389  call assert_equal(['aaa -- eee'], getline(1, '$'))
390  " 3) forced linewise operation
391  %d_
392  call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
393  call cursor(2, 1)
394  norm dVi-
395  call assert_equal('noV', g:m)
396  call assert_equal([''], getline(1, '$'))
397  " 4) forced blockwise operation
398  %d_
399  call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
400  call cursor(2, 1)
401  exe "norm d\<C-V>i-"
402  call assert_equal("no\<C-V>", g:m)
403  call assert_equal(['aaabbb', 'x', 'dddeee'], getline(1, '$'))
404  bwipe!
405  delfunc Select
406  delfunc GetCommand
407endfunc
408
409func Test_error_in_map_expr()
410  " Unlike CheckRunVimInTerminal this does work in a win32 console
411  CheckFeature terminal
412  if has('win32') && has('gui_running')
413    throw 'Skipped: cannot run Vim in a terminal window'
414  endif
415
416  let lines =<< trim [CODE]
417  func Func()
418    " fail to create list
419    let x = [
420  endfunc
421  nmap <expr> ! Func()
422  set updatetime=50
423  [CODE]
424  call writefile(lines, 'Xtest.vim')
425
426  let buf = term_start(GetVimCommandCleanTerm() .. ' -S Xtest.vim', {'term_rows': 8})
427  let job = term_getjob(buf)
428  call WaitForAssert({-> assert_notequal('', term_getline(buf, 8))})
429
430  " GC must not run during map-expr processing, which can make Vim crash.
431  call term_sendkeys(buf, '!')
432  call term_wait(buf, 100)
433  call term_sendkeys(buf, "\<CR>")
434  call term_wait(buf, 100)
435  call assert_equal('run', job_status(job))
436
437  call term_sendkeys(buf, ":qall!\<CR>")
438  call WaitFor({-> job_status(job) ==# 'dead'})
439  if has('unix')
440    call assert_equal('', job_info(job).termsig)
441  endif
442
443  call delete('Xtest.vim')
444  exe buf .. 'bwipe!'
445endfunc
446
447func Test_list_mappings()
448  " Remove default mappings
449  imapclear
450
451  inoremap <C-M> CtrlM
452  inoremap <A-S> AltS
453  inoremap <S-/> ShiftSlash
454  call assert_equal([
455	\ 'i  <S-/>       * ShiftSlash',
456	\ 'i  <M-S>       * AltS',
457	\ 'i  <C-M>       * CtrlM',
458	\], execute('imap')->trim()->split("\n"))
459  iunmap <C-M>
460  iunmap <A-S>
461  call assert_equal(['i  <S-/>       * ShiftSlash'], execute('imap')->trim()->split("\n"))
462  iunmap <S-/>
463  call assert_equal(['No mapping found'], execute('imap')->trim()->split("\n"))
464
465  " List global, buffer local and script local mappings
466  nmap ,f /^\k\+ (<CR>
467  nmap <buffer> ,f /^\k\+ (<CR>
468  nmap <script> ,fs /^\k\+ (<CR>
469  call assert_equal(['n  ,f           @/^\k\+ (<CR>',
470        \ 'n  ,fs         & /^\k\+ (<CR>',
471        \ 'n  ,f            /^\k\+ (<CR>'],
472        \ execute('nmap ,f')->trim()->split("\n"))
473
474  " List <Nop> mapping
475  nmap ,n <Nop>
476  call assert_equal(['n  ,n            <Nop>'],
477        \ execute('nmap ,n')->trim()->split("\n"))
478
479  nmapclear
480endfunc
481
482func Test_expr_map_restore_cursor()
483  CheckScreendump
484
485  let lines =<< trim END
486      call setline(1, ['one', 'two', 'three'])
487      2
488      set ls=2
489      hi! link StatusLine ErrorMsg
490      noremap <expr> <C-B> Func()
491      func Func()
492	  let g:on = !get(g:, 'on', 0)
493	  redraws
494	  return ''
495      endfunc
496      func Status()
497	  return get(g:, 'on', 0) ? '[on]' : ''
498      endfunc
499      set stl=%{Status()}
500  END
501  call writefile(lines, 'XtestExprMap')
502  let buf = RunVimInTerminal('-S XtestExprMap', #{rows: 10})
503  call term_wait(buf)
504  call term_sendkeys(buf, "\<C-B>")
505  call VerifyScreenDump(buf, 'Test_map_expr_1', {})
506
507  " clean up
508  call StopVimInTerminal(buf)
509  call delete('XtestExprMap')
510endfunc
511
512" Test for mapping errors
513func Test_map_error()
514  call assert_fails('unmap', 'E474:')
515  call assert_fails("exe 'map ' .. repeat('a', 51) .. ' :ls'", 'E474:')
516  call assert_fails('unmap abc', 'E31:')
517  call assert_fails('unabbr abc', 'E24:')
518  call assert_equal('', maparg(''))
519  call assert_fails('echo maparg("abc", [])', 'E730:')
520
521  " unique map
522  map ,w /[#&!]<CR>
523  call assert_fails("map <unique> ,w /[#&!]<CR>", 'E227:')
524  " unique buffer-local map
525  call assert_fails("map <buffer> <unique> ,w /[.,;]<CR>", 'E225:')
526  unmap ,w
527
528  " unique abbreviation
529  abbr SP special
530  call assert_fails("abbr <unique> SP special", 'E226:')
531  " unique buffer-local map
532  call assert_fails("abbr <buffer> <unique> SP special", 'E224:')
533  unabbr SP
534
535  call assert_fails('mapclear abc', 'E474:')
536  call assert_fails('abclear abc', 'E474:')
537  call assert_fails('abbr $xyz abc', 'E474:')
538
539  " space character in an abbreviation
540  call assert_fails('abbr ab<space> ABC', 'E474:')
541
542  " invalid <expr> map
543  map <expr> ,f abc
544  call assert_fails('normal ,f', 'E121:')
545  unmap <expr> ,f
546endfunc
547
548" Test for <special> key mapping
549func Test_map_special()
550  new
551  let old_cpo = &cpo
552  set cpo+=<
553  imap <F12> Blue
554  call feedkeys("i\<F12>", "x")
555  call assert_equal("<F12>", getline(1))
556  call feedkeys("ddi<F12>", "x")
557  call assert_equal("Blue", getline(1))
558  iunmap <F12>
559  imap <special> <F12> Green
560  call feedkeys("ddi\<F12>", "x")
561  call assert_equal("Green", getline(1))
562  call feedkeys("ddi<F12>", "x")
563  call assert_equal("<F12>", getline(1))
564  iunmap <special> <F12>
565  let &cpo = old_cpo
566  %bwipe!
567endfunc
568
569" Test for hasmapto()
570func Test_hasmapto()
571  call assert_equal(0, hasmapto('/^\k\+ ('))
572  map ,f /^\k\+ (<CR>
573  call assert_equal(1, hasmapto('/^\k\+ ('))
574  unmap ,f
575
576  " Insert mode mapping
577  call assert_equal(0, hasmapto('/^\k\+ (', 'i'))
578  imap ,f /^\k\+ (<CR>
579  call assert_equal(1, hasmapto('/^\k\+ (', 'i'))
580  iunmap ,f
581
582  " Normal mode mapping
583  call assert_equal(0, hasmapto('/^\k\+ (', 'n'))
584  nmap ,f /^\k\+ (<CR>
585  call assert_equal(1, hasmapto('/^\k\+ ('))
586  call assert_equal(1, hasmapto('/^\k\+ (', 'n'))
587  nunmap ,f
588
589  " Visual and Select mode mapping
590  call assert_equal(0, hasmapto('/^\k\+ (', 'v'))
591  call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
592  call assert_equal(0, hasmapto('/^\k\+ (', 's'))
593  vmap ,f /^\k\+ (<CR>
594  call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
595  call assert_equal(1, hasmapto('/^\k\+ (', 'x'))
596  call assert_equal(1, hasmapto('/^\k\+ (', 's'))
597  vunmap ,f
598
599  " Visual mode mapping
600  call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
601  xmap ,f /^\k\+ (<CR>
602  call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
603  call assert_equal(1, hasmapto('/^\k\+ (', 'x'))
604  call assert_equal(0, hasmapto('/^\k\+ (', 's'))
605  xunmap ,f
606
607  " Select mode mapping
608  call assert_equal(0, hasmapto('/^\k\+ (', 's'))
609  smap ,f /^\k\+ (<CR>
610  call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
611  call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
612  call assert_equal(1, hasmapto('/^\k\+ (', 's'))
613  sunmap ,f
614
615  " Operator-pending mode mapping
616  call assert_equal(0, hasmapto('/^\k\+ (', 'o'))
617  omap ,f /^\k\+ (<CR>
618  call assert_equal(1, hasmapto('/^\k\+ (', 'o'))
619  ounmap ,f
620
621  " Language mapping
622  call assert_equal(0, hasmapto('/^\k\+ (', 'l'))
623  lmap ,f /^\k\+ (<CR>
624  call assert_equal(1, hasmapto('/^\k\+ (', 'l'))
625  lunmap ,f
626
627  " Cmdline mode mapping
628  call assert_equal(0, hasmapto('/^\k\+ (', 'c'))
629  cmap ,f /^\k\+ (<CR>
630  call assert_equal(1, hasmapto('/^\k\+ (', 'c'))
631  cunmap ,f
632
633  call assert_equal(0, hasmapto('/^\k\+ (', 'n', 1))
634endfunc
635
636" Test for command-line completion of maps
637func Test_mapcomplete()
638  call assert_equal(['<buffer>', '<expr>', '<nowait>', '<script>',
639	      \ '<silent>', '<special>', '<unique>'],
640	      \ getcompletion('', 'mapping'))
641  call assert_equal([], getcompletion(',d', 'mapping'))
642
643  call feedkeys(":unmap <buf\<C-A>\<C-B>\"\<CR>", 'tx')
644  call assert_equal('"unmap <buffer>', @:)
645
646  call feedkeys(":unabbr <buf\<C-A>\<C-B>\"\<CR>", 'tx')
647  call assert_equal('"unabbr <buffer>', @:)
648
649  call feedkeys(":abbr! \<C-A>\<C-B>\"\<CR>", 'tx')
650  call assert_equal("\"abbr! \x01", @:)
651
652  " Multiple matches for a map
653  nmap ,f /H<CR>
654  omap ,f /H<CR>
655  call feedkeys(":map ,\<C-A>\<C-B>\"\<CR>", 'tx')
656  call assert_equal('"map ,f', @:)
657  mapclear
658endfunc
659
660" Test for <expr> in abbreviation
661func Test_expr_abbr()
662  new
663  iabbr <expr> teh "the"
664  call feedkeys("iteh ", "tx")
665  call assert_equal('the ', getline(1))
666  iabclear
667  call setline(1, '')
668
669  " invalid <expr> abbreviation
670  abbr <expr> hte GetAbbr()
671  call assert_fails('normal ihte ', 'E117:')
672  call assert_equal(' ', getline(1))
673  unabbr <expr> hte
674
675  close!
676endfunc
677
678" Test for storing mappings in different modes in a vimrc file
679func Test_mkvimrc_mapmodes()
680  map a1 /a1
681  nmap a2 /a2
682  vmap a3 /a3
683  smap a4 /a4
684  xmap a5 /a5
685  omap a6 /a6
686  map! a7 /a7
687  imap a8 /a8
688  lmap a9 /a9
689  cmap a10 /a10
690  tmap a11 /a11
691  " Normal + Visual map
692  map a12 /a12
693  sunmap a12
694  ounmap a12
695  " Normal + Selectmode map
696  map a13 /a13
697  xunmap a13
698  ounmap a13
699  " Normal + OpPending map
700  map a14 /a14
701  vunmap a14
702  " Visual + Selectmode map
703  map a15 /a15
704  nunmap a15
705  ounmap a15
706  " Visual + OpPending map
707  map a16 /a16
708  nunmap a16
709  sunmap a16
710  " Selectmode + OpPending map
711  map a17 /a17
712  nunmap a17
713  xunmap a17
714  " Normal + Visual + Selectmode map
715  map a18 /a18
716  ounmap a18
717  " Normal + Visual + OpPending map
718  map a19 /a19
719  sunmap a19
720  " Normal + Selectmode + OpPending map
721  map a20 /a20
722  xunmap a20
723  " Visual + Selectmode + OpPending map
724  map a21 /a21
725  nunmap a21
726  " Mapping to Nop
727  map a22 <Nop>
728  " Script local mapping
729  map <script> a23 /a23
730
731  " Newline in {lhs} and {rhs} of a map
732  exe "map a24\<C-V>\<C-J> ia24\<C-V>\<C-J><Esc>"
733
734  " Abbreviation
735  abbr a25 A25
736  cabbr a26 A26
737  iabbr a27 A27
738
739  mkvimrc! Xvimrc
740  let l = readfile('Xvimrc')
741  call assert_equal(['map a1 /a1'], filter(copy(l), 'v:val =~ " a1 "'))
742  call assert_equal(['nmap a2 /a2'], filter(copy(l), 'v:val =~ " a2 "'))
743  call assert_equal(['vmap a3 /a3'], filter(copy(l), 'v:val =~ " a3 "'))
744  call assert_equal(['smap a4 /a4'], filter(copy(l), 'v:val =~ " a4 "'))
745  call assert_equal(['xmap a5 /a5'], filter(copy(l), 'v:val =~ " a5 "'))
746  call assert_equal(['omap a6 /a6'], filter(copy(l), 'v:val =~ " a6 "'))
747  call assert_equal(['map! a7 /a7'], filter(copy(l), 'v:val =~ " a7 "'))
748  call assert_equal(['imap a8 /a8'], filter(copy(l), 'v:val =~ " a8 "'))
749  call assert_equal(['lmap a9 /a9'], filter(copy(l), 'v:val =~ " a9 "'))
750  call assert_equal(['cmap a10 /a10'], filter(copy(l), 'v:val =~ " a10 "'))
751  call assert_equal(['tmap a11 /a11'], filter(copy(l), 'v:val =~ " a11 "'))
752  call assert_equal(['nmap a12 /a12', 'xmap a12 /a12'],
753        \ filter(copy(l), 'v:val =~ " a12 "'))
754  call assert_equal(['nmap a13 /a13', 'smap a13 /a13'],
755        \ filter(copy(l), 'v:val =~ " a13 "'))
756  call assert_equal(['nmap a14 /a14', 'omap a14 /a14'],
757        \ filter(copy(l), 'v:val =~ " a14 "'))
758  call assert_equal(['vmap a15 /a15'], filter(copy(l), 'v:val =~ " a15 "'))
759  call assert_equal(['xmap a16 /a16', 'omap a16 /a16'],
760        \ filter(copy(l), 'v:val =~ " a16 "'))
761  call assert_equal(['smap a17 /a17', 'omap a17 /a17'],
762        \ filter(copy(l), 'v:val =~ " a17 "'))
763  call assert_equal(['nmap a18 /a18', 'vmap a18 /a18'],
764        \ filter(copy(l), 'v:val =~ " a18 "'))
765  call assert_equal(['nmap a19 /a19', 'xmap a19 /a19', 'omap a19 /a19'],
766        \ filter(copy(l), 'v:val =~ " a19 "'))
767  call assert_equal(['nmap a20 /a20', 'smap a20 /a20', 'omap a20 /a20'],
768        \ filter(copy(l), 'v:val =~ " a20 "'))
769  call assert_equal(['vmap a21 /a21', 'omap a21 /a21'],
770        \ filter(copy(l), 'v:val =~ " a21 "'))
771  call assert_equal(['map a22 <Nop>'], filter(copy(l), 'v:val =~ " a22 "'))
772  call assert_equal([], filter(copy(l), 'v:val =~ " a23 "'))
773  call assert_equal(["map a24<NL> ia24<NL>\x16\e"],
774        \ filter(copy(l), 'v:val =~ " a24"'))
775
776  call assert_equal(['abbr a25 A25'], filter(copy(l), 'v:val =~ " a25 "'))
777  call assert_equal(['cabbr a26 A26'], filter(copy(l), 'v:val =~ " a26 "'))
778  call assert_equal(['iabbr a27 A27'], filter(copy(l), 'v:val =~ " a27 "'))
779  call delete('Xvimrc')
780
781  mapclear
782  nmapclear
783  vmapclear
784  xmapclear
785  smapclear
786  omapclear
787  imapclear
788  lmapclear
789  cmapclear
790  tmapclear
791endfunc
792
793" Test for recursive mapping ('maxmapdepth')
794func Test_map_recursive()
795  map x y
796  map y x
797  call assert_fails('normal x', 'E223:')
798  unmap x
799  unmap y
800endfunc
801
802" Test for removing an abbreviation using {rhs} and with space after {lhs}
803func Test_abbr_remove()
804  abbr foo bar
805  let d = maparg('foo', 'i', 1, 1)
806  call assert_equal(['foo', 'bar', '!'], [d.lhs, d.rhs, d.mode])
807  unabbr bar
808  call assert_equal({}, maparg('foo', 'i', 1, 1))
809
810  abbr foo bar
811  unabbr foo<space><tab>
812  call assert_equal({}, maparg('foo', 'i', 1, 1))
813endfunc
814
815" vim: shiftwidth=2 sts=2 expandtab
816