1" Tests for the Tcl interface. 2 3if !has('tcl') 4 finish 5end 6 7" Helper function as there is no builtin tcleval() function similar 8" to perleval, luaevel(), pyeval(), etc. 9func TclEval(tcl_expr) 10 let s = split(execute('tcl ' . a:tcl_expr), "\n") 11 return (len(s) == 0) ? '' : s[-1] 12endfunc 13 14func Test_tcldo() 15 " Check deleting lines does not trigger ml_get error. 16 new 17 call setline(1, ['one', 'two', 'three']) 18 tcldo ::vim::command %d_ 19 bwipe! 20 21 " Check that switching to another buffer does not trigger ml_get error. 22 new 23 let wincount = winnr('$') 24 call setline(1, ['one', 'two', 'three']) 25 tcldo ::vim::command new 26 call assert_equal(wincount + 1, winnr('$')) 27 %bwipe! 28endfunc 29 30" Test :tcldo with a range 31func Test_tcldo_range() 32 new 33 call setline(1, ['line1', 'line2', 'line3', 'line4']) 34 2,3tcldo set line [string toupper $line] 35 call assert_equal(['line1', 'LINE2', 'LINE3', 'line4'], getline(1, '$')) 36 bwipe! 37endfunc 38 39" Test ::vim::beep 40func Test_vim_beep() 41 call assert_beeps('tcl ::vim::beep') 42 call assert_fails('tcl ::vim::beep x', 'wrong # args: should be "::vim::beep"') 43endfunc 44 45" Test ::vim::buffer 46func Test_vim_buffer() 47 " Test ::vim::buffer {nr} 48 e Xfoo1 49 call setline(1, ['foobar']) 50 let bn1 = bufnr('%') 51 let b1 = TclEval('::vim::buffer ' . bn1) 52 call assert_equal(b1, TclEval('set ::vim::current(buffer)')) 53 54 new Xfoo2 55 call setline(1, ['barfoo']) 56 let bn2 = bufnr('%') 57 let b2 = TclEval('::vim::buffer ' . bn2) 58 call assert_equal(b2, TclEval('set ::vim::current(buffer)')) 59 60 call assert_match('Xfoo1$', TclEval(b1 . ' name')) 61 call assert_match('Xfoo2$', TclEval(b2 . ' name')) 62 63 " Test ::vim::buffer exists {nr} 64 call assert_match('^[1-9]\d*$', TclEval('::vim::buffer exists ' . bn1)) 65 call assert_match('^[1-9]\d*$', TclEval('::vim::buffer exists ' . bn2)) 66 call assert_equal('0', TclEval('::vim::buffer exists 54321')) 67 68 " Test ::vim::buffer list 69 call assert_equal('2', TclEval('llength [::vim::buffer list]')) 70 call assert_equal(b1.' '.b2, TclEval('::vim::buffer list')) 71 tcl <<EOF 72 proc eachbuf { cmd } { 73 foreach b [::vim::buffer list] { $b command $cmd } 74 } 75EOF 76 tcl eachbuf %s/foo/FOO/g 77 b! Xfoo1 78 call assert_equal(['FOObar'], getline(1, '$')) 79 b! Xfoo2 80 call assert_equal(['barFOO'], getline(1, '$')) 81 82 call assert_fails('tcl ::vim::buffer', 83 \ 'wrong # args: should be "::vim::buffer option"') 84 call assert_fails('tcl ::vim::buffer ' . bn1 . ' x', 85 \ 'wrong # args: should be "::vim::buffer bufNumber"') 86 call assert_fails('tcl ::vim::buffer 4321', 'invalid buffer number') 87 call assert_fails('tcl ::vim::buffer x', 88 \ 'bad option "x": must be exists or list') 89 call assert_fails('tcl ::vim::buffer exists', 90 \ 'wrong # args: should be "::vim::buffer exists bufNumber"') 91 call assert_fails('tcl ::vim::buffer exists x', 92 \ 'expected integer but got "x"') 93 call assert_fails('tcl ::vim::buffer list x', 94 \ 'wrong # args: should be "::vim::buffer list "') 95 96 tcl rename eachbuf "" 97 %bwipe! 98endfunc 99 100" Test ::vim::option 101func Test_vim_option() 102 set cc=3,5 103 104 " Test getting option 'cc' 105 call assert_equal('3,5', TclEval('::vim::option cc')) 106 call assert_equal('3,5', &cc) 107 108 " Test setting option 'cc' (it returns the old option value) 109 call assert_equal('3,5', TclEval('::vim::option cc +4')) 110 call assert_equal('+4', &cc) 111 call assert_equal('+4', TclEval('::vim::option cc')) 112 113 call assert_fails('tcl ::vim::option xxx', 'unknown vimOption') 114 call assert_fails('tcl ::vim::option', 115 \ 'wrong # args: should be "::vim::option vimOption ?value?"') 116 117 set cc& 118endfunc 119 120" Test ::vim::expr 121func Test_vim_expr() 122 call assert_equal(string(char2nr('X')), 123 \ TclEval('::vim::expr char2nr("X")')) 124 125 call assert_fails('tcl ::vim::expr x y', 126 \ 'wrong # args: should be "::vim::expr vimExpr"') 127endfunc 128 129" Test ::vim::command 130func Test_vim_command() 131 call assert_equal('hello world', 132 \ TclEval('::vim::command {echo "hello world"}')) 133 134 " With the -quiet option, the error should silently be ignored. 135 call assert_equal('', TclEval('::vim::command -quiet xyz')) 136 137 call assert_fails('tcl ::vim::command', 138 \ 'wrong # args: should be "::vim::command ?-quiet? exCommand"') 139 call assert_fails('tcl ::vim::command -foo xyz', 'unknown flag: -foo') 140 call assert_fails('tcl ::vim::command xyz', 141 \ 'E492: Not an editor command: xyz') 142 143 " With the -quiet option, the error should silently be ignored. 144 call assert_equal('', TclEval('::vim::command -quiet xyz')) 145endfunc 146 147" Test ::vim::window list 148func Test_vim_window_list() 149 e Xfoo1 150 new Xfoo2 151 let w2 = TclEval('set ::vim::current(window)') 152 wincmd j 153 let w1 = TclEval('set ::vim::current(window)') 154 155 call assert_equal('2', TclEval('llength [::vim::window list]')) 156 call assert_equal(w2.' '.w1, TclEval('::vim::window list')) 157 158 call assert_fails('tcl ::vim::window x', 'unknown option') 159 call assert_fails('tcl ::vim::window list x', 160 \ 'wrong # args: should be "::vim::window option"') 161 162 %bwipe 163endfunc 164 165" Test output messages 166func Test_output() 167 call assert_fails('tcl puts vimerr "an error"', 'an error') 168 tcl puts vimout "a message" 169 tcl puts "another message" 170 let messages = split(execute('message'), "\n") 171 call assert_equal('a message', messages[-2]) 172 call assert_equal('another message', messages[-1]) 173 174 call assert_fails('tcl puts', 175 \ 'wrong # args: should be "puts ?-nonewline? ?channelId? string"') 176endfunc 177 178" Test $win height (get and set window height) 179func Test_window_height() 180 new 181 182 " Test setting window height 183 tcl $::vim::current(window) height 2 184 call assert_equal(2, winheight(0)) 185 186 " Test getting window height 187 call assert_equal('2', TclEval('$::vim::current(window) height')) 188 189 call assert_fails('tcl $::vim::current(window) height 2 2', 'wrong # args:') 190 call assert_fails('tcl $::vim::current(window) height x', 191 \ 'expected integer but got "x"') 192 bwipe 193endfunc 194 195" Test $win cursor (get and set cursor) 196func Test_window_cursor() 197 new 198 call setline(1, ['line1', 'line2', 'line3', 'line5']) 199 tcl set win $::vim::current(window) 200 201 tcl $win cursor 2 4 202 call assert_equal([0, 2, 4, 0], getpos('.')) 203 call assert_equal('row 2 column 4', TclEval('$win cursor')) 204 205 " When setting ::vim::lbase to 0, line/col are counted from 0 206 " instead of 1. 207 tcl set ::vim::lbase 0 208 call assert_equal([0, 2, 4, 0], getpos('.')) 209 call assert_equal('row 1 column 3', TclEval('$win cursor')) 210 tcl $win cursor 2 4 211 call assert_equal([0, 3, 5, 0], getpos('.')) 212 call assert_equal('row 2 column 4', TclEval('$win cursor')) 213 tcl set ::vim::lbase 1 214 call assert_equal('row 3 column 5', TclEval('$win cursor')) 215 call assert_equal([0, 3, 5, 0], getpos('.')) 216 217 " test $win cursor {$var} 218 call cursor(2, 3) 219 tcl array set here [$win cursor] 220 call assert_equal([0, 2, 3, 0], getpos('.')) 221 call cursor(3, 1) 222 call assert_equal([0, 3, 1, 0], getpos('.')) 223 tcl $win cursor here 224 call assert_equal([0, 2, 3, 0], getpos('.')) 225 call cursor(3, 1) 226 call assert_equal([0, 3, 1, 0], getpos('.')) 227 tcl $win cursor $here(row) $here(column) 228 call assert_equal([0, 2, 3, 0], getpos('.')) 229 230 call assert_fails('tcl $win cursor 1 1 1', 'wrong # args:') 231 232 tcl unset win here 233 bwipe! 234endfunc 235 236" Test $win buffer 237func Test_window_buffer() 238 new Xfoo1 239 new Xfoo2 240 tcl set b2 $::vim::current(buffer) 241 tcl set w2 $::vim::current(window) 242 wincmd j 243 tcl set b1 $::vim::current(buffer) 244 tcl set w1 $::vim::current(window) 245 246 call assert_equal(TclEval('set b1'), TclEval('$w1 buffer')) 247 call assert_equal(TclEval('set b2'), TclEval('$w2 buffer')) 248 call assert_equal(string(bufnr('Xfoo1')), TclEval('[$w1 buffer] number')) 249 call assert_equal(string(bufnr('Xfoo2')), TclEval('[$w2 buffer] number')) 250 251 call assert_fails('tcl $w1 buffer x', 'wrong # args:') 252 253 tcl unset b1 b2 w1 w2 254 %bwipe 255endfunc 256 257" Test $win command 258func Test_window_command() 259 new Xfoo1 260 call setline(1, ['FOObar']) 261 new Xfoo2 262 call setline(1, ['fooBAR']) 263 tcl set w2 $::vim::current(window) 264 wincmd j 265 tcl set w1 $::vim::current(window) 266 267 tcl $w1 command "norm VU" 268 tcl $w2 command "norm Vu" 269 b! Xfoo1 270 call assert_equal('FOOBAR', getline(1)) 271 b! Xfoo2 272 call assert_equal('foobar', getline(1)) 273 274 call assert_fails('tcl $w1 command xyz', 275 \ 'E492: Not an editor command: xyz') 276 tcl $w1 command -quiet xyz 277 278 tcl unset w1 w2 279 %bwipe! 280endfunc 281 282" Test $win expr 283func Test_window_expr() 284 new Xfoo1 285 new Xfoo2 286 tcl set w2 $::vim::current(window) 287 wincmd j 288 tcl set w1 $::vim::current(window) 289 290 call assert_equal('Xfoo1', TclEval('$w1 expr bufname("%")')) 291 call assert_equal('Xfoo2', TclEval('$w2 expr bufname("%")')) 292 293 call assert_fails('tcl $w1 expr', 'wrong # args:') 294 call assert_fails('tcl $w1 expr x x', 'wrong # args:') 295 296 tcl unset w1 w2 297 %bwipe 298endfunc 299 300" Test $win option 301func Test_window_option() 302 new Xfoo1 303 new Xfoo2 304 tcl set w2 $::vim::current(window) 305 wincmd j 306 tcl set w1 $::vim::current(window) 307 308 " Test setting window option 309 tcl $w1 option syntax java 310 tcl $w2 option syntax rust 311 312 call assert_equal('java', &syntax) 313 wincmd k 314 call assert_equal('rust', &syntax) 315 316 " Test getting window option 317 call assert_equal('java', TclEval('$w1 option syntax')) 318 call assert_equal('rust', TclEval('$w2 option syntax')) 319 320 tcl unset w1 w2 321 %bwipe 322endfunc 323 324" Test $win delcmd {cmd} 325func Test_window_delcmd() 326 new 327 tcl $::vim::current(window) delcmd [list set msg "window deleted"] 328 call assert_fails('tcl set msg', "can't read \"msg\": no such variable") 329 q 330 call assert_equal('window deleted', TclEval('set msg')) 331 332 call assert_fails('tcl $::vim::current(window) delcmd', 'wrong # args') 333 334 tcl unset msg 335 bwipe 336endfunc 337 338" Test $buf name 339func Test_buffer_name() 340 " Test buffer name with a named buffer 341 new Xfoo 342 call assert_equal(expand('%:p'), TclEval('$::vim::current(buffer) name')) 343 bwipe 344 345 " Test buffer name with an unnamed buffer 346 new 347 call assert_equal('', TclEval('$::vim::current(buffer) name')) 348 349 call assert_fails('tcl $::vim::current(buffer) name x', 'wrong # args:') 350 351 bwipe 352endfunc 353 354" Test $buf number 355func Test_buffer_number() 356 new 357 call assert_equal(string(bufnr('%')), TclEval('$::vim::current(buffer) number')) 358 new 359 call assert_equal(string(bufnr('%')), TclEval('$::vim::current(buffer) number')) 360 361 call assert_fails('tcl $::vim::current(buffer) number x', 'wrong # args:') 362 363 %bwipe 364endfunc 365 366" Test $buf count and $buf last 367func Test_buffer_count() 368 new 369 call setline(1, ['one', 'two', 'three']) 370 call assert_equal('3', TclEval('$::vim::current(buffer) count')) 371 call assert_equal('3', TclEval('$::vim::current(buffer) last')) 372 373 " Check that $buf count and $buf last differ when ::vim::lbase is 0. 374 tcl set ::vim::lbase 0 375 call assert_equal('3', TclEval('$::vim::current(buffer) count')) 376 call assert_equal('2', TclEval('$::vim::current(buffer) last')) 377 378 call assert_fails('tcl $::vim::current(buffer) count x', 'wrong # args:') 379 call assert_fails('tcl $::vim::current(buffer) last x', 'wrong # args:') 380 381 tcl set ::vim::lbase 1 382 bwipe! 383endfunc 384 385" Test $buf delete (delete line(s) in buffer) 386func Test_buffer_delete() 387 new 388 call setline(1, ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight']) 389 tcl $::vim::current(buffer) delete 4 6 390 tcl $::vim::current(buffer) delete 2 391 call assert_equal(['one', 'three', 'seven', 'eight'], getline(1, '$')) 392 393 call assert_fails('tcl $::vim::current(buffer) delete -1', 'line number out of range') 394 call assert_fails('tcl $::vim::current(buffer) delete 0', 'line number out of range') 395 call assert_fails('tcl $::vim::current(buffer) delete 5', 'line number out of range') 396 397 call assert_fails('tcl $::vim::current(buffer) delete', 'wrong # args:') 398 call assert_fails('tcl $::vim::current(buffer) delete 1 2 3', 'wrong # args:') 399 400 bwipe! 401endfunc 402 403" Test $buf insert (insert line(s) in buffer) 404func Test_buffer_insert() 405 new 406 tcl set buf $::vim::current(buffer) 407 tcl $buf insert 1 "first" 408 tcl $buf insert 2 "second" 409 tcl $buf insert 2 "third" 410 tcl $buf insert 4 "fourth" 411 tcl $buf insert 1 "fifth" 412 call assert_equal(['fifth', 'first', 'third', 'second', 'fourth', ''], getline(1, '$')) 413 414 call assert_fails('tcl $buf insert -1 "x"', 'line number out of range') 415 call assert_fails('tcl $buf insert 0 "x"', 'line number out of range') 416 call assert_fails('tcl $buf insert 7 "x"', 'line number out of range') 417 418 tcl unset buf 419 bwipe! 420endfunc 421 422" Test $buf append (append line in buffer) 423func Test_buffer_append() 424 new 425 tcl set buf $::vim::current(buffer) 426 tcl $buf append 1 "first" 427 tcl $buf append 2 "second" 428 tcl $buf append 2 "third" 429 tcl $buf append 4 "fourth" 430 tcl $buf append 1 "fifth" 431 call assert_equal(['', 'fifth', 'first', 'third', 'second', 'fourth'], getline(1, '$')) 432 433 call assert_fails('tcl $buf append -1 "x"', 'line number out of range') 434 call assert_fails('tcl $buf append 0 "x"', 'line number out of range') 435 call assert_fails('tcl $buf append 7 "x"', 'line number out of range') 436 437 call assert_fails('tcl $buf append', 'wrong # args:') 438 call assert_fails('tcl $buf append 1 x x', 'wrong # args:') 439 440 tcl unset buf 441 bwipe! 442endfunc 443 444" Test $buf set (replacing line(s) in a buffer) 445func Test_buffer_set() 446 new 447 call setline(1, ['line1', 'line2', 'line3', 'line4', 'line5']) 448 tcl $::vim::current(buffer) set 2 a 449 call assert_equal(['line1', 'a', 'line3', 'line4', 'line5'], getline(1, '$')) 450 tcl $::vim::current(buffer) set 3 4 b 451 call assert_equal(['line1', 'a', 'b', 'line5'], getline(1, '$')) 452 tcl $::vim::current(buffer) set 4 3 c 453 call assert_equal(['line1', 'a', 'c'], getline(1, '$')) 454 455 call assert_fails('tcl $::vim::current(buffer) set 0 "x"', 'line number out of range') 456 call assert_fails('tcl $::vim::current(buffer) set 5 "x"', 'line number out of range') 457 458 call assert_fails('tcl $::vim::current(buffer) set', 'wrong # args:') 459 bwipe! 460endfunc 461 462" Test $buf get (get line(s) from buffer) 463func Test_buffer_get() 464 new 465 call setline(1, ['first line', 'two', 'three', 'last line']) 466 tcl set buf $::vim::current(buffer) 467 468 call assert_equal('first line', TclEval('$buf get top')) 469 call assert_equal('first line', TclEval('$buf get begin')) 470 call assert_equal('last line', TclEval('$buf get bottom')) 471 call assert_equal('last line', TclEval('$buf get last')) 472 473 call assert_equal('first line', TclEval('$buf get 1')) 474 call assert_equal('two', TclEval('$buf get 2')) 475 call assert_equal('three', TclEval('$buf get 3')) 476 call assert_equal('last line', TclEval('$buf get 4')) 477 478 call assert_equal('two three', TclEval('$buf get 2 3')) 479 call assert_equal('two three', TclEval('$buf get 3 2')) 480 call assert_equal('three {last line}', TclEval('$buf get 3 last')) 481 482 call assert_fails('tcl $buf get -1', 'line number out of range') 483 call assert_fails('tcl $buf get 0', 'line number out of range') 484 call assert_fails('tcl $buf get 5', 'line number out of range') 485 call assert_fails('tcl $buf get 0 1', 'line number out of range') 486 487 call assert_fails('tcl $::vim::current(buffer) get x', 'expected integer but got "x"') 488 call assert_fails('tcl $::vim::current(buffer) get 1 1 1', 'wrong # args:') 489 490 tcl unset buf 491 bwipe! 492endfunc 493 494" Test $buf mark (get position of a mark) 495func Test_buffer_mark() 496 new 497 call setline(1, ['one', 'two', 'three', 'four']) 498 /three 499 norm! ma 500 norm! jllmB 501 502 call assert_equal('row 3 column 1', TclEval('$::vim::current(buffer) mark a')) 503 call assert_equal('row 4 column 3', TclEval('$::vim::current(buffer) mark B')) 504 505 call assert_fails('tcl $::vim::current(buffer) mark /', 'invalid mark name') 506 call assert_fails('tcl $::vim::current(buffer) mark z', 'mark not set') 507 call assert_fails('tcl $::vim::current(buffer) mark', 'wrong # args:') 508 509 delmarks aB 510 bwipe! 511endfunc 512 513" Test $buf option (test and set option in context of a buffer) 514func Test_buffer_option() 515 new Xfoo1 516 tcl set b1 $::vim::current(buffer) 517 new Xfoo2 518 tcl set b2 $::vim::current(buffer) 519 520 tcl $b1 option foldcolumn 2 521 tcl $b2 option foldcolumn 3 522 523 call assert_equal(3, &foldcolumn) 524 wincmd j 525 call assert_equal(2, &foldcolumn) 526 527 call assert_equal('2', TclEval('$b1 option foldcolumn')) 528 call assert_equal('3', TclEval('$b2 option foldcolumn')) 529 530 call assert_fails('tcl $::vim::current(buffer) option', 'wrong # args:') 531 532 set foldcolumn& 533 tcl unset b1 b2 534 %bwipe 535endfunc 536 537" Test $buf expr (evaluate vim expression) 538func Test_buffer_expr() 539 new Xfoo1 540 norm ifoo1 541 tcl set b1 $::vim::current(buffer) 542 543 new Xfoo2 544 norm ifoo2 545 tcl set b2 $::vim::current(buffer) 546 547 call assert_equal('foo1', TclEval('$b1 expr getline(1)')) 548 call assert_equal('foo2', TclEval('$b2 expr getline(1)')) 549 550 call assert_fails('tcl expr', 'wrong # args:') 551 552 tcl unset b1 b2 553 %bwipe! 554endfunc 555 556" Test $buf delcmd {cmd} (command executed when buffer is deleted) 557func Test_buffer_delcmd() 558 new Xfoo 559 split 560 tcl $::vim::current(buffer) delcmd [list set msg "buffer deleted"] 561 q 562 call assert_fails('tcl set msg', "can't read \"msg\": no such variable") 563 q 564 call assert_equal('buffer deleted', TclEval('set msg')) 565 566 call assert_fails('tcl $::vim::current(window) delcmd', 'wrong # args') 567 call assert_fails('tcl $::vim::current(window) delcmd x x', 'wrong # args') 568 569 tcl unset msg 570 %bwipe 571endfunc 572 573func Test_vim_current() 574 " Only test errors as ::vim::current(...) is already indirectly 575 " tested by many other tests. 576 call assert_fails('tcl $::vim::current(buffer)', 'wrong # args:') 577 call assert_fails('tcl $::vim::current(window)', 'wrong # args:') 578endfunc 579 580" Test $buf windows (windows list of a buffer) 581func Test_buffer_windows() 582 new Xfoo 583 split 584 new Xbar 585 split 586 vsplit 587 588 tcl set bar_wl [$::vim::current(buffer) windows] 589 2wincmd j 590 tcl set foo_wl [$::vim::current(buffer) windows] 591 592 call assert_equal('2', TclEval('llength $foo_wl')) 593 call assert_equal('3', TclEval('llength $bar_wl')) 594 595 call assert_fails('tcl $::vim::current(buffer) windows x', 'wrong # args:') 596 597 tcl unset bar_wl foo_wl 598 %bwipe 599endfunc 600 601" Test :tclfile 602func Test_tclfile() 603 call delete('Xtcl_file') 604 call writefile(['set pi [format "%.2f" [expr acos(-1.0)]]'], 'Xtcl_file') 605 call setfperm('Xtcl_file', 'r-xr-xr-x') 606 607 tclfile Xtcl_file 608 call assert_equal('3.14', TclEval('set pi')) 609 610 tcl unset pi 611 call delete('Xtcl_file') 612endfunc 613 614" Test :tclfile with syntax error in tcl script 615func Test_tclfile_error() 616 call delete('Xtcl_file') 617 call writefile(['xyz'], 'Xtcl_file') 618 call setfperm('Xtcl_file', 'r-xr-xr-x') 619 620 call assert_fails('tclfile Xtcl_file', 'invalid command name "xyz"') 621 622 call delete('Xtcl_file') 623endfunc 624 625" Test exiting current Tcl interprepter and re-creating one. 626func Test_tcl_exit() 627 tcl set foo "foo" 628 call assert_fails('tcl exit 3', 'E572: exit code 3') 629 630 " The Tcl interpreter should have been deleted and a new one 631 " is re-created with the next :tcl command. 632 call assert_fails('tcl set foo', "can't read \"foo\": no such variable") 633 tcl set bar "bar" 634 call assert_equal('bar', TclEval('set bar')) 635 636 tcl unset bar 637endfunc 638