1" Tests for mappings and abbreviations 2 3source shared.vim 4source check.vim 5 6func Test_abbreviation() 7 " abbreviation with 0x80 should work 8 inoreab чкпр vim 9 call feedkeys("Goчкпр \<Esc>", "xt") 10 call assert_equal('vim ', getline('$')) 11 iunab чкпр 12 set nomodified 13endfunc 14 15func Test_abclear() 16 abbrev foo foobar 17 iabbrev fooi foobari 18 cabbrev fooc foobarc 19 call assert_equal("\n\n" 20 \ .. "c fooc foobarc\n" 21 \ .. "i fooi foobari\n" 22 \ .. "! foo foobar", execute('abbrev')) 23 24 iabclear 25 call assert_equal("\n\n" 26 \ .. "c fooc foobarc\n" 27 \ .. "c foo foobar", execute('abbrev')) 28 abbrev foo foobar 29 iabbrev fooi foobari 30 31 cabclear 32 call assert_equal("\n\n" 33 \ .. "i fooi foobari\n" 34 \ .. "i foo foobar", execute('abbrev')) 35 abbrev foo foobar 36 cabbrev fooc foobarc 37 38 abclear 39 call assert_equal("\n\nNo abbreviation found", execute('abbrev')) 40endfunc 41 42func Test_abclear_buffer() 43 abbrev foo foobar 44 new X1 45 abbrev <buffer> foo1 foobar1 46 new X2 47 abbrev <buffer> foo2 foobar2 48 49 call assert_equal("\n\n" 50 \ .. "! foo2 @foobar2\n" 51 \ .. "! foo foobar", execute('abbrev')) 52 53 abclear <buffer> 54 call assert_equal("\n\n" 55 \ .. "! foo foobar", execute('abbrev')) 56 57 b X1 58 call assert_equal("\n\n" 59 \ .. "! foo1 @foobar1\n" 60 \ .. "! foo foobar", execute('abbrev')) 61 abclear <buffer> 62 call assert_equal("\n\n" 63 \ .. "! foo foobar", execute('abbrev')) 64 65 abclear 66 call assert_equal("\n\nNo abbreviation found", execute('abbrev')) 67 68 %bwipe 69endfunc 70 71func Test_map_ctrl_c_insert() 72 " mapping of ctrl-c in Insert mode 73 set cpo-=< cpo-=k 74 inoremap <c-c> <ctrl-c> 75 cnoremap <c-c> dummy 76 cunmap <c-c> 77 call feedkeys("GoTEST2: CTRL-C |\<C-C>A|\<Esc>", "xt") 78 call assert_equal('TEST2: CTRL-C |<ctrl-c>A|', getline('$')) 79 unmap! <c-c> 80 set nomodified 81endfunc 82 83func Test_map_ctrl_c_visual() 84 " mapping of ctrl-c in Visual mode 85 vnoremap <c-c> :<C-u>$put ='vmap works' 86 call feedkeys("GV\<C-C>\<CR>", "xt") 87 call assert_equal('vmap works', getline('$')) 88 vunmap <c-c> 89 set nomodified 90endfunc 91 92func Test_map_langmap() 93 if !has('langmap') 94 return 95 endif 96 97 " check langmap applies in normal mode 98 set langmap=+- nolangremap 99 new 100 call setline(1, ['a', 'b', 'c']) 101 2 102 call assert_equal('b', getline('.')) 103 call feedkeys("+", "xt") 104 call assert_equal('a', getline('.')) 105 106 " check no remapping 107 map x + 108 2 109 call feedkeys("x", "xt") 110 call assert_equal('c', getline('.')) 111 112 " check with remapping 113 set langremap 114 2 115 call feedkeys("x", "xt") 116 call assert_equal('a', getline('.')) 117 118 unmap x 119 bwipe! 120 121 " 'langnoremap' follows 'langremap' and vise versa 122 set langremap 123 set langnoremap 124 call assert_equal(0, &langremap) 125 set langremap 126 call assert_equal(0, &langnoremap) 127 set nolangremap 128 call assert_equal(1, &langnoremap) 129 130 " check default values 131 set langnoremap& 132 call assert_equal(0, &langnoremap) 133 call assert_equal(1, &langremap) 134 set langremap& 135 call assert_equal(0, &langnoremap) 136 call assert_equal(1, &langremap) 137 138 " langmap should not apply in insert mode, 'langremap' doesn't matter 139 set langmap=+{ nolangremap 140 call feedkeys("Go+\<Esc>", "xt") 141 call assert_equal('+', getline('$')) 142 set langmap=+{ langremap 143 call feedkeys("Go+\<Esc>", "xt") 144 call assert_equal('+', getline('$')) 145 146 " langmap used for register name in insert mode. 147 call setreg('a', 'aaaa') 148 call setreg('b', 'bbbb') 149 call setreg('c', 'cccc') 150 set langmap=ab langremap 151 call feedkeys("Go\<C-R>a\<Esc>", "xt") 152 call assert_equal('bbbb', getline('$')) 153 call feedkeys("Go\<C-R>\<C-R>a\<Esc>", "xt") 154 call assert_equal('bbbb', getline('$')) 155 " mapping does not apply 156 imap c a 157 call feedkeys("Go\<C-R>c\<Esc>", "xt") 158 call assert_equal('cccc', getline('$')) 159 imap a c 160 call feedkeys("Go\<C-R>a\<Esc>", "xt") 161 call assert_equal('bbbb', getline('$')) 162 163 " langmap should not apply in Command-line mode 164 set langmap=+{ nolangremap 165 call feedkeys(":call append(line('$'), '+')\<CR>", "xt") 166 call assert_equal('+', getline('$')) 167 168 iunmap a 169 iunmap c 170 set nomodified 171endfunc 172 173func Test_map_feedkeys() 174 " issue #212 (feedkeys insert mapping at current position) 175 nnoremap . :call feedkeys(".", "in")<cr> 176 call setline('$', ['a b c d', 'a b c d']) 177 $-1 178 call feedkeys("0qqdw.ifoo\<Esc>qj0@q\<Esc>", "xt") 179 call assert_equal(['fooc d', 'fooc d'], getline(line('$') - 1, line('$'))) 180 nunmap . 181 set nomodified 182endfunc 183 184func Test_map_cursor() 185 " <c-g>U<cursor> works only within a single line 186 imapclear 187 imap ( ()<c-g>U<left> 188 call feedkeys("G2o\<Esc>ki\<CR>Test1: text with a (here some more text\<Esc>k.", "xt") 189 call assert_equal('Test1: text with a (here some more text)', getline(line('$') - 2)) 190 call assert_equal('Test1: text with a (here some more text)', getline(line('$') - 1)) 191 192 " test undo 193 call feedkeys("G2o\<Esc>ki\<CR>Test2: text wit a (here some more text [und undo]\<C-G>u\<Esc>k.u", "xt") 194 call assert_equal('', getline(line('$') - 2)) 195 call assert_equal('Test2: text wit a (here some more text [und undo])', getline(line('$') - 1)) 196 set nomodified 197 imapclear 198endfunc 199 200func Test_map_cursor_ctrl_gU() 201 " <c-g>U<cursor> works only within a single line 202 nnoremap c<* *Ncgn<C-r>"<C-G>U<S-Left> 203 call setline(1, ['foo', 'foobar', '', 'foo']) 204 call cursor(1,2) 205 call feedkeys("c<*PREFIX\<esc>.", 'xt') 206 call assert_equal(['PREFIXfoo', 'foobar', '', 'PREFIXfoo'], getline(1,'$')) 207 " break undo manually 208 set ul=1000 209 exe ":norm! uu" 210 call assert_equal(['foo', 'foobar', '', 'foo'], getline(1,'$')) 211 212 " Test that it does not work if the cursor moves to the previous line 213 " 2 times <S-Left> move to the previous line 214 nnoremap c<* *Ncgn<C-r>"<C-G>U<S-Left><C-G>U<S-Left> 215 call setline(1, ['', ' foo', 'foobar', '', 'foo']) 216 call cursor(2,3) 217 call feedkeys("c<*PREFIX\<esc>.", 'xt') 218 call assert_equal(['PREFIXPREFIX', ' foo', 'foobar', '', 'foo'], getline(1,'$')) 219 nmapclear 220endfunc 221 222 223" This isn't actually testing a mapping, but similar use of CTRL-G U as above. 224func Test_break_undo() 225 set whichwrap=<,>,[,] 226 call feedkeys("G4o2k", "xt") 227 exe ":norm! iTest3: text with a (parenthesis here\<C-G>U\<Right>new line here\<esc>\<up>\<up>." 228 call assert_equal('new line here', getline(line('$') - 3)) 229 call assert_equal('Test3: text with a (parenthesis here', getline(line('$') - 2)) 230 call assert_equal('new line here', getline(line('$') - 1)) 231 set nomodified 232endfunc 233 234func Test_map_meta_quotes() 235 imap <M-"> foo 236 call feedkeys("Go-\<M-\">-\<Esc>", "xt") 237 call assert_equal("-foo-", getline('$')) 238 set nomodified 239 iunmap <M-"> 240endfunc 241 242func Test_map_meta_multibyte() 243 imap <M-á> foo 244 call assert_match('i <M-á>\s*foo', execute('imap')) 245 iunmap <M-á> 246endfunc 247 248func Test_abbr_after_line_join() 249 new 250 abbr foo bar 251 set backspace=indent,eol,start 252 exe "normal o\<BS>foo " 253 call assert_equal("bar ", getline(1)) 254 bwipe! 255 unabbr foo 256 set backspace& 257endfunc 258 259func Test_map_timeout() 260 if !has('timers') 261 return 262 endif 263 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 272 let timer = timer_start(300, 'ExitInsert') 273 " 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 287 call timer_stop(timer) 288endfunc 289 290func Test_map_timeout_with_timer_interrupt() 291 if !has('job') || !has('timers') 292 return 293 endif 294 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> 301 set timeout timeoutlen=200 302 303 func ExitCb(job, status) 304 let g:timer = timer_start(1, {-> feedkeys("3\<Esc>", 't')}) 305 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 320endfunc 321 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 337 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 353 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 407 408func Test_error_in_map_expr() 409 " Unlike CheckRunVimInTerminal this does work in a win32 console 410 CheckFeature terminal 411 if has('win32') && has('gui_running') 412 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 425 let buf = term_start(GetVimCommandCleanTerm() .. ' -S Xtest.vim', {'term_rows': 8}) 426 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, '!') 431 call term_wait(buf, 100) 432 call term_sendkeys(buf, "\<CR>") 433 call term_wait(buf, 100) 434 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 445 446func Test_list_mappings() 447 " Remove default mappings 448 imapclear 449 450 inoremap <C-M> CtrlM 451 inoremap <A-S> AltS 452 inoremap <S-/> ShiftSlash 453 call assert_equal([ 454 \ 'i <S-/> * ShiftSlash', 455 \ 'i <M-S> * AltS', 456 \ 'i <C-M> * CtrlM', 457 \], execute('imap')->trim()->split("\n")) 458 iunmap <C-M> 459 iunmap <A-S> 460 call assert_equal(['i <S-/> * ShiftSlash'], execute('imap')->trim()->split("\n")) 461 iunmap <S-/> 462 call assert_equal(['No mapping found'], execute('imap')->trim()->split("\n")) 463endfunc 464