xref: /vim-8.2.3635/src/testdir/test_mapping.vim (revision 4b96df5a)
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  " verbose map
480  call assert_match("\tLast set from .*/test_mapping.vim line \\d\\+$",
481        \ execute('verbose map ,n')->trim()->split("\n")[1])
482
483  " map to CTRL-V
484  exe "nmap ,k \<C-V>"
485  call assert_equal(['n  ,k            <Nop>'],
486        \ execute('nmap ,k')->trim()->split("\n"))
487
488  nmapclear
489endfunc
490
491func Test_expr_map_restore_cursor()
492  CheckScreendump
493
494  let lines =<< trim END
495      call setline(1, ['one', 'two', 'three'])
496      2
497      set ls=2
498      hi! link StatusLine ErrorMsg
499      noremap <expr> <C-B> Func()
500      func Func()
501	  let g:on = !get(g:, 'on', 0)
502	  redraws
503	  return ''
504      endfunc
505      func Status()
506	  return get(g:, 'on', 0) ? '[on]' : ''
507      endfunc
508      set stl=%{Status()}
509  END
510  call writefile(lines, 'XtestExprMap')
511  let buf = RunVimInTerminal('-S XtestExprMap', #{rows: 10})
512  call term_wait(buf)
513  call term_sendkeys(buf, "\<C-B>")
514  call VerifyScreenDump(buf, 'Test_map_expr_1', {})
515
516  " clean up
517  call StopVimInTerminal(buf)
518  call delete('XtestExprMap')
519endfunc
520
521" Test for mapping errors
522func Test_map_error()
523  call assert_fails('unmap', 'E474:')
524  call assert_fails("exe 'map ' .. repeat('a', 51) .. ' :ls'", 'E474:')
525  call assert_fails('unmap abc', 'E31:')
526  call assert_fails('unabbr abc', 'E24:')
527  call assert_equal('', maparg(''))
528  call assert_fails('echo maparg("abc", [])', 'E730:')
529
530  " unique map
531  map ,w /[#&!]<CR>
532  call assert_fails("map <unique> ,w /[#&!]<CR>", 'E227:')
533  " unique buffer-local map
534  call assert_fails("map <buffer> <unique> ,w /[.,;]<CR>", 'E225:')
535  unmap ,w
536
537  " unique abbreviation
538  abbr SP special
539  call assert_fails("abbr <unique> SP special", 'E226:')
540  " unique buffer-local map
541  call assert_fails("abbr <buffer> <unique> SP special", 'E224:')
542  unabbr SP
543
544  call assert_fails('mapclear abc', 'E474:')
545  call assert_fails('abclear abc', 'E474:')
546  call assert_fails('abbr $xyz abc', 'E474:')
547
548  " space character in an abbreviation
549  call assert_fails('abbr ab<space> ABC', 'E474:')
550
551  " invalid <expr> map
552  map <expr> ,f abc
553  call assert_fails('normal ,f', 'E121:')
554  unmap <expr> ,f
555endfunc
556
557" Test for <special> key mapping
558func Test_map_special()
559  new
560  let old_cpo = &cpo
561  set cpo+=<
562  imap <F12> Blue
563  call feedkeys("i\<F12>", "x")
564  call assert_equal("<F12>", getline(1))
565  call feedkeys("ddi<F12>", "x")
566  call assert_equal("Blue", getline(1))
567  iunmap <F12>
568  imap <special> <F12> Green
569  call feedkeys("ddi\<F12>", "x")
570  call assert_equal("Green", getline(1))
571  call feedkeys("ddi<F12>", "x")
572  call assert_equal("<F12>", getline(1))
573  iunmap <special> <F12>
574  let &cpo = old_cpo
575  %bwipe!
576endfunc
577
578" Test for hasmapto()
579func Test_hasmapto()
580  call assert_equal(0, hasmapto('/^\k\+ ('))
581  map ,f /^\k\+ (<CR>
582  call assert_equal(1, hasmapto('/^\k\+ ('))
583  unmap ,f
584
585  " Insert mode mapping
586  call assert_equal(0, hasmapto('/^\k\+ (', 'i'))
587  imap ,f /^\k\+ (<CR>
588  call assert_equal(1, hasmapto('/^\k\+ (', 'i'))
589  iunmap ,f
590
591  " Normal mode mapping
592  call assert_equal(0, hasmapto('/^\k\+ (', 'n'))
593  nmap ,f /^\k\+ (<CR>
594  call assert_equal(1, hasmapto('/^\k\+ ('))
595  call assert_equal(1, hasmapto('/^\k\+ (', 'n'))
596  nunmap ,f
597
598  " Visual and Select mode mapping
599  call assert_equal(0, hasmapto('/^\k\+ (', 'v'))
600  call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
601  call assert_equal(0, hasmapto('/^\k\+ (', 's'))
602  vmap ,f /^\k\+ (<CR>
603  call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
604  call assert_equal(1, hasmapto('/^\k\+ (', 'x'))
605  call assert_equal(1, hasmapto('/^\k\+ (', 's'))
606  vunmap ,f
607
608  " Visual mode mapping
609  call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
610  xmap ,f /^\k\+ (<CR>
611  call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
612  call assert_equal(1, hasmapto('/^\k\+ (', 'x'))
613  call assert_equal(0, hasmapto('/^\k\+ (', 's'))
614  xunmap ,f
615
616  " Select mode mapping
617  call assert_equal(0, hasmapto('/^\k\+ (', 's'))
618  smap ,f /^\k\+ (<CR>
619  call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
620  call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
621  call assert_equal(1, hasmapto('/^\k\+ (', 's'))
622  sunmap ,f
623
624  " Operator-pending mode mapping
625  call assert_equal(0, hasmapto('/^\k\+ (', 'o'))
626  omap ,f /^\k\+ (<CR>
627  call assert_equal(1, hasmapto('/^\k\+ (', 'o'))
628  ounmap ,f
629
630  " Language mapping
631  call assert_equal(0, hasmapto('/^\k\+ (', 'l'))
632  lmap ,f /^\k\+ (<CR>
633  call assert_equal(1, hasmapto('/^\k\+ (', 'l'))
634  lunmap ,f
635
636  " Cmdline mode mapping
637  call assert_equal(0, hasmapto('/^\k\+ (', 'c'))
638  cmap ,f /^\k\+ (<CR>
639  call assert_equal(1, hasmapto('/^\k\+ (', 'c'))
640  cunmap ,f
641
642  call assert_equal(0, hasmapto('/^\k\+ (', 'n', 1))
643endfunc
644
645" Test for command-line completion of maps
646func Test_mapcomplete()
647  call assert_equal(['<buffer>', '<expr>', '<nowait>', '<script>',
648	      \ '<silent>', '<special>', '<unique>'],
649	      \ getcompletion('', 'mapping'))
650  call assert_equal([], getcompletion(',d', 'mapping'))
651
652  call feedkeys(":unmap <buf\<C-A>\<C-B>\"\<CR>", 'tx')
653  call assert_equal('"unmap <buffer>', @:)
654
655  call feedkeys(":unabbr <buf\<C-A>\<C-B>\"\<CR>", 'tx')
656  call assert_equal('"unabbr <buffer>', @:)
657
658  call feedkeys(":abbr! \<C-A>\<C-B>\"\<CR>", 'tx')
659  call assert_equal("\"abbr! \x01", @:)
660
661  " Multiple matches for a map
662  nmap ,f /H<CR>
663  omap ,f /H<CR>
664  call feedkeys(":map ,\<C-A>\<C-B>\"\<CR>", 'tx')
665  call assert_equal('"map ,f', @:)
666  mapclear
667endfunc
668
669" Test for <expr> in abbreviation
670func Test_expr_abbr()
671  new
672  iabbr <expr> teh "the"
673  call feedkeys("iteh ", "tx")
674  call assert_equal('the ', getline(1))
675  iabclear
676  call setline(1, '')
677
678  " invalid <expr> abbreviation
679  abbr <expr> hte GetAbbr()
680  call assert_fails('normal ihte ', 'E117:')
681  call assert_equal(' ', getline(1))
682  unabbr <expr> hte
683
684  close!
685endfunc
686
687" Test for storing mappings in different modes in a vimrc file
688func Test_mkvimrc_mapmodes()
689  map a1 /a1
690  nmap a2 /a2
691  vmap a3 /a3
692  smap a4 /a4
693  xmap a5 /a5
694  omap a6 /a6
695  map! a7 /a7
696  imap a8 /a8
697  lmap a9 /a9
698  cmap a10 /a10
699  tmap a11 /a11
700  " Normal + Visual map
701  map a12 /a12
702  sunmap a12
703  ounmap a12
704  " Normal + Selectmode map
705  map a13 /a13
706  xunmap a13
707  ounmap a13
708  " Normal + OpPending map
709  map a14 /a14
710  vunmap a14
711  " Visual + Selectmode map
712  map a15 /a15
713  nunmap a15
714  ounmap a15
715  " Visual + OpPending map
716  map a16 /a16
717  nunmap a16
718  sunmap a16
719  " Selectmode + OpPending map
720  map a17 /a17
721  nunmap a17
722  xunmap a17
723  " Normal + Visual + Selectmode map
724  map a18 /a18
725  ounmap a18
726  " Normal + Visual + OpPending map
727  map a19 /a19
728  sunmap a19
729  " Normal + Selectmode + OpPending map
730  map a20 /a20
731  xunmap a20
732  " Visual + Selectmode + OpPending map
733  map a21 /a21
734  nunmap a21
735  " Mapping to Nop
736  map a22 <Nop>
737  " Script local mapping
738  map <script> a23 /a23
739
740  " Newline in {lhs} and {rhs} of a map
741  exe "map a24\<C-V>\<C-J> ia24\<C-V>\<C-J><Esc>"
742
743  " Abbreviation
744  abbr a25 A25
745  cabbr a26 A26
746  iabbr a27 A27
747
748  mkvimrc! Xvimrc
749  let l = readfile('Xvimrc')
750  call assert_equal(['map a1 /a1'], filter(copy(l), 'v:val =~ " a1 "'))
751  call assert_equal(['nmap a2 /a2'], filter(copy(l), 'v:val =~ " a2 "'))
752  call assert_equal(['vmap a3 /a3'], filter(copy(l), 'v:val =~ " a3 "'))
753  call assert_equal(['smap a4 /a4'], filter(copy(l), 'v:val =~ " a4 "'))
754  call assert_equal(['xmap a5 /a5'], filter(copy(l), 'v:val =~ " a5 "'))
755  call assert_equal(['omap a6 /a6'], filter(copy(l), 'v:val =~ " a6 "'))
756  call assert_equal(['map! a7 /a7'], filter(copy(l), 'v:val =~ " a7 "'))
757  call assert_equal(['imap a8 /a8'], filter(copy(l), 'v:val =~ " a8 "'))
758  call assert_equal(['lmap a9 /a9'], filter(copy(l), 'v:val =~ " a9 "'))
759  call assert_equal(['cmap a10 /a10'], filter(copy(l), 'v:val =~ " a10 "'))
760  call assert_equal(['tmap a11 /a11'], filter(copy(l), 'v:val =~ " a11 "'))
761  call assert_equal(['nmap a12 /a12', 'xmap a12 /a12'],
762        \ filter(copy(l), 'v:val =~ " a12 "'))
763  call assert_equal(['nmap a13 /a13', 'smap a13 /a13'],
764        \ filter(copy(l), 'v:val =~ " a13 "'))
765  call assert_equal(['nmap a14 /a14', 'omap a14 /a14'],
766        \ filter(copy(l), 'v:val =~ " a14 "'))
767  call assert_equal(['vmap a15 /a15'], filter(copy(l), 'v:val =~ " a15 "'))
768  call assert_equal(['xmap a16 /a16', 'omap a16 /a16'],
769        \ filter(copy(l), 'v:val =~ " a16 "'))
770  call assert_equal(['smap a17 /a17', 'omap a17 /a17'],
771        \ filter(copy(l), 'v:val =~ " a17 "'))
772  call assert_equal(['nmap a18 /a18', 'vmap a18 /a18'],
773        \ filter(copy(l), 'v:val =~ " a18 "'))
774  call assert_equal(['nmap a19 /a19', 'xmap a19 /a19', 'omap a19 /a19'],
775        \ filter(copy(l), 'v:val =~ " a19 "'))
776  call assert_equal(['nmap a20 /a20', 'smap a20 /a20', 'omap a20 /a20'],
777        \ filter(copy(l), 'v:val =~ " a20 "'))
778  call assert_equal(['vmap a21 /a21', 'omap a21 /a21'],
779        \ filter(copy(l), 'v:val =~ " a21 "'))
780  call assert_equal(['map a22 <Nop>'], filter(copy(l), 'v:val =~ " a22 "'))
781  call assert_equal([], filter(copy(l), 'v:val =~ " a23 "'))
782  call assert_equal(["map a24<NL> ia24<NL>\x16\e"],
783        \ filter(copy(l), 'v:val =~ " a24"'))
784
785  call assert_equal(['abbr a25 A25'], filter(copy(l), 'v:val =~ " a25 "'))
786  call assert_equal(['cabbr a26 A26'], filter(copy(l), 'v:val =~ " a26 "'))
787  call assert_equal(['iabbr a27 A27'], filter(copy(l), 'v:val =~ " a27 "'))
788  call delete('Xvimrc')
789
790  mapclear
791  nmapclear
792  vmapclear
793  xmapclear
794  smapclear
795  omapclear
796  imapclear
797  lmapclear
798  cmapclear
799  tmapclear
800endfunc
801
802" Test for recursive mapping ('maxmapdepth')
803func Test_map_recursive()
804  map x y
805  map y x
806  call assert_fails('normal x', 'E223:')
807  unmap x
808  unmap y
809endfunc
810
811" Test for removing an abbreviation using {rhs} and with space after {lhs}
812func Test_abbr_remove()
813  abbr foo bar
814  let d = maparg('foo', 'i', 1, 1)
815  call assert_equal(['foo', 'bar', '!'], [d.lhs, d.rhs, d.mode])
816  unabbr bar
817  call assert_equal({}, maparg('foo', 'i', 1, 1))
818
819  abbr foo bar
820  unabbr foo<space><tab>
821  call assert_equal({}, maparg('foo', 'i', 1, 1))
822endfunc
823
824" Trigger an abbreviation using a special key
825func Test_abbr_trigger_special()
826  new
827  iabbr teh the
828  call feedkeys("iteh\<F2>\<Esc>", 'xt')
829  call assert_equal('the<F2>', getline(1))
830  iunab teh
831  close!
832endfunc
833
834" Test for '<' in 'cpoptions'
835func Test_map_cpo_special_keycode()
836  set cpo-=<
837  imap x<Bslash>k Test
838  let d = maparg('x<Bslash>k', 'i', 0, 1)
839  call assert_equal(['x\k', 'Test', 'i'], [d.lhs, d.rhs, d.mode])
840  call feedkeys(":imap x\<C-A>\<C-B>\"\<CR>", 'tx')
841  call assert_equal('"imap x\k', @:)
842  iunmap x<Bslash>k
843  set cpo+=<
844  imap x<Bslash>k Test
845  let d = maparg('x<Bslash>k', 'i', 0, 1)
846  call assert_equal(['x<Bslash>k', 'Test', 'i'], [d.lhs, d.rhs, d.mode])
847  call feedkeys(":imap x\<C-A>\<C-B>\"\<CR>", 'tx')
848  call assert_equal('"imap x<Bslash>k', @:)
849  iunmap x<Bslash>k
850  set cpo-=<
851  " Modifying 'cpo' above adds some default mappings, remove them
852  mapclear
853  mapclear!
854endfunc
855
856" vim: shiftwidth=2 sts=2 expandtab
857