blob: 61a1edd4ad978fc739ef7c6903db8557b236b697 [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
4
Bram Moolenaar2d1a2482016-08-14 15:32:11 +02005func 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()
Bram Moolenaar920694c2016-08-21 17:45:02 +020036 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
Bram Moolenaarda9ce2c2016-09-02 19:34:10 +020073 " 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
Bram Moolenaar920694c2016-08-21 17:45:02 +020081 " 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
Bram Moolenaar2d1a2482016-08-14 15:32:11 +020086 call feedkeys("Go+\<Esc>", "xt")
87 call assert_equal('+', getline('$'))
88
Bram Moolenaar920694c2016-08-21 17:45:02 +020089 " 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
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200108 call feedkeys(":call append(line('$'), '+')\<CR>", "xt")
109 call assert_equal('+', getline('$'))
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200110
Bram Moolenaare90858d2017-02-01 17:24:34 +0100111 iunmap a
112 iunmap c
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200113 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('$')))
Bram Moolenaare90858d2017-02-01 17:24:34 +0100123 nunmap .
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200124 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
Bram Moolenaar75bf3d22019-03-26 22:46:05 +0100143func 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
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200166" This isn't actually testing a mapping, but similar use of CTRL-G U as above.
167func Test_break_undo()
Bram Moolenaar75bf3d22019-03-26 22:46:05 +0100168 set whichwrap=<,>,[,]
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200169 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
Bram Moolenaar35a4cfa2016-08-14 16:07:48 +0200176
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
Bram Moolenaar878c2632017-04-01 15:15:52 +0200184
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
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200195
196func Test_map_timeout()
Bram Moolenaar26d98212019-01-27 22:32:55 +0100197 if !has('timers')
198 return
199 endif
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200200 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
Bram Moolenaar26d98212019-01-27 22:32:55 +0100209 let timer = timer_start(300, 'ExitInsert')
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200210 " 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
Bram Moolenaar26d98212019-01-27 22:32:55 +0100224 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)
Bram Moolenaar8d4ce562019-01-30 22:01:40 +0100241 let g:timer = timer_start(1, {-> feedkeys("3\<Esc>", 't')})
Bram Moolenaar26d98212019-01-27 22:32:55 +0100242 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
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200257endfunc
Bram Moolenaarc3c3e692018-04-26 22:30:33 +0200258
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
Bram Moolenaar5e3423d2018-05-13 18:36:27 +0200274
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
Bram Moolenaar5976f8f2018-12-27 23:44:44 +0100290
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