blob: bc5b487f2f17c5f8584bf2d608c396449e27e15e [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
Bram Moolenaar8c5a2782019-08-07 23:07:07 +02004source check.vim
Bram Moolenaar4ebe0e62019-11-22 20:55:40 +01005source screendump.vim
Bram Moolenaar957cf672020-11-12 14:21:06 +01006source term_util.vim
Bram Moolenaar62aec932022-01-29 21:45:34 +00007import './vim9.vim' as v9
Bram Moolenaar26d98212019-01-27 22:32:55 +01008
Bram Moolenaar2d1a2482016-08-14 15:32:11 +02009func Test_abbreviation()
10 " abbreviation with 0x80 should work
11 inoreab чкпр vim
12 call feedkeys("Goчкпр \<Esc>", "xt")
13 call assert_equal('vim ', getline('$'))
14 iunab чкпр
15 set nomodified
16endfunc
17
Bram Moolenaar8485be42019-04-23 16:36:05 +020018func Test_abclear()
19 abbrev foo foobar
20 iabbrev fooi foobari
21 cabbrev fooc foobarc
22 call assert_equal("\n\n"
23 \ .. "c fooc foobarc\n"
24 \ .. "i fooi foobari\n"
25 \ .. "! foo foobar", execute('abbrev'))
26
27 iabclear
28 call assert_equal("\n\n"
29 \ .. "c fooc foobarc\n"
30 \ .. "c foo foobar", execute('abbrev'))
31 abbrev foo foobar
32 iabbrev fooi foobari
33
34 cabclear
35 call assert_equal("\n\n"
36 \ .. "i fooi foobari\n"
37 \ .. "i foo foobar", execute('abbrev'))
38 abbrev foo foobar
39 cabbrev fooc foobarc
40
41 abclear
42 call assert_equal("\n\nNo abbreviation found", execute('abbrev'))
Bram Moolenaarf0cee192020-02-16 13:33:56 +010043 call assert_fails('%abclear', 'E481:')
Bram Moolenaar8485be42019-04-23 16:36:05 +020044endfunc
45
46func Test_abclear_buffer()
47 abbrev foo foobar
48 new X1
49 abbrev <buffer> foo1 foobar1
50 new X2
51 abbrev <buffer> foo2 foobar2
52
53 call assert_equal("\n\n"
54 \ .. "! foo2 @foobar2\n"
55 \ .. "! foo foobar", execute('abbrev'))
56
57 abclear <buffer>
58 call assert_equal("\n\n"
59 \ .. "! foo foobar", execute('abbrev'))
60
61 b X1
62 call assert_equal("\n\n"
63 \ .. "! foo1 @foobar1\n"
64 \ .. "! foo foobar", execute('abbrev'))
65 abclear <buffer>
66 call assert_equal("\n\n"
67 \ .. "! foo foobar", execute('abbrev'))
68
69 abclear
70 call assert_equal("\n\nNo abbreviation found", execute('abbrev'))
71
72 %bwipe
73endfunc
74
Bram Moolenaar2d1a2482016-08-14 15:32:11 +020075func Test_map_ctrl_c_insert()
76 " mapping of ctrl-c in Insert mode
77 set cpo-=< cpo-=k
78 inoremap <c-c> <ctrl-c>
79 cnoremap <c-c> dummy
80 cunmap <c-c>
Bram Moolenaarfccd93f2020-05-31 22:06:51 +020081 call feedkeys("GoTEST2: CTRL-C |\<*C-C>A|\<Esc>", "xt")
Bram Moolenaar2d1a2482016-08-14 15:32:11 +020082 call assert_equal('TEST2: CTRL-C |<ctrl-c>A|', getline('$'))
83 unmap! <c-c>
84 set nomodified
85endfunc
86
87func Test_map_ctrl_c_visual()
88 " mapping of ctrl-c in Visual mode
89 vnoremap <c-c> :<C-u>$put ='vmap works'
Bram Moolenaarfccd93f2020-05-31 22:06:51 +020090 call feedkeys("GV\<*C-C>\<CR>", "xt")
Bram Moolenaar2d1a2482016-08-14 15:32:11 +020091 call assert_equal('vmap works', getline('$'))
92 vunmap <c-c>
93 set nomodified
94endfunc
95
96func Test_map_langmap()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +020097 CheckFeature langmap
Bram Moolenaar920694c2016-08-21 17:45:02 +020098
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
Bram Moolenaarda9ce2c2016-09-02 19:34:10 +0200132 " 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
Bram Moolenaar920694c2016-08-21 17:45:02 +0200140 " 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
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200145 call feedkeys("Go+\<Esc>", "xt")
146 call assert_equal('+', getline('$'))
147
Bram Moolenaar920694c2016-08-21 17:45:02 +0200148 " 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
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200167 call feedkeys(":call append(line('$'), '+')\<CR>", "xt")
168 call assert_equal('+', getline('$'))
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200169
Bram Moolenaare90858d2017-02-01 17:24:34 +0100170 iunmap a
171 iunmap c
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200172 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('$')))
Bram Moolenaare90858d2017-02-01 17:24:34 +0100182 nunmap .
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200183 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
Bram Moolenaar75bf3d22019-03-26 22:46:05 +0100202func 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
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200225" This isn't actually testing a mapping, but similar use of CTRL-G U as above.
226func Test_break_undo()
Bram Moolenaar75bf3d22019-03-26 22:46:05 +0100227 set whichwrap=<,>,[,]
Bram Moolenaar2d1a2482016-08-14 15:32:11 +0200228 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
Bram Moolenaar35a4cfa2016-08-14 16:07:48 +0200235
236func Test_map_meta_quotes()
237 imap <M-"> foo
Bram Moolenaarfccd93f2020-05-31 22:06:51 +0200238 call feedkeys("Go-\<*M-\">-\<Esc>", "xt")
Bram Moolenaar35a4cfa2016-08-14 16:07:48 +0200239 call assert_equal("-foo-", getline('$'))
240 set nomodified
241 iunmap <M-">
242endfunc
Bram Moolenaar878c2632017-04-01 15:15:52 +0200243
Bram Moolenaarc8fd33d2019-08-16 20:33:05 +0200244func Test_map_meta_multibyte()
245 imap <M-á> foo
Bram Moolenaar2f710af2019-08-16 20:56:03 +0200246 call assert_match('i <M-á>\s*foo', execute('imap'))
Bram Moolenaarc8fd33d2019-08-16 20:33:05 +0200247 iunmap <M-á>
248endfunc
249
Bram Moolenaar878c2632017-04-01 15:15:52 +0200250func 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
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200260
261func Test_map_timeout()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200262 CheckFeature timers
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200263 nnoremap aaaa :let got_aaaa = 1<CR>
264 nnoremap bb :let got_bb = 1<CR>
265 nmap b aaa
266 new
267 func ExitInsert(timer)
268 let g:line = getline(1)
269 call feedkeys("\<Esc>", "t")
270 endfunc
271 set timeout timeoutlen=200
Bram Moolenaar26d98212019-01-27 22:32:55 +0100272 let timer = timer_start(300, 'ExitInsert')
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200273 " After the 'b' Vim waits for another character to see if it matches 'bb'.
274 " When it times out it is expanded to "aaa", but there is no wait for
275 " "aaaa". Can't check that reliably though.
276 call feedkeys("b", "xt!")
277 call assert_equal("aa", g:line)
278 call assert_false(exists('got_aaa'))
279 call assert_false(exists('got_bb'))
280
281 bwipe!
282 nunmap aaaa
283 nunmap bb
284 nunmap b
285 set timeoutlen&
286 delfunc ExitInsert
Bram Moolenaar26d98212019-01-27 22:32:55 +0100287 call timer_stop(timer)
288endfunc
289
290func Test_map_timeout_with_timer_interrupt()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200291 CheckFeature job
292 CheckFeature timers
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +0100293 let g:test_is_flaky = 1
Bram Moolenaar26d98212019-01-27 22:32:55 +0100294
295 " Confirm the timer invoked in exit_cb of the job doesn't disturb mapped key
296 " sequence.
297 new
298 let g:val = 0
299 nnoremap \12 :let g:val = 1<CR>
300 nnoremap \123 :let g:val = 2<CR>
Bram Moolenaarea94c852019-08-16 21:47:27 +0200301 set timeout timeoutlen=200
Bram Moolenaar26d98212019-01-27 22:32:55 +0100302
303 func ExitCb(job, status)
Bram Moolenaar8d4ce562019-01-30 22:01:40 +0100304 let g:timer = timer_start(1, {-> feedkeys("3\<Esc>", 't')})
Bram Moolenaar26d98212019-01-27 22:32:55 +0100305 endfunc
306
307 call job_start([&shell, &shellcmdflag, 'echo'], {'exit_cb': 'ExitCb'})
308 call feedkeys('\12', 'xt!')
309 call assert_equal(2, g:val)
310
311 bwipe!
312 nunmap \12
313 nunmap \123
314 set timeoutlen&
315 call WaitFor({-> exists('g:timer')})
316 call timer_stop(g:timer)
317 unlet g:timer
318 unlet g:val
319 delfunc ExitCb
Bram Moolenaarb7637c42017-04-23 18:49:36 +0200320endfunc
Bram Moolenaarc3c3e692018-04-26 22:30:33 +0200321
322func Test_abbreviation_CR()
323 new
324 func Eatchar(pat)
325 let c = nr2char(getchar(0))
326 return (c =~ a:pat) ? '' : c
327 endfunc
328 iabbrev <buffer><silent> ~~7 <c-r>=repeat('~', 7)<CR><c-r>=Eatchar('\s')<cr>
329 call feedkeys("GA~~7 \<esc>", 'xt')
330 call assert_equal('~~~~~~~', getline('$'))
331 %d
332 call feedkeys("GA~~7\<cr>\<esc>", 'xt')
333 call assert_equal(['~~~~~~~', ''], getline(1,'$'))
334 delfunc Eatchar
335 bw!
336endfunc
Bram Moolenaar5e3423d2018-05-13 18:36:27 +0200337
338func Test_cabbr_visual_mode()
339 cabbr s su
340 call feedkeys(":s \<c-B>\"\<CR>", 'itx')
341 call assert_equal('"su ', getreg(':'))
342 call feedkeys(":'<,'>s \<c-B>\"\<CR>", 'itx')
343 let expected = '"'. "'<,'>su "
344 call assert_equal(expected, getreg(':'))
345 call feedkeys(": '<,'>s \<c-B>\"\<CR>", 'itx')
346 let expected = '" '. "'<,'>su "
347 call assert_equal(expected, getreg(':'))
348 call feedkeys(":'a,'bs \<c-B>\"\<CR>", 'itx')
349 let expected = '"'. "'a,'bsu "
350 call assert_equal(expected, getreg(':'))
351 cunabbr s
352endfunc
Bram Moolenaar5976f8f2018-12-27 23:44:44 +0100353
354func Test_motionforce_omap()
355 func GetCommand()
356 let g:m=mode(1)
357 let [g:lnum1, g:col1] = searchpos('-', 'Wb')
358 if g:lnum1 == 0
359 return "\<Esc>"
360 endif
361 let [g:lnum2, g:col2] = searchpos('-', 'W')
362 if g:lnum2 == 0
363 return "\<Esc>"
364 endif
365 return ":call Select()\<CR>"
366 endfunc
367 func Select()
368 call cursor([g:lnum1, g:col1])
369 exe "normal! 1 ". (strlen(g:m) == 2 ? 'v' : g:m[2])
370 call cursor([g:lnum2, g:col2])
371 execute "normal! \<BS>"
372 endfunc
373 new
374 onoremap <buffer><expr> i- GetCommand()
375 " 1) default omap mapping
376 %d_
377 call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
378 call cursor(2, 1)
379 norm di-
380 call assert_equal('no', g:m)
381 call assert_equal(['aaa -- eee'], getline(1, '$'))
382 " 2) forced characterwise operation
383 %d_
384 call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
385 call cursor(2, 1)
386 norm dvi-
387 call assert_equal('nov', g:m)
388 call assert_equal(['aaa -- eee'], getline(1, '$'))
389 " 3) forced linewise operation
390 %d_
391 call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
392 call cursor(2, 1)
393 norm dVi-
394 call assert_equal('noV', g:m)
395 call assert_equal([''], getline(1, '$'))
396 " 4) forced blockwise operation
397 %d_
398 call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
399 call cursor(2, 1)
400 exe "norm d\<C-V>i-"
401 call assert_equal("no\<C-V>", g:m)
402 call assert_equal(['aaabbb', 'x', 'dddeee'], getline(1, '$'))
403 bwipe!
404 delfunc Select
405 delfunc GetCommand
406endfunc
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200407
408func Test_error_in_map_expr()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200409 " Unlike CheckRunVimInTerminal this does work in a win32 console
410 CheckFeature terminal
411 if has('win32') && has('gui_running')
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200412 throw 'Skipped: cannot run Vim in a terminal window'
413 endif
414
415 let lines =<< trim [CODE]
416 func Func()
417 " fail to create list
418 let x = [
419 endfunc
420 nmap <expr> ! Func()
421 set updatetime=50
422 [CODE]
423 call writefile(lines, 'Xtest.vim')
424
Bram Moolenaar0d702022019-07-04 14:20:41 +0200425 let buf = term_start(GetVimCommandCleanTerm() .. ' -S Xtest.vim', {'term_rows': 8})
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200426 let job = term_getjob(buf)
427 call WaitForAssert({-> assert_notequal('', term_getline(buf, 8))})
428
429 " GC must not run during map-expr processing, which can make Vim crash.
430 call term_sendkeys(buf, '!')
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200431 call TermWait(buf, 50)
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200432 call term_sendkeys(buf, "\<CR>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200433 call TermWait(buf, 50)
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200434 call assert_equal('run', job_status(job))
435
436 call term_sendkeys(buf, ":qall!\<CR>")
437 call WaitFor({-> job_status(job) ==# 'dead'})
438 if has('unix')
439 call assert_equal('', job_info(job).termsig)
440 endif
441
442 call delete('Xtest.vim')
443 exe buf .. 'bwipe!'
444endfunc
Bram Moolenaarfafb4b12019-10-16 18:34:57 +0200445
446func Test_list_mappings()
Bram Moolenaar2559a472019-10-16 23:33:12 +0200447 " Remove default mappings
448 imapclear
Bram Moolenaar4f2f61a2019-10-16 22:27:49 +0200449
Bram Moolenaare3d1f4c2021-04-06 20:21:59 +0200450 " reset 'isident' to check it isn't used
451 set isident=
452 inoremap <C-m> CtrlM
Bram Moolenaarfafb4b12019-10-16 18:34:57 +0200453 inoremap <A-S> AltS
454 inoremap <S-/> ShiftSlash
Bram Moolenaare3d1f4c2021-04-06 20:21:59 +0200455 set isident&
Bram Moolenaarfafb4b12019-10-16 18:34:57 +0200456 call assert_equal([
457 \ 'i <S-/> * ShiftSlash',
458 \ 'i <M-S> * AltS',
459 \ 'i <C-M> * CtrlM',
460 \], execute('imap')->trim()->split("\n"))
461 iunmap <C-M>
462 iunmap <A-S>
463 call assert_equal(['i <S-/> * ShiftSlash'], execute('imap')->trim()->split("\n"))
464 iunmap <S-/>
465 call assert_equal(['No mapping found'], execute('imap')->trim()->split("\n"))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100466
467 " List global, buffer local and script local mappings
468 nmap ,f /^\k\+ (<CR>
469 nmap <buffer> ,f /^\k\+ (<CR>
470 nmap <script> ,fs /^\k\+ (<CR>
471 call assert_equal(['n ,f @/^\k\+ (<CR>',
472 \ 'n ,fs & /^\k\+ (<CR>',
473 \ 'n ,f /^\k\+ (<CR>'],
474 \ execute('nmap ,f')->trim()->split("\n"))
475
476 " List <Nop> mapping
477 nmap ,n <Nop>
478 call assert_equal(['n ,n <Nop>'],
479 \ execute('nmap ,n')->trim()->split("\n"))
480
Bram Moolenaar7f51bbe2020-01-24 20:21:19 +0100481 " verbose map
482 call assert_match("\tLast set from .*/test_mapping.vim line \\d\\+$",
483 \ execute('verbose map ,n')->trim()->split("\n")[1])
484
zeertzjqac402f42022-05-04 18:51:43 +0100485 " character with K_SPECIAL byte in rhs
486 nmap foo
487 call assert_equal(['n foo …'],
488 \ execute('nmap foo')->trim()->split("\n"))
489
490 " modified character with K_SPECIAL byte in rhs
491 nmap foo <M-…>
492 call assert_equal(['n foo <M-…>'],
493 \ execute('nmap foo')->trim()->split("\n"))
494
495 " character with K_SPECIAL byte in lhs
496 nmap foo
497 call assert_equal(['n … foo'],
498 \ execute('nmap …')->trim()->split("\n"))
499
500 " modified character with K_SPECIAL byte in lhs
501 nmap <M-…> foo
502 call assert_equal(['n <M-…> foo'],
503 \ execute('nmap <M-…>')->trim()->split("\n"))
504
zeertzjq0519ce02022-05-09 12:16:19 +0100505 " illegal bytes
506 let str = ":\x7f:\x80:\x90:\xd0:"
507 exe 'nmap foo ' .. str
508 call assert_equal(['n foo ' .. strtrans(str)],
509 \ execute('nmap foo')->trim()->split("\n"))
510 unlet str
511
Bram Moolenaar7f51bbe2020-01-24 20:21:19 +0100512 " map to CTRL-V
513 exe "nmap ,k \<C-V>"
514 call assert_equal(['n ,k <Nop>'],
515 \ execute('nmap ,k')->trim()->split("\n"))
516
Yegappan Lakshmanan2d6d7182021-06-13 21:52:48 +0200517 " map with space at the beginning
518 exe "nmap \<C-V> w <Nop>"
519 call assert_equal(['n <Space>w <Nop>'],
520 \ execute("nmap \<C-V> w")->trim()->split("\n"))
521
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100522 nmapclear
Bram Moolenaarfafb4b12019-10-16 18:34:57 +0200523endfunc
Bram Moolenaar4ebe0e62019-11-22 20:55:40 +0100524
Bram Moolenaar18b7d862021-03-17 13:28:05 +0100525func Test_expr_map_gets_cursor()
526 new
527 call setline(1, ['one', 'some w!rd'])
528 func StoreColumn()
529 let g:exprLine = line('.')
530 let g:exprCol = col('.')
531 return 'x'
532 endfunc
533 nnoremap <expr> x StoreColumn()
534 2
535 nmap ! f!<Ignore>x
536 call feedkeys("!", 'xt')
537 call assert_equal('some wrd', getline(2))
538 call assert_equal(2, g:exprLine)
539 call assert_equal(7, g:exprCol)
540
541 bwipe!
542 unlet g:exprLine
543 unlet g:exprCol
Bram Moolenaar6ccfd992021-03-17 13:39:33 +0100544 delfunc StoreColumn
Bram Moolenaar18b7d862021-03-17 13:28:05 +0100545 nunmap x
546 nunmap !
547endfunc
548
Bram Moolenaar4ebe0e62019-11-22 20:55:40 +0100549func Test_expr_map_restore_cursor()
550 CheckScreendump
551
552 let lines =<< trim END
553 call setline(1, ['one', 'two', 'three'])
554 2
555 set ls=2
556 hi! link StatusLine ErrorMsg
557 noremap <expr> <C-B> Func()
558 func Func()
559 let g:on = !get(g:, 'on', 0)
560 redraws
561 return ''
562 endfunc
563 func Status()
564 return get(g:, 'on', 0) ? '[on]' : ''
565 endfunc
566 set stl=%{Status()}
567 END
568 call writefile(lines, 'XtestExprMap')
569 let buf = RunVimInTerminal('-S XtestExprMap', #{rows: 10})
Bram Moolenaar4ebe0e62019-11-22 20:55:40 +0100570 call term_sendkeys(buf, "\<C-B>")
571 call VerifyScreenDump(buf, 'Test_map_expr_1', {})
572
573 " clean up
574 call StopVimInTerminal(buf)
575 call delete('XtestExprMap')
576endfunc
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100577
Bram Moolenaard288eaa2022-02-16 18:27:55 +0000578func Test_map_listing()
579 CheckScreendump
580
581 let lines =<< trim END
582 nmap a b
583 END
584 call writefile(lines, 'XtestMapList')
585 let buf = RunVimInTerminal('-S XtestMapList', #{rows: 6})
586 call term_sendkeys(buf, ": nmap a\<CR>")
587 call VerifyScreenDump(buf, 'Test_map_list_1', {})
588
589 " clean up
590 call StopVimInTerminal(buf)
591 call delete('XtestMapList')
592endfunc
593
Bram Moolenaar74a0a5b2022-02-10 14:07:41 +0000594func Test_expr_map_error()
595 CheckScreendump
596
597 let lines =<< trim END
598 func Func()
599 throw 'test'
600 return ''
601 endfunc
602
603 nnoremap <expr> <F2> Func()
604 cnoremap <expr> <F2> Func()
605
606 call test_override('ui_delay', 10)
607 END
608 call writefile(lines, 'XtestExprMap')
609 let buf = RunVimInTerminal('-S XtestExprMap', #{rows: 10})
Bram Moolenaar74a0a5b2022-02-10 14:07:41 +0000610 call term_sendkeys(buf, "\<F2>")
611 call TermWait(buf)
612 call term_sendkeys(buf, "\<CR>")
613 call VerifyScreenDump(buf, 'Test_map_expr_2', {})
614
615 call term_sendkeys(buf, ":abc\<F2>")
616 call VerifyScreenDump(buf, 'Test_map_expr_3', {})
617 call term_sendkeys(buf, "\<Esc>0")
618 call VerifyScreenDump(buf, 'Test_map_expr_4', {})
619
620 " clean up
621 call StopVimInTerminal(buf)
622 call delete('XtestExprMap')
623endfunc
624
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100625" Test for mapping errors
626func Test_map_error()
627 call assert_fails('unmap', 'E474:')
628 call assert_fails("exe 'map ' .. repeat('a', 51) .. ' :ls'", 'E474:')
629 call assert_fails('unmap abc', 'E31:')
630 call assert_fails('unabbr abc', 'E24:')
631 call assert_equal('', maparg(''))
632 call assert_fails('echo maparg("abc", [])', 'E730:')
633
634 " unique map
635 map ,w /[#&!]<CR>
636 call assert_fails("map <unique> ,w /[#&!]<CR>", 'E227:')
637 " unique buffer-local map
638 call assert_fails("map <buffer> <unique> ,w /[.,;]<CR>", 'E225:')
639 unmap ,w
640
641 " unique abbreviation
642 abbr SP special
643 call assert_fails("abbr <unique> SP special", 'E226:')
644 " unique buffer-local map
645 call assert_fails("abbr <buffer> <unique> SP special", 'E224:')
646 unabbr SP
647
648 call assert_fails('mapclear abc', 'E474:')
649 call assert_fails('abclear abc', 'E474:')
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100650 call assert_fails('abbr $xyz abc', 'E474:')
651
652 " space character in an abbreviation
653 call assert_fails('abbr ab<space> ABC', 'E474:')
654
655 " invalid <expr> map
656 map <expr> ,f abc
657 call assert_fails('normal ,f', 'E121:')
658 unmap <expr> ,f
Bram Moolenaar9f6277b2020-02-11 22:04:02 +0100659
660 " Recursive use of :normal in a map
661 set maxmapdepth=100
662 map gq :normal gq<CR>
663 call assert_fails('normal gq', 'E192:')
664 unmap gq
665 set maxmapdepth&
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100666endfunc
667
668" Test for <special> key mapping
669func Test_map_special()
670 new
671 let old_cpo = &cpo
672 set cpo+=<
673 imap <F12> Blue
674 call feedkeys("i\<F12>", "x")
675 call assert_equal("<F12>", getline(1))
676 call feedkeys("ddi<F12>", "x")
677 call assert_equal("Blue", getline(1))
678 iunmap <F12>
679 imap <special> <F12> Green
680 call feedkeys("ddi\<F12>", "x")
681 call assert_equal("Green", getline(1))
682 call feedkeys("ddi<F12>", "x")
683 call assert_equal("<F12>", getline(1))
684 iunmap <special> <F12>
685 let &cpo = old_cpo
686 %bwipe!
687endfunc
688
689" Test for hasmapto()
690func Test_hasmapto()
691 call assert_equal(0, hasmapto('/^\k\+ ('))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100692 map ,f /^\k\+ (<CR>
693 call assert_equal(1, hasmapto('/^\k\+ ('))
694 unmap ,f
695
696 " Insert mode mapping
697 call assert_equal(0, hasmapto('/^\k\+ (', 'i'))
698 imap ,f /^\k\+ (<CR>
699 call assert_equal(1, hasmapto('/^\k\+ (', 'i'))
700 iunmap ,f
701
702 " Normal mode mapping
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100703 call assert_equal(0, hasmapto('/^\k\+ (', 'n'))
704 nmap ,f /^\k\+ (<CR>
705 call assert_equal(1, hasmapto('/^\k\+ ('))
706 call assert_equal(1, hasmapto('/^\k\+ (', 'n'))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100707 nunmap ,f
708
709 " Visual and Select mode mapping
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100710 call assert_equal(0, hasmapto('/^\k\+ (', 'v'))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100711 call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
712 call assert_equal(0, hasmapto('/^\k\+ (', 's'))
713 vmap ,f /^\k\+ (<CR>
714 call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
715 call assert_equal(1, hasmapto('/^\k\+ (', 'x'))
716 call assert_equal(1, hasmapto('/^\k\+ (', 's'))
717 vunmap ,f
718
719 " Visual mode mapping
720 call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
721 xmap ,f /^\k\+ (<CR>
722 call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
723 call assert_equal(1, hasmapto('/^\k\+ (', 'x'))
724 call assert_equal(0, hasmapto('/^\k\+ (', 's'))
725 xunmap ,f
726
727 " Select mode mapping
728 call assert_equal(0, hasmapto('/^\k\+ (', 's'))
729 smap ,f /^\k\+ (<CR>
730 call assert_equal(1, hasmapto('/^\k\+ (', 'v'))
731 call assert_equal(0, hasmapto('/^\k\+ (', 'x'))
732 call assert_equal(1, hasmapto('/^\k\+ (', 's'))
733 sunmap ,f
734
735 " Operator-pending mode mapping
736 call assert_equal(0, hasmapto('/^\k\+ (', 'o'))
737 omap ,f /^\k\+ (<CR>
738 call assert_equal(1, hasmapto('/^\k\+ (', 'o'))
739 ounmap ,f
740
741 " Language mapping
742 call assert_equal(0, hasmapto('/^\k\+ (', 'l'))
743 lmap ,f /^\k\+ (<CR>
744 call assert_equal(1, hasmapto('/^\k\+ (', 'l'))
745 lunmap ,f
746
747 " Cmdline mode mapping
748 call assert_equal(0, hasmapto('/^\k\+ (', 'c'))
749 cmap ,f /^\k\+ (<CR>
750 call assert_equal(1, hasmapto('/^\k\+ (', 'c'))
751 cunmap ,f
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100752
753 call assert_equal(0, hasmapto('/^\k\+ (', 'n', 1))
754endfunc
755
756" Test for command-line completion of maps
757func Test_mapcomplete()
758 call assert_equal(['<buffer>', '<expr>', '<nowait>', '<script>',
759 \ '<silent>', '<special>', '<unique>'],
760 \ getcompletion('', 'mapping'))
761 call assert_equal([], getcompletion(',d', 'mapping'))
762
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100763 call feedkeys(":unmap <buf\<C-A>\<C-B>\"\<CR>", 'tx')
764 call assert_equal('"unmap <buffer>', @:)
765
766 call feedkeys(":unabbr <buf\<C-A>\<C-B>\"\<CR>", 'tx')
767 call assert_equal('"unabbr <buffer>', @:)
768
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100769 call feedkeys(":abbr! \<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100770 call assert_equal("\"abbr! \x01", @:)
771
772 " Multiple matches for a map
773 nmap ,f /H<CR>
774 omap ,f /H<CR>
775 call feedkeys(":map ,\<C-A>\<C-B>\"\<CR>", 'tx')
776 call assert_equal('"map ,f', @:)
777 mapclear
778endfunc
779
Bram Moolenaar94075b22022-01-18 20:30:39 +0000780func GetAbbrText()
781 unabbr hola
782 return 'hello'
783endfunc
784
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100785" Test for <expr> in abbreviation
786func Test_expr_abbr()
787 new
788 iabbr <expr> teh "the"
789 call feedkeys("iteh ", "tx")
790 call assert_equal('the ', getline(1))
791 iabclear
792 call setline(1, '')
793
794 " invalid <expr> abbreviation
795 abbr <expr> hte GetAbbr()
796 call assert_fails('normal ihte ', 'E117:')
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100797 call assert_equal('', getline(1))
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100798 unabbr <expr> hte
799
Bram Moolenaar94075b22022-01-18 20:30:39 +0000800 " evaluating the expression deletes the abbreviation
801 abbr <expr> hola GetAbbrText()
802 call assert_equal('GetAbbrText()', maparg('hola', 'i', '1'))
803 call feedkeys("ahola \<Esc>", 'xt')
804 call assert_equal('hello ', getline('.'))
805 call assert_equal('', maparg('hola', 'i', '1'))
806
807 bwipe!
Bram Moolenaarc2a60ae2020-01-23 16:19:54 +0100808endfunc
809
810" Test for storing mappings in different modes in a vimrc file
811func Test_mkvimrc_mapmodes()
812 map a1 /a1
813 nmap a2 /a2
814 vmap a3 /a3
815 smap a4 /a4
816 xmap a5 /a5
817 omap a6 /a6
818 map! a7 /a7
819 imap a8 /a8
820 lmap a9 /a9
821 cmap a10 /a10
822 tmap a11 /a11
823 " Normal + Visual map
824 map a12 /a12
825 sunmap a12
826 ounmap a12
827 " Normal + Selectmode map
828 map a13 /a13
829 xunmap a13
830 ounmap a13
831 " Normal + OpPending map
832 map a14 /a14
833 vunmap a14
834 " Visual + Selectmode map
835 map a15 /a15
836 nunmap a15
837 ounmap a15
838 " Visual + OpPending map
839 map a16 /a16
840 nunmap a16
841 sunmap a16
842 " Selectmode + OpPending map
843 map a17 /a17
844 nunmap a17
845 xunmap a17
846 " Normal + Visual + Selectmode map
847 map a18 /a18
848 ounmap a18
849 " Normal + Visual + OpPending map
850 map a19 /a19
851 sunmap a19
852 " Normal + Selectmode + OpPending map
853 map a20 /a20
854 xunmap a20
855 " Visual + Selectmode + OpPending map
856 map a21 /a21
857 nunmap a21
858 " Mapping to Nop
859 map a22 <Nop>
860 " Script local mapping
861 map <script> a23 /a23
862
863 " Newline in {lhs} and {rhs} of a map
864 exe "map a24\<C-V>\<C-J> ia24\<C-V>\<C-J><Esc>"
865
866 " Abbreviation
867 abbr a25 A25
868 cabbr a26 A26
869 iabbr a27 A27
870
871 mkvimrc! Xvimrc
872 let l = readfile('Xvimrc')
873 call assert_equal(['map a1 /a1'], filter(copy(l), 'v:val =~ " a1 "'))
874 call assert_equal(['nmap a2 /a2'], filter(copy(l), 'v:val =~ " a2 "'))
875 call assert_equal(['vmap a3 /a3'], filter(copy(l), 'v:val =~ " a3 "'))
876 call assert_equal(['smap a4 /a4'], filter(copy(l), 'v:val =~ " a4 "'))
877 call assert_equal(['xmap a5 /a5'], filter(copy(l), 'v:val =~ " a5 "'))
878 call assert_equal(['omap a6 /a6'], filter(copy(l), 'v:val =~ " a6 "'))
879 call assert_equal(['map! a7 /a7'], filter(copy(l), 'v:val =~ " a7 "'))
880 call assert_equal(['imap a8 /a8'], filter(copy(l), 'v:val =~ " a8 "'))
881 call assert_equal(['lmap a9 /a9'], filter(copy(l), 'v:val =~ " a9 "'))
882 call assert_equal(['cmap a10 /a10'], filter(copy(l), 'v:val =~ " a10 "'))
883 call assert_equal(['tmap a11 /a11'], filter(copy(l), 'v:val =~ " a11 "'))
884 call assert_equal(['nmap a12 /a12', 'xmap a12 /a12'],
885 \ filter(copy(l), 'v:val =~ " a12 "'))
886 call assert_equal(['nmap a13 /a13', 'smap a13 /a13'],
887 \ filter(copy(l), 'v:val =~ " a13 "'))
888 call assert_equal(['nmap a14 /a14', 'omap a14 /a14'],
889 \ filter(copy(l), 'v:val =~ " a14 "'))
890 call assert_equal(['vmap a15 /a15'], filter(copy(l), 'v:val =~ " a15 "'))
891 call assert_equal(['xmap a16 /a16', 'omap a16 /a16'],
892 \ filter(copy(l), 'v:val =~ " a16 "'))
893 call assert_equal(['smap a17 /a17', 'omap a17 /a17'],
894 \ filter(copy(l), 'v:val =~ " a17 "'))
895 call assert_equal(['nmap a18 /a18', 'vmap a18 /a18'],
896 \ filter(copy(l), 'v:val =~ " a18 "'))
897 call assert_equal(['nmap a19 /a19', 'xmap a19 /a19', 'omap a19 /a19'],
898 \ filter(copy(l), 'v:val =~ " a19 "'))
899 call assert_equal(['nmap a20 /a20', 'smap a20 /a20', 'omap a20 /a20'],
900 \ filter(copy(l), 'v:val =~ " a20 "'))
901 call assert_equal(['vmap a21 /a21', 'omap a21 /a21'],
902 \ filter(copy(l), 'v:val =~ " a21 "'))
903 call assert_equal(['map a22 <Nop>'], filter(copy(l), 'v:val =~ " a22 "'))
904 call assert_equal([], filter(copy(l), 'v:val =~ " a23 "'))
905 call assert_equal(["map a24<NL> ia24<NL>\x16\e"],
906 \ filter(copy(l), 'v:val =~ " a24"'))
907
908 call assert_equal(['abbr a25 A25'], filter(copy(l), 'v:val =~ " a25 "'))
909 call assert_equal(['cabbr a26 A26'], filter(copy(l), 'v:val =~ " a26 "'))
910 call assert_equal(['iabbr a27 A27'], filter(copy(l), 'v:val =~ " a27 "'))
911 call delete('Xvimrc')
912
913 mapclear
914 nmapclear
915 vmapclear
916 xmapclear
917 smapclear
918 omapclear
919 imapclear
920 lmapclear
921 cmapclear
922 tmapclear
923endfunc
924
925" Test for recursive mapping ('maxmapdepth')
926func Test_map_recursive()
927 map x y
928 map y x
929 call assert_fails('normal x', 'E223:')
930 unmap x
931 unmap y
932endfunc
933
934" Test for removing an abbreviation using {rhs} and with space after {lhs}
935func Test_abbr_remove()
936 abbr foo bar
937 let d = maparg('foo', 'i', 1, 1)
938 call assert_equal(['foo', 'bar', '!'], [d.lhs, d.rhs, d.mode])
939 unabbr bar
940 call assert_equal({}, maparg('foo', 'i', 1, 1))
941
942 abbr foo bar
943 unabbr foo<space><tab>
944 call assert_equal({}, maparg('foo', 'i', 1, 1))
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +0100945endfunc
946
Bram Moolenaar7f51bbe2020-01-24 20:21:19 +0100947" Trigger an abbreviation using a special key
948func Test_abbr_trigger_special()
949 new
950 iabbr teh the
951 call feedkeys("iteh\<F2>\<Esc>", 'xt')
952 call assert_equal('the<F2>', getline(1))
953 iunab teh
954 close!
955endfunc
956
957" Test for '<' in 'cpoptions'
958func Test_map_cpo_special_keycode()
959 set cpo-=<
960 imap x<Bslash>k Test
961 let d = maparg('x<Bslash>k', 'i', 0, 1)
962 call assert_equal(['x\k', 'Test', 'i'], [d.lhs, d.rhs, d.mode])
963 call feedkeys(":imap x\<C-A>\<C-B>\"\<CR>", 'tx')
964 call assert_equal('"imap x\k', @:)
965 iunmap x<Bslash>k
966 set cpo+=<
967 imap x<Bslash>k Test
968 let d = maparg('x<Bslash>k', 'i', 0, 1)
969 call assert_equal(['x<Bslash>k', 'Test', 'i'], [d.lhs, d.rhs, d.mode])
970 call feedkeys(":imap x\<C-A>\<C-B>\"\<CR>", 'tx')
971 call assert_equal('"imap x<Bslash>k', @:)
972 iunmap x<Bslash>k
973 set cpo-=<
974 " Modifying 'cpo' above adds some default mappings, remove them
975 mapclear
976 mapclear!
977endfunc
978
Bram Moolenaar957cf672020-11-12 14:21:06 +0100979" Test for <Cmd> key in maps to execute commands
980func Test_map_cmdkey()
981 new
982
983 " Error cases
984 let x = 0
985 noremap <F3> <Cmd><Cmd>let x = 1<CR>
986 call assert_fails('call feedkeys("\<F3>", "xt")', 'E1136:')
987 call assert_equal(0, x)
988
989 noremap <F3> <Cmd><F3>let x = 2<CR>
990 call assert_fails('call feedkeys("\<F3>", "xt")', 'E1137:')
991 call assert_equal(0, x)
992
993 noremap <F3> <Cmd>let x = 3
Bram Moolenaar806da512021-12-24 19:54:52 +0000994 call assert_fails('call feedkeys("\<F3>", "xt!")', 'E1255:')
Bram Moolenaar957cf672020-11-12 14:21:06 +0100995 call assert_equal(0, x)
996
997 " works in various modes and sees the correct mode()
998 noremap <F3> <Cmd>let m = mode(1)<CR>
999 noremap! <F3> <Cmd>let m = mode(1)<CR>
1000
1001 " normal mode
1002 call feedkeys("\<F3>", 'xt')
1003 call assert_equal('n', m)
1004
1005 " visual mode
1006 call feedkeys("v\<F3>", 'xt!')
1007 call assert_equal('v', m)
1008 " shouldn't leave the visual mode
1009 call assert_equal('v', mode(1))
1010 call feedkeys("\<Esc>", 'xt')
1011 call assert_equal('n', mode(1))
1012
1013 " visual mapping in select mode
1014 call feedkeys("gh\<F3>", 'xt!')
1015 call assert_equal('v', m)
1016 " shouldn't leave select mode
1017 call assert_equal('s', mode(1))
1018 call feedkeys("\<Esc>", 'xt')
1019 call assert_equal('n', mode(1))
1020
1021 " select mode mapping
1022 snoremap <F3> <Cmd>let m = mode(1)<cr>
1023 call feedkeys("gh\<F3>", 'xt!')
1024 call assert_equal('s', m)
1025 " shouldn't leave select mode
1026 call assert_equal('s', mode(1))
1027 call feedkeys("\<Esc>", 'xt')
1028 call assert_equal('n', mode(1))
1029
1030 " operator-pending mode
1031 call feedkeys("d\<F3>", 'xt!')
1032 call assert_equal('no', m)
1033 " leaves the operator-pending mode
1034 call assert_equal('n', mode(1))
1035
1036 " insert mode
1037 call feedkeys("i\<F3>abc", 'xt')
1038 call assert_equal('i', m)
1039 call assert_equal('abc', getline('.'))
1040
1041 " replace mode
1042 call feedkeys("0R\<F3>two", 'xt')
1043 call assert_equal('R', m)
1044 call assert_equal('two', getline('.'))
1045
1046 " virtual replace mode
1047 call setline('.', "one\ttwo")
1048 call feedkeys("4|gR\<F3>xxx", 'xt')
1049 call assert_equal('Rv', m)
1050 call assert_equal("onexxx\ttwo", getline('.'))
1051
1052 " cmdline mode
1053 call feedkeys(":\<F3>\"xxx\<CR>", 'xt!')
1054 call assert_equal('c', m)
1055 call assert_equal('"xxx', @:)
1056
1057 " terminal mode
1058 if CanRunVimInTerminal()
1059 tnoremap <F3> <Cmd>let m = mode(1)<CR>
1060 let buf = Run_shell_in_terminal({})
1061 call feedkeys("\<F3>", 'xt')
1062 call assert_equal('t', m)
1063 call assert_equal('t', mode(1))
1064 call StopShellInTerminal(buf)
Bram Moolenaar957cf672020-11-12 14:21:06 +01001065 close!
1066 tunmap <F3>
1067 endif
1068
1069 " invoke cmdline mode recursively
1070 noremap! <F2> <Cmd>norm! :foo<CR>
1071 %d
1072 call setline(1, ['some short lines', 'of test text'])
1073 call feedkeys(":bar\<F2>x\<C-B>\"\r", 'xt')
1074 call assert_equal('"barx', @:)
1075 unmap! <F2>
1076
1077 " test for calling a <SID> function
1078 let lines =<< trim END
1079 map <F2> <Cmd>call <SID>do_it()<CR>
1080 func s:do_it()
1081 let g:x = 32
1082 endfunc
1083 END
1084 call writefile(lines, 'Xscript')
1085 source Xscript
1086 call feedkeys("\<F2>", 'xt')
1087 call assert_equal(32, g:x)
1088 call delete('Xscript')
1089
1090 unmap <F3>
1091 unmap! <F3>
1092 %bw!
Bram Moolenaar4a441202020-11-28 14:43:26 +01001093
1094 " command line ending in "0" is handled without errors
1095 onoremap ix <cmd>eval 0<cr>
1096 call feedkeys('dix.', 'xt')
1097 ounmap ix
Bram Moolenaar957cf672020-11-12 14:21:06 +01001098endfunc
1099
1100" text object enters visual mode
1101func TextObj()
1102 if mode() !=# "v"
1103 normal! v
1104 end
1105 call cursor(1, 3)
1106 normal! o
1107 call cursor(2, 4)
1108endfunc
1109
1110func s:cmdmap(lhs, rhs)
1111 exe 'noremap ' .. a:lhs .. ' <Cmd>' .. a:rhs .. '<CR>'
1112 exe 'noremap! ' .. a:lhs .. ' <Cmd>' .. a:rhs .. '<CR>'
1113endfunc
1114
1115func s:cmdunmap(lhs)
1116 exe 'unmap ' .. a:lhs
1117 exe 'unmap! ' .. a:lhs
1118endfunc
1119
1120" Map various <Fx> keys used by the <Cmd> key tests
1121func s:setupMaps()
1122 call s:cmdmap('<F3>', 'let m = mode(1)')
1123 call s:cmdmap('<F4>', 'normal! ww')
1124 call s:cmdmap('<F5>', 'normal! "ay')
1125 call s:cmdmap('<F6>', 'throw "very error"')
1126 call s:cmdmap('<F7>', 'call TextObj()')
1127 call s:cmdmap('<F8>', 'startinsert')
1128 call s:cmdmap('<F9>', 'stopinsert')
1129endfunc
1130
1131" Remove the mappings setup by setupMaps()
1132func s:cleanupMaps()
1133 call s:cmdunmap('<F3>')
1134 call s:cmdunmap('<F4>')
1135 call s:cmdunmap('<F5>')
1136 call s:cmdunmap('<F6>')
1137 call s:cmdunmap('<F7>')
1138 call s:cmdunmap('<F8>')
1139 call s:cmdunmap('<F9>')
1140endfunc
1141
1142" Test for <Cmd> mapping in normal mode
1143func Test_map_cmdkey_normal_mode()
1144 new
1145 call s:setupMaps()
1146
1147 " check v:count and v:register works
1148 call s:cmdmap('<F2>', 'let s = [mode(1), v:count, v:register]')
1149 call feedkeys("\<F2>", 'xt')
1150 call assert_equal(['n', 0, '"'], s)
1151 call feedkeys("7\<F2>", 'xt')
1152 call assert_equal(['n', 7, '"'], s)
1153 call feedkeys("\"e\<F2>", 'xt')
1154 call assert_equal(['n', 0, 'e'], s)
1155 call feedkeys("5\"k\<F2>", 'xt')
1156 call assert_equal(['n', 5, 'k'], s)
1157 call s:cmdunmap('<F2>')
1158
1159 call setline(1, ['some short lines', 'of test text'])
1160 call feedkeys("\<F7>y", 'xt')
1161 call assert_equal("me short lines\nof t", @")
1162 call assert_equal('v', getregtype('"'))
1163 call assert_equal([0, 1, 3, 0], getpos("'<"))
1164 call assert_equal([0, 2, 4, 0], getpos("'>"))
1165
1166 " startinsert
1167 %d
1168 call feedkeys("\<F8>abc", 'xt')
1169 call assert_equal('abc', getline(1))
1170
1171 " feedkeys are not executed immediately
1172 noremap ,a <Cmd>call feedkeys("aalpha") \| let g:a = getline(2)<CR>
1173 %d
1174 call setline(1, ['some short lines', 'of test text'])
1175 call cursor(2, 3)
1176 call feedkeys(",a\<F3>", 'xt')
1177 call assert_equal('of test text', g:a)
1178 call assert_equal('n', m)
1179 call assert_equal(['some short lines', 'of alphatest text'], getline(1, '$'))
1180 nunmap ,a
1181
1182 " feedkeys(..., 'x') is executed immediately, but insert mode is aborted
1183 noremap ,b <Cmd>call feedkeys("abeta", 'x') \| let g:b = getline(2)<CR>
1184 call feedkeys(",b\<F3>", 'xt')
1185 call assert_equal('n', m)
1186 call assert_equal('of alphabetatest text', g:b)
1187 nunmap ,b
1188
1189 call s:cleanupMaps()
1190 %bw!
1191endfunc
1192
1193" Test for <Cmd> mapping with the :normal command
1194func Test_map_cmdkey_normal_cmd()
1195 new
1196 noremap ,x <Cmd>call append(1, "xx") \| call append(1, "aa")<CR>
1197 noremap ,f <Cmd>nosuchcommand<CR>
1198 noremap ,e <Cmd>throw "very error" \| call append(1, "yy")<CR>
1199 noremap ,m <Cmd>echoerr "The message." \| call append(1, "zz")<CR>
1200 noremap ,w <Cmd>for i in range(5) \| if i==1 \| echoerr "Err" \| endif \| call append(1, i) \| endfor<CR>
1201
1202 call setline(1, ['some short lines', 'of test text'])
1203 exe "norm ,x\r"
1204 call assert_equal(['some short lines', 'aa', 'xx', 'of test text'], getline(1, '$'))
1205
1206 call assert_fails('norm ,f', 'E492:')
1207 call assert_fails('norm ,e', 'very error')
1208 call assert_fails('norm ,m', 'The message.')
1209 call assert_equal(['some short lines', 'aa', 'xx', 'of test text'], getline(1, '$'))
1210
1211 %d
1212 let caught_err = 0
1213 try
1214 exe "normal ,w"
1215 catch /Vim(echoerr):Err/
1216 let caught_err = 1
1217 endtry
1218 call assert_equal(1, caught_err)
1219 call assert_equal(['', '0'], getline(1, '$'))
1220
1221 %d
1222 call assert_fails('normal ,w', 'Err')
1223 call assert_equal(['', '4', '3', '2' ,'1', '0'], getline(1, '$'))
1224 call assert_equal(1, line('.'))
1225
1226 nunmap ,x
1227 nunmap ,f
1228 nunmap ,e
1229 nunmap ,m
1230 nunmap ,w
1231 %bw!
1232endfunc
1233
1234" Test for <Cmd> mapping in visual mode
1235func Test_map_cmdkey_visual_mode()
1236 new
1237 set showmode
1238 call s:setupMaps()
1239
1240 call setline(1, ['some short lines', 'of test text'])
1241 call feedkeys("v\<F4>", 'xt!')
1242 call assert_equal(['v', 1, 12], [mode(1), col('v'), col('.')])
1243
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +01001244 " can invoke an operator, ending the visual mode
Bram Moolenaar957cf672020-11-12 14:21:06 +01001245 let @a = ''
1246 call feedkeys("\<F5>", 'xt!')
1247 call assert_equal('n', mode(1))
1248 call assert_equal('some short l', @a)
1249
1250 " error doesn't interrupt visual mode
1251 call assert_fails('call feedkeys("ggvw\<F6>", "xt!")', 'E605:')
1252 call assert_equal(['v', 1, 6], [mode(1), col('v'), col('.')])
1253 call feedkeys("\<F7>", 'xt!')
1254 call assert_equal(['v', 1, 3, 2, 4], [mode(1), line('v'), col('v'), line('.'), col('.')])
1255
1256 " startinsert gives "-- (insert) VISUAL --" mode
1257 call feedkeys("\<F8>", 'xt!')
1258 call assert_equal(['v', 1, 3, 2, 4], [mode(1), line('v'), col('v'), line('.'), col('.')])
1259 redraw!
1260 call assert_match('^-- (insert) VISUAL --', Screenline(&lines))
1261 call feedkeys("\<Esc>new ", 'x')
1262 call assert_equal(['some short lines', 'of new test text'], getline(1, '$'))
1263
1264 call s:cleanupMaps()
1265 set showmode&
1266 %bw!
1267endfunc
1268
1269" Test for <Cmd> mapping in select mode
1270func Test_map_cmdkey_select_mode()
1271 new
1272 set showmode
1273 call s:setupMaps()
1274
1275 snoremap <F1> <cmd>throw "very error"<CR>
1276 snoremap <F2> <cmd>normal! <c-g>"by<CR>
1277 call setline(1, ['some short lines', 'of test text'])
1278
1279 call feedkeys("gh\<F4>", "xt!")
1280 call assert_equal(['s', 1, 12], [mode(1), col('v'), col('.')])
1281 redraw!
1282 call assert_match('^-- SELECT --', Screenline(&lines))
1283
1284 " visual mapping in select mode restarts select mode after operator
1285 let @a = ''
1286 call feedkeys("\<F5>", 'xt!')
1287 call assert_equal('s', mode(1))
1288 call assert_equal('some short l', @a)
1289
1290 " select mode mapping works, and does not restart select mode
1291 let @b = ''
1292 call feedkeys("\<F2>", 'xt!')
1293 call assert_equal('n', mode(1))
1294 call assert_equal('some short l', @b)
1295
1296 " error doesn't interrupt temporary visual mode
1297 call assert_fails('call feedkeys("\<Esc>ggvw\<C-G>\<F6>", "xt!")', 'E605:')
1298 redraw!
1299 call assert_match('^-- VISUAL --', Screenline(&lines))
1300 " quirk: restoration of select mode is not performed
1301 call assert_equal(['v', 1, 6], [mode(1), col('v'), col('.')])
1302
1303 " error doesn't interrupt select mode
1304 call assert_fails('call feedkeys("\<Esc>ggvw\<C-G>\<F1>", "xt!")', 'E605:')
1305 redraw!
1306 call assert_match('^-- SELECT --', Screenline(&lines))
1307 call assert_equal(['s', 1, 6], [mode(1), col('v'), col('.')])
1308
1309 call feedkeys("\<F7>", 'xt!')
1310 redraw!
1311 call assert_match('^-- SELECT --', Screenline(&lines))
1312 call assert_equal(['s', 1, 3, 2, 4], [mode(1), line('v'), col('v'), line('.'), col('.')])
1313
1314 " startinsert gives "-- SELECT (insert) --" mode
1315 call feedkeys("\<F8>", 'xt!')
1316 redraw!
1317 call assert_match('^-- (insert) SELECT --', Screenline(&lines))
1318 call assert_equal(['s', 1, 3, 2, 4], [mode(1), line('v'), col('v'), line('.'), col('.')])
1319 call feedkeys("\<Esc>new ", 'x')
1320 call assert_equal(['some short lines', 'of new test text'], getline(1, '$'))
1321
1322 sunmap <F1>
1323 sunmap <F2>
1324 call s:cleanupMaps()
1325 set showmode&
1326 %bw!
1327endfunc
1328
1329" Test for <Cmd> mapping in operator-pending mode
1330func Test_map_cmdkey_op_pending_mode()
1331 new
1332 call s:setupMaps()
1333
1334 call setline(1, ['some short lines', 'of test text'])
1335 call feedkeys("d\<F4>", 'xt')
1336 call assert_equal(['lines', 'of test text'], getline(1, '$'))
1337 call assert_equal(['some short '], getreg('"', 1, 1))
1338 " create a new undo point
1339 let &undolevels = &undolevels
1340
1341 call feedkeys(".", 'xt')
1342 call assert_equal(['test text'], getline(1, '$'))
1343 call assert_equal(['lines', 'of '], getreg('"', 1, 1))
1344 " create a new undo point
1345 let &undolevels = &undolevels
1346
1347 call feedkeys("uu", 'xt')
1348 call assert_equal(['some short lines', 'of test text'], getline(1, '$'))
1349
1350 " error aborts operator-pending, operator not performed
1351 call assert_fails('call feedkeys("d\<F6>", "xt")', 'E605:')
1352 call assert_equal(['some short lines', 'of test text'], getline(1, '$'))
1353
1354 call feedkeys("\"bd\<F7>", 'xt')
1355 call assert_equal(['soest text'], getline(1, '$'))
1356 call assert_equal(['me short lines', 'of t'], getreg('b', 1, 1))
1357
1358 " startinsert aborts operator
1359 call feedkeys("d\<F8>cc", 'xt')
1360 call assert_equal(['soccest text'], getline(1, '$'))
1361
1362 call s:cleanupMaps()
1363 %bw!
1364endfunc
1365
1366" Test for <Cmd> mapping in insert mode
1367func Test_map_cmdkey_insert_mode()
1368 new
1369 call s:setupMaps()
1370
1371 call setline(1, ['some short lines', 'of test text'])
1372 " works the same as <C-O>w<C-O>w
1373 call feedkeys("iindeed \<F4>little ", 'xt')
1374 call assert_equal(['indeed some short little lines', 'of test text'], getline(1, '$'))
1375 call assert_fails('call feedkeys("i\<F6> 2", "xt")', 'E605:')
1376 call assert_equal(['indeed some short little 2 lines', 'of test text'], getline(1, '$'))
1377
1378 " Note when entering visual mode from InsertEnter autocmd, an async event,
1379 " or a <Cmd> mapping, vim ends up in undocumented "INSERT VISUAL" mode.
1380 call feedkeys("i\<F7>stuff ", 'xt')
1381 call assert_equal(['indeed some short little 2 lines', 'of stuff test text'], getline(1, '$'))
1382 call assert_equal(['v', 1, 3, 2, 9], [mode(1), line('v'), col('v'), line('.'), col('.')])
1383
1384 call feedkeys("\<F5>", 'xt')
1385 call assert_equal(['deed some short little 2 lines', 'of stuff '], getreg('a', 1, 1))
1386
1387 " also works as part of abbreviation
1388 abbr foo <Cmd>let g:y = 17<CR>bar
1389 exe "normal i\<space>foo "
1390 call assert_equal(17, g:y)
1391 call assert_equal('in bar deed some short little 2 lines', getline(1))
1392 unabbr foo
1393
1394 " :startinsert does nothing
1395 call setline(1, 'foo bar')
1396 call feedkeys("ggi\<F8>vim", 'xt')
1397 call assert_equal('vimfoo bar', getline(1))
1398
1399 " :stopinsert works
1400 call feedkeys("ggi\<F9>Abc", 'xt')
1401 call assert_equal('vimfoo barbc', getline(1))
1402
1403 call s:cleanupMaps()
1404 %bw!
1405endfunc
1406
1407" Test for <Cmd> mapping in insert-completion mode
1408func Test_map_cmdkey_insert_complete_mode()
1409 new
1410 call s:setupMaps()
1411
1412 call setline(1, 'some short lines')
1413 call feedkeys("os\<C-X>\<C-N>\<F3>\<C-N> ", 'xt')
1414 call assert_equal('ic', m)
1415 call assert_equal(['some short lines', 'short '], getline(1, '$'))
1416
1417 call s:cleanupMaps()
1418 %bw!
1419endfunc
1420
1421" Test for <Cmd> mapping in cmdline mode
1422func Test_map_cmdkey_cmdline_mode()
1423 new
1424 call s:setupMaps()
1425
1426 call setline(1, ['some short lines', 'of test text'])
1427 let x = 0
1428 call feedkeys(":let x\<F3>= 10\r", 'xt')
1429 call assert_equal('c', m)
1430 call assert_equal(10, x)
1431
1432 " exception doesn't leave cmdline mode
1433 call assert_fails('call feedkeys(":let x\<F6>= 20\r", "xt")', 'E605:')
1434 call assert_equal(20, x)
1435
1436 " move cursor in the buffer from cmdline mode
1437 call feedkeys(":let x\<F4>= 30\r", 'xt')
1438 call assert_equal(30, x)
1439 call assert_equal(12, col('.'))
1440
1441 " :startinsert takes effect after leaving cmdline mode
1442 call feedkeys(":let x\<F8>= 40\rnew ", 'xt')
1443 call assert_equal(40, x)
1444 call assert_equal('some short new lines', getline(1))
1445
1446 call s:cleanupMaps()
1447 %bw!
1448endfunc
1449
Bram Moolenaarc77534c2020-11-18 11:34:37 +01001450func Test_map_cmdkey_redo()
1451 func SelectDash()
1452 call search('^---\n\zs', 'bcW')
1453 norm! V
1454 call search('\n\ze---$', 'W')
1455 endfunc
1456
1457 let text =<< trim END
1458 ---
1459 aaa
1460 ---
1461 bbb
1462 bbb
1463 ---
1464 ccc
1465 ccc
1466 ccc
1467 ---
1468 END
1469 new Xcmdtext
1470 call setline(1, text)
1471
1472 onoremap <silent> i- <Cmd>call SelectDash()<CR>
1473 call feedkeys('2Gdi-', 'xt')
1474 call assert_equal(['---', '---'], getline(1, 2))
1475 call feedkeys('j.', 'xt')
1476 call assert_equal(['---', '---', '---'], getline(1, 3))
1477 call feedkeys('j.', 'xt')
1478 call assert_equal(['---', '---', '---', '---'], getline(1, 4))
1479
1480 bwipe!
1481 call delete('Xcmdtext')
1482 delfunc SelectDash
1483 ounmap i-
1484endfunc
1485
Bram Moolenaara9725222022-01-16 13:30:33 +00001486func Test_map_script_cmd_restore()
1487 let lines =<< trim END
1488 vim9script
1489 nnoremap <F3> <ScriptCmd>eval 1 + 2<CR>
1490 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001491 call v9.CheckScriptSuccess(lines)
Bram Moolenaara9725222022-01-16 13:30:33 +00001492 call feedkeys("\<F3>:let g:result = 3+4\<CR>", 'xtc')
1493 call assert_equal(7, g:result)
1494
1495 nunmap <F3>
1496 unlet g:result
1497endfunc
1498
Bram Moolenaardc987762022-01-16 15:52:35 +00001499func Test_map_script_cmd_finds_func()
1500 let lines =<< trim END
1501 vim9script
1502 onoremap <F3> <ScriptCmd>Func()<CR>
1503 def Func()
1504 g:func_called = 'yes'
1505 enddef
1506 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001507 call v9.CheckScriptSuccess(lines)
Bram Moolenaardc987762022-01-16 15:52:35 +00001508 call feedkeys("y\<F3>\<Esc>", 'xtc')
1509 call assert_equal('yes', g:func_called)
1510
1511 ounmap <F3>
1512 unlet g:func_called
1513endfunc
1514
Bram Moolenaarf61c89d2022-01-19 22:51:48 +00001515func Test_map_script_cmd_survives_unmap()
1516 let lines =<< trim END
1517 vim9script
1518 var n = 123
1519 nnoremap <F4> <ScriptCmd><CR>
1520 autocmd CmdlineEnter * silent! nunmap <F4>
1521 nnoremap <F3> :<ScriptCmd>eval setbufvar(bufnr(), "result", n)<CR>
1522 feedkeys("\<F3>\<CR>", 'xct')
1523 assert_equal(123, b:result)
1524 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001525 call v9.CheckScriptSuccess(lines)
Bram Moolenaarf61c89d2022-01-19 22:51:48 +00001526
1527 nunmap <F3>
1528 unlet b:result
Bram Moolenaarca34db32022-01-20 11:17:18 +00001529 autocmd! CmdlineEnter
Bram Moolenaarf61c89d2022-01-19 22:51:48 +00001530endfunc
1531
Bram Moolenaarddf7dba2022-09-05 16:53:21 +01001532func Test_map_script_cmd_redo()
1533 call mkdir('Xmapcmd')
1534 let lines =<< trim END
1535 vim9script
1536 import autoload './script.vim'
1537 onoremap <F3> <ScriptCmd>script.Func()<CR>
1538 END
1539 call writefile(lines, 'Xmapcmd/plugin.vim')
1540
1541 let lines =<< trim END
1542 vim9script
1543 export def Func()
1544 normal! dd
1545 enddef
1546 END
1547 call writefile(lines, 'Xmapcmd/script.vim')
1548 new
1549 call setline(1, ['one', 'two', 'three', 'four'])
1550 nnoremap j j
1551 source Xmapcmd/plugin.vim
1552 call feedkeys("d\<F3>j.", 'xt')
1553 call assert_equal(['two', 'four'], getline(1, '$'))
1554
1555 ounmap <F3>
1556 nunmap j
1557 call delete('Xmapcmd', 'rf')
1558 bwipe!
1559endfunc
1560
Bram Moolenaar1f448d92021-03-22 19:37:06 +01001561" Test for using <script> with a map to remap characters in rhs
1562func Test_script_local_remap()
1563 new
1564 inoremap <buffer> <SID>xyz mno
1565 inoremap <buffer> <script> abc st<SID>xyzre
1566 normal iabc
1567 call assert_equal('stmnore', getline(1))
1568 bwipe!
1569endfunc
1570
Bram Moolenaar4934ed32021-04-30 19:43:11 +02001571func Test_abbreviate_multi_byte()
1572 new
1573 iabbrev foo bar
1574 call feedkeys("ifoo…\<Esc>", 'xt')
1575 call assert_equal("bar…", getline(1))
1576 iunabbrev foo
1577 bwipe!
1578endfunc
1579
Yegappan Lakshmanan2d6d7182021-06-13 21:52:48 +02001580" Test for abbreviations with 'latin1' encoding
1581func Test_abbreviate_latin1_encoding()
1582 set encoding=latin1
1583 call assert_fails('abbr ab#$c ABC', 'E474:')
1584 new
1585 iabbr <buffer> #i #include
1586 iabbr <buffer> ## #enddef
1587 exe "normal i#i\<C-]>"
1588 call assert_equal('#include', getline(1))
1589 exe "normal 0Di##\<C-]>"
1590 call assert_equal('#enddef', getline(1))
1591 %bw!
1592 set encoding=utf-8
1593endfunc
1594
Bram Moolenaar1fc34222022-03-03 13:56:24 +00001595" Test for <Plug> always being mapped, even when used with "noremap".
1596func Test_plug_remap()
1597 let g:foo = 0
1598 nnoremap <Plug>(Increase_x) <Cmd>let g:foo += 1<CR>
1599 nmap <F2> <Plug>(Increase_x)
1600 nnoremap <F3> <Plug>(Increase_x)
1601 call feedkeys("\<F2>", 'xt')
1602 call assert_equal(1, g:foo)
1603 call feedkeys("\<F3>", 'xt')
1604 call assert_equal(2, g:foo)
1605 nnoremap x <Nop>
1606 nmap <F4> x<Plug>(Increase_x)x
1607 nnoremap <F5> x<Plug>(Increase_x)x
1608 call setline(1, 'Some text')
1609 normal! gg$
1610 call feedkeys("\<F4>", 'xt')
1611 call assert_equal(3, g:foo)
1612 call assert_equal('Some text', getline(1))
1613 call feedkeys("\<F5>", 'xt')
1614 call assert_equal(4, g:foo)
1615 call assert_equal('Some te', getline(1))
1616 nunmap <Plug>(Increase_x)
1617 nunmap <F2>
1618 nunmap <F3>
1619 nunmap <F4>
1620 nunmap <F5>
1621 unlet g:foo
1622 %bw!
1623endfunc
1624
zeertzjqac92ab72022-04-24 15:58:30 +01001625func Test_mouse_drag_mapped_start_select()
1626 set mouse=a
1627 set selectmode=key,mouse
1628 func ClickExpr()
1629 call test_setmouse(1, 1)
1630 return "\<LeftMouse>"
1631 endfunc
1632 func DragExpr()
1633 call test_setmouse(1, 2)
1634 return "\<LeftDrag>"
1635 endfunc
1636 nnoremap <expr> <F2> ClickExpr()
1637 nmap <expr> <F3> DragExpr()
1638
1639 nnoremap <LeftDrag> <LeftDrag><Cmd><CR>
1640 exe "normal \<F2>\<F3>"
1641 call assert_equal('s', mode())
1642 exe "normal! \<C-\>\<C-N>"
1643
1644 nunmap <LeftDrag>
1645 nunmap <F2>
1646 nunmap <F3>
1647 delfunc ClickExpr
1648 delfunc DragExpr
1649 set selectmode&
1650 set mouse&
1651endfunc
1652
zeertzjq0f68e6c2022-04-05 13:17:01 +01001653" Test for mapping <LeftDrag> in Insert mode
1654func Test_mouse_drag_insert_map()
1655 set mouse=a
1656 func ClickExpr()
1657 call test_setmouse(1, 1)
1658 return "\<LeftMouse>"
1659 endfunc
1660 func DragExpr()
1661 call test_setmouse(1, 2)
1662 return "\<LeftDrag>"
1663 endfunc
1664 inoremap <expr> <F2> ClickExpr()
1665 imap <expr> <F3> DragExpr()
1666
1667 inoremap <LeftDrag> <LeftDrag><Cmd>let g:dragged = 1<CR>
1668 exe "normal i\<F2>\<F3>"
1669 call assert_equal(1, g:dragged)
1670 call assert_equal('v', mode())
1671 exe "normal! \<C-\>\<C-N>"
1672 unlet g:dragged
1673
1674 inoremap <LeftDrag> <LeftDrag><C-\><C-N>
1675 exe "normal i\<F2>\<F3>"
1676 call assert_equal('n', mode())
1677
1678 iunmap <LeftDrag>
1679 iunmap <F2>
1680 iunmap <F3>
1681 delfunc ClickExpr
1682 delfunc DragExpr
1683 set mouse&
1684endfunc
1685
zeertzjqabeb09b2022-04-26 12:29:43 +01001686func Test_unmap_simplifiable()
zeertzjqa4e33322022-04-24 17:07:53 +01001687 map <C-I> foo
1688 map <Tab> bar
1689 call assert_equal('foo', maparg('<C-I>'))
1690 call assert_equal('bar', maparg('<Tab>'))
1691 unmap <C-I>
1692 call assert_equal('', maparg('<C-I>'))
1693 call assert_equal('bar', maparg('<Tab>'))
1694 unmap <Tab>
zeertzjqabeb09b2022-04-26 12:29:43 +01001695
1696 map <C-I> foo
1697 unmap <Tab>
1698 " This should not error
1699 unmap <C-I>
zeertzjqa4e33322022-04-24 17:07:53 +01001700endfunc
1701
zeertzjqdb088872022-05-02 22:53:45 +01001702func Test_expr_map_escape_special()
1703 nnoremap … <Cmd>let g:got_ellipsis += 1<CR>
1704 func Func()
1705 return '…'
1706 endfunc
1707 nmap <expr> <F2> Func()
1708 let g:got_ellipsis = 0
1709 call feedkeys("\<F2>", 'xt')
1710 call assert_equal(1, g:got_ellipsis)
1711 delfunc Func
1712 nunmap <F2>
1713 unlet g:got_ellipsis
1714 nunmap …
1715endfunc
1716
zeertzjq3760bfd2022-06-06 16:22:46 +01001717" Testing for mapping after an <Nop> mapping is triggered on timeout.
1718" Test for what patch 8.1.0052 fixes.
1719func Test_map_after_timed_out_nop()
1720 CheckRunVimInTerminal
1721
1722 let lines =<< trim END
1723 set timeout timeoutlen=400
1724 inoremap ab TEST
1725 inoremap a <Nop>
1726 END
1727 call writefile(lines, 'Xtest_map_after_timed_out_nop')
1728 let buf = RunVimInTerminal('-S Xtest_map_after_timed_out_nop', #{rows: 6})
1729
1730 " Enter Insert mode
1731 call term_sendkeys(buf, 'i')
1732 " Wait for the "a" mapping to timeout
1733 call term_sendkeys(buf, 'a')
1734 call term_wait(buf, 500)
1735 " Send "a" and wait for a period shorter than 'timeoutlen'
1736 call term_sendkeys(buf, 'a')
1737 call term_wait(buf, 100)
1738 " Send "b", should trigger the "ab" mapping
1739 call term_sendkeys(buf, 'b')
1740 call WaitForAssert({-> assert_equal("TEST", term_getline(buf, 1))})
1741
1742 " clean up
1743 call StopVimInTerminal(buf)
1744 call delete('Xtest_map_after_timed_out_nop')
1745endfunc
1746
Bram Moolenaar27efc622022-07-01 16:35:45 +01001747func Test_using_past_typeahead()
1748 nnoremap :00 0
1749 exe "norm :set \x80\xfb0=0\<CR>"
1750 exe "sil norm :0\x0f\<C-U>\<CR>"
1751
1752 exe "norm :set \x80\xfb0=\<CR>"
1753 nunmap :00
1754endfunc
1755
1756
Bram Moolenaar8ba6bb72020-01-20 20:41:42 +01001757" vim: shiftwidth=2 sts=2 expandtab