xref: /vim-8.2.3635/src/testdir/test_mapping.vim (revision 577fadfc)
1" Tests for mappings and abbreviations
2
3source shared.vim
4
5func Test_abbreviation()
6  " abbreviation with 0x80 should work
7  inoreab чкпр   vim
8  call feedkeys("Goчкпр \<Esc>", "xt")
9  call assert_equal('vim ', getline('$'))
10  iunab чкпр
11  set nomodified
12endfunc
13
14func Test_map_ctrl_c_insert()
15  " mapping of ctrl-c in Insert mode
16  set cpo-=< cpo-=k
17  inoremap <c-c> <ctrl-c>
18  cnoremap <c-c> dummy
19  cunmap <c-c>
20  call feedkeys("GoTEST2: CTRL-C |\<C-C>A|\<Esc>", "xt")
21  call assert_equal('TEST2: CTRL-C |<ctrl-c>A|', getline('$'))
22  unmap! <c-c>
23  set nomodified
24endfunc
25
26func Test_map_ctrl_c_visual()
27  " mapping of ctrl-c in Visual mode
28  vnoremap <c-c> :<C-u>$put ='vmap works'
29  call feedkeys("GV\<C-C>\<CR>", "xt")
30  call assert_equal('vmap works', getline('$'))
31  vunmap <c-c>
32  set nomodified
33endfunc
34
35func Test_map_langmap()
36  if !has('langmap')
37    return
38  endif
39
40  " check langmap applies in normal mode
41  set langmap=+- nolangremap
42  new
43  call setline(1, ['a', 'b', 'c'])
44  2
45  call assert_equal('b', getline('.'))
46  call feedkeys("+", "xt")
47  call assert_equal('a', getline('.'))
48
49  " check no remapping
50  map x +
51  2
52  call feedkeys("x", "xt")
53  call assert_equal('c', getline('.'))
54
55  " check with remapping
56  set langremap
57  2
58  call feedkeys("x", "xt")
59  call assert_equal('a', getline('.'))
60
61  unmap x
62  bwipe!
63
64  " 'langnoremap' follows 'langremap' and vise versa
65  set langremap
66  set langnoremap
67  call assert_equal(0, &langremap)
68  set langremap
69  call assert_equal(0, &langnoremap)
70  set nolangremap
71  call assert_equal(1, &langnoremap)
72
73  " check default values
74  set langnoremap&
75  call assert_equal(0, &langnoremap)
76  call assert_equal(1, &langremap)
77  set langremap&
78  call assert_equal(0, &langnoremap)
79  call assert_equal(1, &langremap)
80
81  " langmap should not apply in insert mode, 'langremap' doesn't matter
82  set langmap=+{ nolangremap
83  call feedkeys("Go+\<Esc>", "xt")
84  call assert_equal('+', getline('$'))
85  set langmap=+{ langremap
86  call feedkeys("Go+\<Esc>", "xt")
87  call assert_equal('+', getline('$'))
88
89  " langmap used for register name in insert mode.
90  call setreg('a', 'aaaa')
91  call setreg('b', 'bbbb')
92  call setreg('c', 'cccc')
93  set langmap=ab langremap
94  call feedkeys("Go\<C-R>a\<Esc>", "xt")
95  call assert_equal('bbbb', getline('$'))
96  call feedkeys("Go\<C-R>\<C-R>a\<Esc>", "xt")
97  call assert_equal('bbbb', getline('$'))
98  " mapping does not apply
99  imap c a
100  call feedkeys("Go\<C-R>c\<Esc>", "xt")
101  call assert_equal('cccc', getline('$'))
102  imap a c
103  call feedkeys("Go\<C-R>a\<Esc>", "xt")
104  call assert_equal('bbbb', getline('$'))
105
106  " langmap should not apply in Command-line mode
107  set langmap=+{ nolangremap
108  call feedkeys(":call append(line('$'), '+')\<CR>", "xt")
109  call assert_equal('+', getline('$'))
110
111  iunmap a
112  iunmap c
113  set nomodified
114endfunc
115
116func Test_map_feedkeys()
117  " issue #212 (feedkeys insert mapping at current position)
118  nnoremap . :call feedkeys(".", "in")<cr>
119  call setline('$', ['a b c d', 'a b c d'])
120  $-1
121  call feedkeys("0qqdw.ifoo\<Esc>qj0@q\<Esc>", "xt")
122  call assert_equal(['fooc d', 'fooc d'], getline(line('$') - 1, line('$')))
123  nunmap .
124  set nomodified
125endfunc
126
127func Test_map_cursor()
128  " <c-g>U<cursor> works only within a single line
129  imapclear
130  imap ( ()<c-g>U<left>
131  call feedkeys("G2o\<Esc>ki\<CR>Test1: text with a (here some more text\<Esc>k.", "xt")
132  call assert_equal('Test1: text with a (here some more text)', getline(line('$') - 2))
133  call assert_equal('Test1: text with a (here some more text)', getline(line('$') - 1))
134
135  " test undo
136  call feedkeys("G2o\<Esc>ki\<CR>Test2: text wit a (here some more text [und undo]\<C-G>u\<Esc>k.u", "xt")
137  call assert_equal('', getline(line('$') - 2))
138  call assert_equal('Test2: text wit a (here some more text [und undo])', getline(line('$') - 1))
139  set nomodified
140  imapclear
141endfunc
142
143func Test_map_cursor_ctrl_gU()
144  " <c-g>U<cursor> works only within a single line
145  nnoremap c<* *Ncgn<C-r>"<C-G>U<S-Left>
146  call setline(1, ['foo', 'foobar', '', 'foo'])
147  call cursor(1,2)
148  call feedkeys("c<*PREFIX\<esc>.", 'xt')
149  call assert_equal(['PREFIXfoo', 'foobar', '', 'PREFIXfoo'], getline(1,'$'))
150  " break undo manually
151  set ul=1000
152  exe ":norm! uu"
153  call assert_equal(['foo', 'foobar', '', 'foo'], getline(1,'$'))
154
155  " Test that it does not work if the cursor moves to the previous line
156  " 2 times <S-Left> move to the previous line
157  nnoremap c<* *Ncgn<C-r>"<C-G>U<S-Left><C-G>U<S-Left>
158  call setline(1, ['', ' foo', 'foobar', '', 'foo'])
159  call cursor(2,3)
160  call feedkeys("c<*PREFIX\<esc>.", 'xt')
161  call assert_equal(['PREFIXPREFIX', ' foo', 'foobar', '', 'foo'], getline(1,'$'))
162  nmapclear
163endfunc
164
165
166" This isn't actually testing a mapping, but similar use of CTRL-G U as above.
167func Test_break_undo()
168  set whichwrap=<,>,[,]
169  call feedkeys("G4o2k", "xt")
170  exe ":norm! iTest3: text with a (parenthesis here\<C-G>U\<Right>new line here\<esc>\<up>\<up>."
171  call assert_equal('new line here', getline(line('$') - 3))
172  call assert_equal('Test3: text with a (parenthesis here', getline(line('$') - 2))
173  call assert_equal('new line here', getline(line('$') - 1))
174  set nomodified
175endfunc
176
177func Test_map_meta_quotes()
178  imap <M-"> foo
179  call feedkeys("Go-\<M-\">-\<Esc>", "xt")
180  call assert_equal("-foo-", getline('$'))
181  set nomodified
182  iunmap <M-">
183endfunc
184
185func Test_abbr_after_line_join()
186  new
187  abbr foo bar
188  set backspace=indent,eol,start
189  exe "normal o\<BS>foo "
190  call assert_equal("bar ", getline(1))
191  bwipe!
192  unabbr foo
193  set backspace&
194endfunc
195
196func Test_map_timeout()
197  if !has('timers')
198    return
199  endif
200  nnoremap aaaa :let got_aaaa = 1<CR>
201  nnoremap bb :let got_bb = 1<CR>
202  nmap b aaa
203  new
204  func ExitInsert(timer)
205    let g:line = getline(1)
206    call feedkeys("\<Esc>", "t")
207  endfunc
208  set timeout timeoutlen=200
209  let timer = timer_start(300, 'ExitInsert')
210  " After the 'b' Vim waits for another character to see if it matches 'bb'.
211  " When it times out it is expanded to "aaa", but there is no wait for
212  " "aaaa".  Can't check that reliably though.
213  call feedkeys("b", "xt!")
214  call assert_equal("aa", g:line)
215  call assert_false(exists('got_aaa'))
216  call assert_false(exists('got_bb'))
217
218  bwipe!
219  nunmap aaaa
220  nunmap bb
221  nunmap b
222  set timeoutlen&
223  delfunc ExitInsert
224  call timer_stop(timer)
225endfunc
226
227func Test_map_timeout_with_timer_interrupt()
228  if !has('job') || !has('timers')
229    return
230  endif
231
232  " Confirm the timer invoked in exit_cb of the job doesn't disturb mapped key
233  " sequence.
234  new
235  let g:val = 0
236  nnoremap \12 :let g:val = 1<CR>
237  nnoremap \123 :let g:val = 2<CR>
238  set timeout timeoutlen=1000
239
240  func ExitCb(job, status)
241    let g:timer = timer_start(1, {-> feedkeys("3\<Esc>", 't')})
242  endfunc
243
244  call job_start([&shell, &shellcmdflag, 'echo'], {'exit_cb': 'ExitCb'})
245  call feedkeys('\12', 'xt!')
246  call assert_equal(2, g:val)
247
248  bwipe!
249  nunmap \12
250  nunmap \123
251  set timeoutlen&
252  call WaitFor({-> exists('g:timer')})
253  call timer_stop(g:timer)
254  unlet g:timer
255  unlet g:val
256  delfunc ExitCb
257endfunc
258
259func Test_abbreviation_CR()
260  new
261  func Eatchar(pat)
262    let c = nr2char(getchar(0))
263    return (c =~ a:pat) ? '' : c
264  endfunc
265  iabbrev <buffer><silent> ~~7 <c-r>=repeat('~', 7)<CR><c-r>=Eatchar('\s')<cr>
266  call feedkeys("GA~~7 \<esc>", 'xt')
267  call assert_equal('~~~~~~~', getline('$'))
268  %d
269  call feedkeys("GA~~7\<cr>\<esc>", 'xt')
270  call assert_equal(['~~~~~~~', ''], getline(1,'$'))
271  delfunc Eatchar
272  bw!
273endfunc
274
275func Test_cabbr_visual_mode()
276  cabbr s su
277  call feedkeys(":s \<c-B>\"\<CR>", 'itx')
278  call assert_equal('"su ', getreg(':'))
279  call feedkeys(":'<,'>s \<c-B>\"\<CR>", 'itx')
280  let expected = '"'. "'<,'>su "
281  call assert_equal(expected, getreg(':'))
282  call feedkeys(":  '<,'>s \<c-B>\"\<CR>", 'itx')
283  let expected = '"  '. "'<,'>su "
284  call assert_equal(expected, getreg(':'))
285  call feedkeys(":'a,'bs \<c-B>\"\<CR>", 'itx')
286  let expected = '"'. "'a,'bsu "
287  call assert_equal(expected, getreg(':'))
288  cunabbr s
289endfunc
290
291func Test_motionforce_omap()
292  func GetCommand()
293    let g:m=mode(1)
294    let [g:lnum1, g:col1] = searchpos('-', 'Wb')
295    if g:lnum1 == 0
296        return "\<Esc>"
297    endif
298    let [g:lnum2, g:col2] = searchpos('-', 'W')
299    if g:lnum2 == 0
300        return "\<Esc>"
301    endif
302    return ":call Select()\<CR>"
303  endfunc
304  func Select()
305    call cursor([g:lnum1, g:col1])
306    exe "normal! 1 ". (strlen(g:m) == 2 ? 'v' : g:m[2])
307    call cursor([g:lnum2, g:col2])
308    execute "normal! \<BS>"
309  endfunc
310  new
311  onoremap <buffer><expr> i- GetCommand()
312  " 1) default omap mapping
313  %d_
314  call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
315  call cursor(2, 1)
316  norm di-
317  call assert_equal('no', g:m)
318  call assert_equal(['aaa -- eee'], getline(1, '$'))
319  " 2) forced characterwise operation
320  %d_
321  call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
322  call cursor(2, 1)
323  norm dvi-
324  call assert_equal('nov', g:m)
325  call assert_equal(['aaa -- eee'], getline(1, '$'))
326  " 3) forced linewise operation
327  %d_
328  call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
329  call cursor(2, 1)
330  norm dVi-
331  call assert_equal('noV', g:m)
332  call assert_equal([''], getline(1, '$'))
333  " 4) forced blockwise operation
334  %d_
335  call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
336  call cursor(2, 1)
337  exe "norm d\<C-V>i-"
338  call assert_equal("no\<C-V>", g:m)
339  call assert_equal(['aaabbb', 'x', 'dddeee'], getline(1, '$'))
340  bwipe!
341  delfunc Select
342  delfunc GetCommand
343endfunc
344