xref: /vim-8.2.3635/src/testdir/test_mapping.vim (revision 81ea1dfb)
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'))
41   call assert_fails('%abclear', 'E481:')
42endfunc
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
73func 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>
79  call feedkeys("GoTEST2: CTRL-C |\<C-C>A|\<Esc>", "xt")
80  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'
88  call feedkeys("GV\<C-C>\<CR>", "xt")
89  call assert_equal('vmap works', getline('$'))
90  vunmap <c-c>
91  set nomodified
92endfunc
93
94func Test_map_langmap()
95  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
132  " 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
140  " 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
145  call feedkeys("Go+\<Esc>", "xt")
146  call assert_equal('+', getline('$'))
147
148  " 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
167  call feedkeys(":call append(line('$'), '+')\<CR>", "xt")
168  call assert_equal('+', getline('$'))
169
170  iunmap a
171  iunmap c
172  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('$')))
182  nunmap .
183  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
202func 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
225" This isn't actually testing a mapping, but similar use of CTRL-G U as above.
226func Test_break_undo()
227  set whichwrap=<,>,[,]
228  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
235
236func Test_map_meta_quotes()
237  imap <M-"> foo
238  call feedkeys("Go-\<M-\">-\<Esc>", "xt")
239  call assert_equal("-foo-", getline('$'))
240  set nomodified
241  iunmap <M-">
242endfunc
243
244func Test_map_meta_multibyte()
245  imap <M-á> foo
246  call assert_match('i  <M-á>\s*foo', execute('imap'))
247  iunmap <M-á>
248endfunc
249
250func 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
260
261func Test_map_timeout()
262  if !has('timers')
263    return
264  endif
265  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
274  let timer = timer_start(300, 'ExitInsert')
275  " 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
289  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>
303  set timeout timeoutlen=200
304
305  func ExitCb(job, status)
306    let g:timer = timer_start(1, {-> feedkeys("3\<Esc>", 't')})
307  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
322endfunc
323
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
339
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
355
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
409
410func Test_error_in_map_expr()
411  " Unlike CheckRunVimInTerminal this does work in a win32 console
412  CheckFeature terminal
413  if has('win32') && has('gui_running')
414    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
427  let buf = term_start(GetVimCommandCleanTerm() .. ' -S Xtest.vim', {'term_rows': 8})
428  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, '!')
433  call TermWait(buf, 50)
434  call term_sendkeys(buf, "\<CR>")
435  call TermWait(buf, 50)
436  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
447
448func Test_list_mappings()
449  " Remove default mappings
450  imapclear
451
452  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"))
465
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
480  " 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
489  nmapclear
490endfunc
491
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})
513  call TermWait(buf)
514  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
521
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:')
547  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
556
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&
563endfunc
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\+ ('))
589  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
600  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'))
604  nunmap ,f
605
606  " Visual and Select mode mapping
607  call assert_equal(0, hasmapto('/^\k\+ (', 'v'))
608  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
649
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
660  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
666  call feedkeys(":abbr! \<C-A>\<C-B>\"\<CR>", 'tx')
667  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))
830endfunc
831
832" 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
864" vim: shiftwidth=2 sts=2 expandtab
865