1" Test for signs 2 3if !has('signs') 4 finish 5endif 6 7func Test_sign() 8 new 9 call setline(1, ['a', 'b', 'c', 'd']) 10 11 " Define some signs. 12 " We can specify icons even if not all versions of vim support icons as 13 " icon is ignored when not supported. "(not supported)" is shown after 14 " the icon name when listing signs. 15 sign define Sign1 text=x 16 try 17 sign define Sign2 text=xy texthl=Title linehl=Error 18 \ icon=../../pixmaps/stock_vim_find_help.png 19 catch /E255:/ 20 " Ignore error: E255: Couldn't read in sign data! 21 " This error can happen when running in the GUI. 22 " Some gui like Motif do not support the png icon format. 23 endtry 24 25 " Test listing signs. 26 let a=execute('sign list') 27 call assert_match('^\nsign Sign1 text=x \nsign Sign2 ' . 28 \ 'icon=../../pixmaps/stock_vim_find_help.png .*text=xy ' . 29 \ 'linehl=Error texthl=Title$', a) 30 31 let a=execute('sign list Sign1') 32 call assert_equal("\nsign Sign1 text=x ", a) 33 34 " Split the window to the bottom to verify sign jump will stay in the 35 " current window if the buffer is displayed there. 36 let bn = bufnr('%') 37 let wn = winnr() 38 exe 'sign place 41 line=3 name=Sign1 buffer=' . bn 39 1 40 bot split 41 exe 'sign jump 41 buffer=' . bufnr('%') 42 call assert_equal('c', getline('.')) 43 call assert_equal(3, winnr()) 44 call assert_equal(bn, bufnr('%')) 45 call assert_notequal(wn, winnr()) 46 47 " Create a new buffer and check that ":sign jump" switches to the old buffer. 48 1 49 new foo 50 call assert_notequal(bn, bufnr('%')) 51 exe 'sign jump 41 buffer=' . bn 52 call assert_equal(bn, bufnr('%')) 53 call assert_equal('c', getline('.')) 54 55 " Redraw to make sure that screen redraw with sign gets exercised, 56 " with and without 'rightleft'. 57 if has('rightleft') 58 set rightleft 59 redraw 60 set norightleft 61 endif 62 redraw 63 64 " Check that we can't change sign. 65 call assert_fails("sign place 40 name=Sign1 buffer=" . bufnr('%'), 'E885:') 66 67 " Check placed signs 68 let a=execute('sign place') 69 call assert_equal("\n--- Signs ---\nSigns for [NULL]:\n" . 70 \ " line=3 id=41 name=Sign1 priority=10\n", a) 71 72 " Unplace the sign and try jumping to it again should fail. 73 sign unplace 41 74 1 75 call assert_fails("sign jump 41 buffer=" . bufnr('%'), 'E157:') 76 call assert_equal('a', getline('.')) 77 78 " Unplace sign on current line. 79 exe 'sign place 42 line=4 name=Sign2 buffer=' . bufnr('%') 80 4 81 sign unplace 82 let a=execute('sign place') 83 call assert_equal("\n--- Signs ---\n", a) 84 85 " Try again to unplace sign on current line, it should fail this time. 86 call assert_fails('sign unplace', 'E159:') 87 88 " Unplace all signs. 89 exe 'sign place 41 line=3 name=Sign1 buffer=' . bufnr('%') 90 sign unplace * 91 let a=execute('sign place') 92 call assert_equal("\n--- Signs ---\n", a) 93 94 " Place a sign without specifying the filename or buffer 95 sign place 77 line=9 name=Sign2 96 let a=execute('sign place') 97 call assert_equal("\n--- Signs ---\nSigns for [NULL]:\n" . 98 \ " line=9 id=77 name=Sign2 priority=10\n", a) 99 sign unplace * 100 101 " Check :jump with file=... 102 edit foo 103 call setline(1, ['A', 'B', 'C', 'D']) 104 105 try 106 sign define Sign3 text=y texthl=DoesNotExist linehl=DoesNotExist 107 \ icon=doesnotexist.xpm 108 catch /E255:/ 109 " ignore error: E255: it can happens for guis. 110 endtry 111 112 let fn = expand('%:p') 113 exe 'sign place 43 line=2 name=Sign3 file=' . fn 114 edit bar 115 call assert_notequal(fn, expand('%:p')) 116 exe 'sign jump 43 file=' . fn 117 call assert_equal('B', getline('.')) 118 119 " Check for jumping to a sign in a hidden buffer 120 enew! | only! 121 edit foo 122 call setline(1, ['A', 'B', 'C', 'D']) 123 let fn = expand('%:p') 124 exe 'sign place 21 line=3 name=Sign3 file=' . fn 125 hide edit bar 126 exe 'sign jump 21 file=' . fn 127 call assert_equal('C', getline('.')) 128 129 " can't define a sign with a non-printable character as text 130 call assert_fails("sign define Sign4 text=\e linehl=Comment", 'E239:') 131 call assert_fails("sign define Sign4 text=a\e linehl=Comment", 'E239:') 132 call assert_fails("sign define Sign4 text=\ea linehl=Comment", 'E239:') 133 134 " Only 1 or 2 character text is allowed 135 call assert_fails("sign define Sign4 text=abc linehl=Comment", 'E239:') 136 call assert_fails("sign define Sign4 text= linehl=Comment", 'E239:') 137 call assert_fails("sign define Sign4 text=\\ ab linehl=Comment", 'E239:') 138 139 " define sign with whitespace 140 sign define Sign4 text=\ X linehl=Comment 141 sign undefine Sign4 142 sign define Sign4 linehl=Comment text=\ X 143 sign undefine Sign4 144 145 sign define Sign5 text=X\ linehl=Comment 146 sign undefine Sign5 147 sign define Sign5 linehl=Comment text=X\ 148 sign undefine Sign5 149 150 " define sign with backslash 151 sign define Sign4 text=\\\\ linehl=Comment 152 sign undefine Sign4 153 sign define Sign4 text=\\ linehl=Comment 154 sign undefine Sign4 155 156 " define a sign with a leading 0 in the name 157 sign unplace * 158 sign define 004 text=#> linehl=Comment 159 let a = execute('sign list 4') 160 call assert_equal("\nsign 4 text=#> linehl=Comment", a) 161 exe 'sign place 20 line=3 name=004 buffer=' . bufnr('') 162 let a = execute('sign place') 163 call assert_equal("\n--- Signs ---\nSigns for foo:\n" . 164 \ " line=3 id=20 name=4 priority=10\n", a) 165 exe 'sign unplace 20 buffer=' . bufnr('') 166 sign undefine 004 167 call assert_fails('sign list 4', 'E155:') 168 169 " After undefining the sign, we should no longer be able to place it. 170 sign undefine Sign1 171 sign undefine Sign2 172 sign undefine Sign3 173 call assert_fails("sign place 41 line=3 name=Sign1 buffer=" . 174 \ bufnr('%'), 'E155:') 175endfunc 176 177" Undefining placed sign is not recommended. 178" Quoting :help sign 179" 180" :sign undefine {name} 181" Deletes a previously defined sign. If signs with this {name} 182" are still placed this will cause trouble. 183func Test_sign_undefine_still_placed() 184 new foobar 185 sign define Sign text=x 186 exe 'sign place 41 line=1 name=Sign buffer=' . bufnr('%') 187 sign undefine Sign 188 189 " Listing placed sign should show that sign is deleted. 190 let a=execute('sign place') 191 call assert_equal("\n--- Signs ---\nSigns for foobar:\n" . 192 \ " line=1 id=41 name=[Deleted] priority=10\n", a) 193 194 sign unplace 41 195 let a=execute('sign place') 196 call assert_equal("\n--- Signs ---\n", a) 197endfunc 198 199func Test_sign_completion() 200 sign define Sign1 text=x 201 sign define Sign2 text=y 202 203 call feedkeys(":sign \<C-A>\<C-B>\"\<CR>", 'tx') 204 call assert_equal('"sign define jump list place undefine unplace', @:) 205 206 call feedkeys(":sign define Sign \<C-A>\<C-B>\"\<CR>", 'tx') 207 call assert_equal('"sign define Sign icon= linehl= text= texthl=', @:) 208 209 call feedkeys(":sign define Sign linehl=Spell\<C-A>\<C-B>\"\<CR>", 'tx') 210 call assert_equal('"sign define Sign linehl=SpellBad SpellCap ' . 211 \ 'SpellLocal SpellRare', @:) 212 213 call feedkeys(":sign define Sign texthl=Spell\<C-A>\<C-B>\"\<CR>", 'tx') 214 call assert_equal('"sign define Sign texthl=SpellBad SpellCap ' . 215 \ 'SpellLocal SpellRare', @:) 216 217 call writefile(repeat(["Sun is shining"], 30), "XsignOne") 218 call writefile(repeat(["Sky is blue"], 30), "XsignTwo") 219 call feedkeys(":sign define Sign icon=Xsig\<C-A>\<C-B>\"\<CR>", 'tx') 220 call assert_equal('"sign define Sign icon=XsignOne XsignTwo', @:) 221 222 " Test for completion of arguments to ':sign undefine' 223 call feedkeys(":sign undefine \<C-A>\<C-B>\"\<CR>", 'tx') 224 call assert_equal('"sign undefine Sign1 Sign2', @:) 225 226 call feedkeys(":sign place 1 \<C-A>\<C-B>\"\<CR>", 'tx') 227 call assert_equal('"sign place 1 buffer= file= group= line= name= priority=', 228 \ @:) 229 230 call feedkeys(":sign place 1 name=\<C-A>\<C-B>\"\<CR>", 'tx') 231 call assert_equal('"sign place 1 name=Sign1 Sign2', @:) 232 233 edit XsignOne 234 sign place 1 name=Sign1 line=5 235 sign place 1 name=Sign1 group=g1 line=10 236 edit XsignTwo 237 sign place 1 name=Sign2 group=g2 line=15 238 239 " Test for completion of group= and file= arguments to ':sign place' 240 call feedkeys(":sign place 1 name=Sign1 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx') 241 call assert_equal('"sign place 1 name=Sign1 file=XsignOne XsignTwo', @:) 242 call feedkeys(":sign place 1 name=Sign1 group=\<C-A>\<C-B>\"\<CR>", 'tx') 243 call assert_equal('"sign place 1 name=Sign1 group=g1 g2', @:) 244 245 " Test for completion of arguments to 'sign place' without sign identifier 246 call feedkeys(":sign place \<C-A>\<C-B>\"\<CR>", 'tx') 247 call assert_equal('"sign place buffer= file= group=', @:) 248 call feedkeys(":sign place file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx') 249 call assert_equal('"sign place file=XsignOne XsignTwo', @:) 250 call feedkeys(":sign place group=\<C-A>\<C-B>\"\<CR>", 'tx') 251 call assert_equal('"sign place group=g1 g2', @:) 252 call feedkeys(":sign place group=g1 file=\<C-A>\<C-B>\"\<CR>", 'tx') 253 call assert_equal('"sign place group=g1 file=XsignOne XsignTwo', @:) 254 255 " Test for completion of arguments to ':sign unplace' 256 call feedkeys(":sign unplace 1 \<C-A>\<C-B>\"\<CR>", 'tx') 257 call assert_equal('"sign unplace 1 buffer= file= group=', @:) 258 call feedkeys(":sign unplace 1 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx') 259 call assert_equal('"sign unplace 1 file=XsignOne XsignTwo', @:) 260 call feedkeys(":sign unplace 1 group=\<C-A>\<C-B>\"\<CR>", 'tx') 261 call assert_equal('"sign unplace 1 group=g1 g2', @:) 262 call feedkeys(":sign unplace 1 group=g2 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx') 263 call assert_equal('"sign unplace 1 group=g2 file=XsignOne XsignTwo', @:) 264 265 " Test for completion of arguments to ':sign list' 266 call feedkeys(":sign list \<C-A>\<C-B>\"\<CR>", 'tx') 267 call assert_equal('"sign list Sign1 Sign2', @:) 268 269 " Test for completion of arguments to ':sign jump' 270 call feedkeys(":sign jump 1 \<C-A>\<C-B>\"\<CR>", 'tx') 271 call assert_equal('"sign jump 1 buffer= file= group=', @:) 272 call feedkeys(":sign jump 1 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx') 273 call assert_equal('"sign jump 1 file=XsignOne XsignTwo', @:) 274 call feedkeys(":sign jump 1 group=\<C-A>\<C-B>\"\<CR>", 'tx') 275 call assert_equal('"sign jump 1 group=g1 g2', @:) 276 277 " Error cases 278 call feedkeys(":sign here\<C-A>\<C-B>\"\<CR>", 'tx') 279 call assert_equal('"sign here', @:) 280 call feedkeys(":sign define Sign here=\<C-A>\<C-B>\"\<CR>", 'tx') 281 call assert_equal("\"sign define Sign here=\<C-A>", @:) 282 call feedkeys(":sign place 1 here=\<C-A>\<C-B>\"\<CR>", 'tx') 283 call assert_equal("\"sign place 1 here=\<C-A>", @:) 284 call feedkeys(":sign jump 1 here=\<C-A>\<C-B>\"\<CR>", 'tx') 285 call assert_equal("\"sign jump 1 here=\<C-A>", @:) 286 call feedkeys(":sign here there\<C-A>\<C-B>\"\<CR>", 'tx') 287 call assert_equal("\"sign here there\<C-A>", @:) 288 call feedkeys(":sign here there=\<C-A>\<C-B>\"\<CR>", 'tx') 289 call assert_equal("\"sign here there=\<C-A>", @:) 290 291 sign unplace * group=* 292 sign undefine Sign1 293 sign undefine Sign2 294 enew 295 call delete('XsignOne') 296 call delete('XsignTwo') 297endfunc 298 299func Test_sign_invalid_commands() 300 sign define Sign1 text=x 301 302 call assert_fails('sign', 'E471:') 303 call assert_fails('sign jump', 'E471:') 304 call assert_fails('sign xxx', 'E160:') 305 call assert_fails('sign define', 'E156:') 306 call assert_fails('sign define Sign1 xxx', 'E475:') 307 call assert_fails('sign undefine', 'E156:') 308 call assert_fails('sign list xxx', 'E155:') 309 call assert_fails('sign place 1 buffer=999', 'E158:') 310 call assert_fails('sign place 1 name=Sign1 buffer=999', 'E158:') 311 call assert_fails('sign place buffer=999', 'E158:') 312 call assert_fails('sign jump buffer=999', 'E158:') 313 call assert_fails('sign jump 1 file=', 'E158:') 314 call assert_fails('sign jump 1 group=', 'E474:') 315 call assert_fails('sign jump 1 name=', 'E474:') 316 call assert_fails('sign jump 1 name=Sign1', 'E474:') 317 call assert_fails('sign jump 1 line=100', '474:') 318 call assert_fails('sign define Sign2 text=', 'E239:') 319 " Non-numeric identifier for :sign place 320 call assert_fails("sign place abc line=3 name=Sign1 buffer=" . bufnr(''), 321 \ 'E474:') 322 " Non-numeric identifier for :sign unplace 323 call assert_fails("sign unplace abc name=Sign1 buffer=" . bufnr(''), 324 \ 'E474:') 325 " Number followed by an alphabet as sign identifier for :sign place 326 call assert_fails("sign place 1abc line=3 name=Sign1 buffer=" . bufnr(''), 327 \ 'E474:') 328 " Number followed by an alphabet as sign identifier for :sign unplace 329 call assert_fails("sign unplace 2abc name=Sign1 buffer=" . bufnr(''), 330 \ 'E474:') 331 " Sign identifier and '*' for :sign unplace 332 call assert_fails("sign unplace 2 *", 'E474:') 333 " Trailing characters after buffer number for :sign place 334 call assert_fails("sign place 1 line=3 name=Sign1 buffer=" . 335 \ bufnr('%') . 'xxx', 'E488:') 336 " Trailing characters after buffer number for :sign unplace 337 call assert_fails("sign unplace 1 buffer=" . bufnr('%') . 'xxx', 'E488:') 338 call assert_fails("sign unplace * buffer=" . bufnr('%') . 'xxx', 'E488:') 339 call assert_fails("sign unplace 1 xxx", 'E474:') 340 call assert_fails("sign unplace * xxx", 'E474:') 341 call assert_fails("sign unplace xxx", 'E474:') 342 " Placing a sign without line number 343 call assert_fails("sign place name=Sign1 buffer=" . bufnr('%'), 'E474:') 344 " Placing a sign without sign name 345 call assert_fails("sign place line=10 buffer=" . bufnr('%'), 'E474:') 346 " Unplacing a sign with line number 347 call assert_fails("sign unplace 2 line=10 buffer=" . bufnr('%'), 'E474:') 348 " Unplacing a sign with sign name 349 call assert_fails("sign unplace 2 name=Sign1 buffer=" . bufnr('%'), 'E474:') 350 " Placing a sign without sign name 351 call assert_fails("sign place 2 line=3 buffer=" . bufnr('%'), 'E474:') 352 " Placing a sign with only sign identifier 353 call assert_fails("sign place 2", 'E474:') 354 " Placing a sign with only a name 355 call assert_fails("sign place abc", 'E474:') 356 " Placing a sign with only line number 357 call assert_fails("sign place 5 line=3", 'E474:') 358 " Placing a sign with only sign group 359 call assert_fails("sign place 5 group=g1", 'E474:') 360 call assert_fails("sign place 5 group=*", 'E474:') 361 " Placing a sign with only sign priority 362 call assert_fails("sign place 5 priority=10", 'E474:') 363 364 sign undefine Sign1 365endfunc 366 367func Test_sign_delete_buffer() 368 new 369 sign define Sign text=x 370 let bufnr = bufnr('%') 371 new 372 exe 'bd ' . bufnr 373 exe 'sign place 61 line=3 name=Sign buffer=' . bufnr 374 call assert_fails('sign jump 61 buffer=' . bufnr, 'E934:') 375 sign unplace 61 376 sign undefine Sign 377endfunc 378 379" Test for Vim script functions for managing signs 380func Test_sign_funcs() 381 " Remove all the signs 382 call sign_unplace('*') 383 call sign_undefine() 384 385 " Tests for sign_define() 386 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'} 387 call assert_equal(0, sign_define("sign1", attr)) 388 call assert_equal([{'name' : 'sign1', 'texthl' : 'Error', 389 \ 'linehl' : 'Search', 'text' : '=>'}], sign_getdefined()) 390 391 " Define a new sign without attributes and then update it 392 call sign_define("sign2") 393 let attr = {'text' : '!!', 'linehl' : 'DiffAdd', 'texthl' : 'DiffChange', 394 \ 'icon' : 'sign2.ico'} 395 try 396 call sign_define("sign2", attr) 397 catch /E255:/ 398 " ignore error: E255: Couldn't read in sign data! 399 " This error can happen when running in gui. 400 endtry 401 call assert_equal([{'name' : 'sign2', 'texthl' : 'DiffChange', 402 \ 'linehl' : 'DiffAdd', 'text' : '!!', 'icon' : 'sign2.ico'}], 403 \ sign_getdefined("sign2")) 404 405 " Test for a sign name with digits 406 call assert_equal(0, sign_define(0002, {'linehl' : 'StatusLine'})) 407 call assert_equal([{'name' : '2', 'linehl' : 'StatusLine'}], 408 \ sign_getdefined(0002)) 409 call sign_undefine(0002) 410 411 " Tests for invalid arguments to sign_define() 412 call assert_fails('call sign_define("sign4", {"text" : "===>"})', 'E239:') 413 call assert_fails('call sign_define("sign5", {"text" : ""})', 'E239:') 414 call assert_fails('call sign_define([])', 'E730:') 415 call assert_fails('call sign_define("sign6", [])', 'E715:') 416 417 " Tests for sign_getdefined() 418 call assert_equal([], sign_getdefined("none")) 419 call assert_fails('call sign_getdefined({})', 'E731:') 420 421 " Tests for sign_place() 422 call writefile(repeat(["Sun is shining"], 30), "Xsign") 423 edit Xsign 424 425 call assert_equal(10, sign_place(10, '', 'sign1', 'Xsign', 426 \ {'lnum' : 20})) 427 call assert_equal([{'bufnr' : bufnr(''), 'signs' : 428 \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1', 429 \ 'priority' : 10}]}], sign_getplaced('Xsign')) 430 call assert_equal([{'bufnr' : bufnr(''), 'signs' : 431 \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1', 432 \ 'priority' : 10}]}], 433 \ sign_getplaced('%', {'lnum' : 20})) 434 call assert_equal([{'bufnr' : bufnr(''), 'signs' : 435 \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1', 436 \ 'priority' : 10}]}], 437 \ sign_getplaced('', {'id' : 10})) 438 439 " Tests for invalid arguments to sign_place() 440 call assert_fails('call sign_place([], "", "mySign", 1)', 'E745:') 441 call assert_fails('call sign_place(5, "", "mySign", -1)', 'E158:') 442 call assert_fails('call sign_place(-1, "", "sign1", "Xsign", [])', 443 \ 'E474:') 444 call assert_fails('call sign_place(-1, "", "sign1", "Xsign", 445 \ {"lnum" : 30})', 'E474:') 446 call assert_fails('call sign_place(10, "", "xsign1x", "Xsign", 447 \ {"lnum" : 30})', 'E155:') 448 call assert_fails('call sign_place(10, "", "", "Xsign", 449 \ {"lnum" : 30})', 'E155:') 450 call assert_fails('call sign_place(10, "", [], "Xsign", 451 \ {"lnum" : 30})', 'E730:') 452 call assert_fails('call sign_place(5, "", "sign1", "abcxyz.xxx", 453 \ {"lnum" : 10})', 'E158:') 454 call assert_fails('call sign_place(5, "", "sign1", "@", {"lnum" : 10})', 455 \ 'E158:') 456 call assert_fails('call sign_place(5, "", "sign1", [], {"lnum" : 10})', 457 \ 'E158:') 458 call assert_fails('call sign_place(21, "", "sign1", "Xsign", 459 \ {"lnum" : -1})', 'E885:') 460 call assert_fails('call sign_place(22, "", "sign1", "Xsign", 461 \ {"lnum" : 0})', 'E885:') 462 call assert_fails('call sign_place(22, "", "sign1", "Xsign", 463 \ {"lnum" : []})', 'E745:') 464 call assert_equal(-1, sign_place(1, "*", "sign1", "Xsign", {"lnum" : 10})) 465 466 " Tests for sign_getplaced() 467 call assert_equal([{'bufnr' : bufnr(''), 'signs' : 468 \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1', 469 \ 'priority' : 10}]}], 470 \ sign_getplaced(bufnr('Xsign'))) 471 call assert_equal([{'bufnr' : bufnr(''), 'signs' : 472 \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1', 473 \ 'priority' : 10}]}], 474 \ sign_getplaced()) 475 call assert_fails("call sign_getplaced('dummy.sign')", 'E158:') 476 call assert_fails('call sign_getplaced("&")', 'E158:') 477 call assert_fails('call sign_getplaced(-1)', 'E158:') 478 call assert_fails('call sign_getplaced("Xsign", [])', 'E715:') 479 call assert_equal([{'bufnr' : bufnr(''), 'signs' : []}], 480 \ sign_getplaced('Xsign', {'lnum' : 1000000})) 481 call assert_fails("call sign_getplaced('Xsign', {'lnum' : []})", 482 \ 'E745:') 483 call assert_equal([{'bufnr' : bufnr(''), 'signs' : []}], 484 \ sign_getplaced('Xsign', {'id' : 44})) 485 call assert_fails("call sign_getplaced('Xsign', {'id' : []})", 486 \ 'E745:') 487 488 " Tests for sign_unplace() 489 call sign_place(20, '', 'sign2', 'Xsign', {"lnum" : 30}) 490 call assert_equal(0, sign_unplace('', 491 \ {'id' : 20, 'buffer' : 'Xsign'})) 492 call assert_equal(-1, sign_unplace('', 493 \ {'id' : 30, 'buffer' : 'Xsign'})) 494 call sign_place(20, '', 'sign2', 'Xsign', {"lnum" : 30}) 495 call assert_fails("call sign_unplace('', 496 \ {'id' : 20, 'buffer' : 'buffer.c'})", 'E158:') 497 call assert_fails("call sign_unplace('', 498 \ {'id' : 20, 'buffer' : '&'})", 'E158:') 499 call assert_fails("call sign_unplace('g1', 500 \ {'id' : 20, 'buffer' : 200})", 'E158:') 501 call assert_fails("call sign_unplace('g1', 'mySign')", 'E715:') 502 503 " Tests for sign_undefine() 504 call assert_equal(0, sign_undefine("sign1")) 505 call assert_equal([], sign_getdefined("sign1")) 506 call assert_fails('call sign_undefine("none")', 'E155:') 507 call assert_fails('call sign_undefine([])', 'E730:') 508 509 call delete("Xsign") 510 call sign_unplace('*') 511 call sign_undefine() 512 enew | only 513endfunc 514 515" Tests for sign groups 516func Test_sign_group() 517 enew | only 518 " Remove all the signs 519 call sign_unplace('*') 520 call sign_undefine() 521 522 call writefile(repeat(["Sun is shining"], 30), "Xsign") 523 524 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'} 525 call assert_equal(0, sign_define("sign1", attr)) 526 527 edit Xsign 528 let bnum = bufnr('%') 529 530 " Error case 531 call assert_fails("call sign_place(5, [], 'sign1', 'Xsign', 532 \ {'lnum' : 30})", 'E730:') 533 534 " place three signs with the same identifier. One in the global group and 535 " others in the named groups 536 call assert_equal(5, sign_place(5, '', 'sign1', 'Xsign', 537 \ {'lnum' : 10})) 538 call assert_equal(5, sign_place(5, 'g1', 'sign1', bnum, {'lnum' : 20})) 539 call assert_equal(5, sign_place(5, 'g2', 'sign1', bnum, {'lnum' : 30})) 540 541 " Test for sign_getplaced() with group 542 let s = sign_getplaced('Xsign') 543 call assert_equal(1, len(s[0].signs)) 544 call assert_equal(s[0].signs[0].group, '') 545 let s = sign_getplaced(bnum, {'group' : ''}) 546 call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10, 547 \ 'priority' : 10}], s[0].signs) 548 call assert_equal(1, len(s[0].signs)) 549 let s = sign_getplaced(bnum, {'group' : 'g2'}) 550 call assert_equal('g2', s[0].signs[0].group) 551 let s = sign_getplaced(bnum, {'group' : 'g3'}) 552 call assert_equal([], s[0].signs) 553 let s = sign_getplaced(bnum, {'group' : '*'}) 554 call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10, 555 \ 'priority' : 10}, 556 \ {'id' : 5, 'group' : 'g1', 'name' : 'sign1', 'lnum' : 20, 557 \ 'priority' : 10}, 558 \ {'id' : 5, 'group' : 'g2', 'name' : 'sign1', 'lnum' : 30, 559 \ 'priority' : 10}], 560 \ s[0].signs) 561 562 " Test for sign_getplaced() with id 563 let s = sign_getplaced(bnum, {'id' : 5}) 564 call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10, 565 \ 'priority' : 10}], 566 \ s[0].signs) 567 let s = sign_getplaced(bnum, {'id' : 5, 'group' : 'g2'}) 568 call assert_equal( 569 \ [{'id' : 5, 'name' : 'sign1', 'lnum' : 30, 'group' : 'g2', 570 \ 'priority' : 10}], 571 \ s[0].signs) 572 let s = sign_getplaced(bnum, {'id' : 5, 'group' : '*'}) 573 call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10, 574 \ 'priority' : 10}, 575 \ {'id' : 5, 'group' : 'g1', 'name' : 'sign1', 'lnum' : 20, 576 \ 'priority' : 10}, 577 \ {'id' : 5, 'group' : 'g2', 'name' : 'sign1', 'lnum' : 30, 578 \ 'priority' : 10}], 579 \ s[0].signs) 580 let s = sign_getplaced(bnum, {'id' : 5, 'group' : 'g3'}) 581 call assert_equal([], s[0].signs) 582 583 " Test for sign_getplaced() with lnum 584 let s = sign_getplaced(bnum, {'lnum' : 20}) 585 call assert_equal([], s[0].signs) 586 let s = sign_getplaced(bnum, {'lnum' : 20, 'group' : 'g1'}) 587 call assert_equal( 588 \ [{'id' : 5, 'name' : 'sign1', 'lnum' : 20, 'group' : 'g1', 589 \ 'priority' : 10}], 590 \ s[0].signs) 591 let s = sign_getplaced(bnum, {'lnum' : 30, 'group' : '*'}) 592 call assert_equal( 593 \ [{'id' : 5, 'name' : 'sign1', 'lnum' : 30, 'group' : 'g2', 594 \ 'priority' : 10}], 595 \ s[0].signs) 596 let s = sign_getplaced(bnum, {'lnum' : 40, 'group' : '*'}) 597 call assert_equal([], s[0].signs) 598 599 " Error case 600 call assert_fails("call sign_getplaced(bnum, {'group' : []})", 601 \ 'E730:') 602 603 " Clear the sign in global group 604 call sign_unplace('', {'id' : 5, 'buffer' : bnum}) 605 let s = sign_getplaced(bnum, {'group' : '*'}) 606 call assert_equal([ 607 \ {'id' : 5, 'name' : 'sign1', 'lnum' : 20, 'group' : 'g1', 608 \ 'priority' : 10}, 609 \ {'id' : 5, 'name' : 'sign1', 'lnum' : 30, 'group' : 'g2', 610 \ 'priority' : 10}], 611 \ s[0].signs) 612 613 " Clear the sign in one of the groups 614 call sign_unplace('g1', {'buffer' : 'Xsign'}) 615 let s = sign_getplaced(bnum, {'group' : '*'}) 616 call assert_equal([ 617 \ {'id' : 5, 'name' : 'sign1', 'lnum' : 30, 'group' : 'g2', 618 \ 'priority' : 10}], 619 \ s[0].signs) 620 621 " Clear all the signs from the buffer 622 call sign_unplace('*', {'buffer' : bnum}) 623 call assert_equal([], sign_getplaced(bnum, {'group' : '*'})[0].signs) 624 625 " Clear sign across groups using an identifier 626 call sign_place(25, '', 'sign1', bnum, {'lnum' : 10}) 627 call sign_place(25, 'g1', 'sign1', bnum, {'lnum' : 11}) 628 call sign_place(25, 'g2', 'sign1', bnum, {'lnum' : 12}) 629 call assert_equal(0, sign_unplace('*', {'id' : 25})) 630 call assert_equal([], sign_getplaced(bnum, {'group' : '*'})[0].signs) 631 632 " Error case 633 call assert_fails("call sign_unplace([])", 'E474:') 634 635 " Place a sign in the global group and try to delete it using a group 636 call assert_equal(5, sign_place(5, '', 'sign1', bnum, {'lnum' : 10})) 637 call assert_equal(-1, sign_unplace('g1', {'id' : 5})) 638 639 " Place signs in multiple groups and delete all the signs in one of the 640 " group 641 call assert_equal(5, sign_place(5, '', 'sign1', bnum, {'lnum' : 10})) 642 call assert_equal(6, sign_place(6, '', 'sign1', bnum, {'lnum' : 11})) 643 call assert_equal(5, sign_place(5, 'g1', 'sign1', bnum, {'lnum' : 10})) 644 call assert_equal(5, sign_place(5, 'g2', 'sign1', bnum, {'lnum' : 10})) 645 call assert_equal(6, sign_place(6, 'g1', 'sign1', bnum, {'lnum' : 11})) 646 call assert_equal(6, sign_place(6, 'g2', 'sign1', bnum, {'lnum' : 11})) 647 call assert_equal(0, sign_unplace('g1')) 648 let s = sign_getplaced(bnum, {'group' : 'g1'}) 649 call assert_equal([], s[0].signs) 650 let s = sign_getplaced(bnum) 651 call assert_equal(2, len(s[0].signs)) 652 let s = sign_getplaced(bnum, {'group' : 'g2'}) 653 call assert_equal('g2', s[0].signs[0].group) 654 call assert_equal(0, sign_unplace('', {'id' : 5})) 655 call assert_equal(0, sign_unplace('', {'id' : 6})) 656 let s = sign_getplaced(bnum, {'group' : 'g2'}) 657 call assert_equal('g2', s[0].signs[0].group) 658 call assert_equal(0, sign_unplace('', {'buffer' : bnum})) 659 660 call sign_unplace('*') 661 662 " Test for :sign command and groups 663 sign place 5 line=10 name=sign1 file=Xsign 664 sign place 5 group=g1 line=10 name=sign1 file=Xsign 665 sign place 5 group=g2 line=10 name=sign1 file=Xsign 666 667 " Tests for the ':sign place' command 668 669 " :sign place file={fname} 670 let a = execute('sign place file=Xsign') 671 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" . 672 \ " line=10 id=5 name=sign1 priority=10\n", a) 673 674 " :sign place group={group} file={fname} 675 let a = execute('sign place group=g2 file=Xsign') 676 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" . 677 \ " line=10 id=5 group=g2 name=sign1 priority=10\n", a) 678 679 " :sign place group=* file={fname} 680 let a = execute('sign place group=* file=Xsign') 681 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" . 682 \ " line=10 id=5 group=g2 name=sign1 priority=10\n" . 683 \ " line=10 id=5 group=g1 name=sign1 priority=10\n" . 684 \ " line=10 id=5 name=sign1 priority=10\n", a) 685 686 " Error case: non-existing group 687 let a = execute('sign place group=xyz file=Xsign') 688 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n", a) 689 690 call sign_unplace('*') 691 let bnum = bufnr('Xsign') 692 exe 'sign place 5 line=10 name=sign1 buffer=' . bnum 693 exe 'sign place 5 group=g1 line=11 name=sign1 buffer=' . bnum 694 exe 'sign place 5 group=g2 line=12 name=sign1 buffer=' . bnum 695 696 " :sign place buffer={fname} 697 let a = execute('sign place buffer=' . bnum) 698 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" . 699 \ " line=10 id=5 name=sign1 priority=10\n", a) 700 701 " :sign place group={group} buffer={fname} 702 let a = execute('sign place group=g2 buffer=' . bnum) 703 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" . 704 \ " line=12 id=5 group=g2 name=sign1 priority=10\n", a) 705 706 " :sign place group=* buffer={fname} 707 let a = execute('sign place group=* buffer=' . bnum) 708 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" . 709 \ " line=10 id=5 name=sign1 priority=10\n" . 710 \ " line=11 id=5 group=g1 name=sign1 priority=10\n" . 711 \ " line=12 id=5 group=g2 name=sign1 priority=10\n", a) 712 713 " Error case: non-existing group 714 let a = execute('sign place group=xyz buffer=' . bnum) 715 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n", a) 716 717 " :sign place 718 let a = execute('sign place') 719 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" . 720 \ " line=10 id=5 name=sign1 priority=10\n", a) 721 722 " Place signs in more than one buffer and list the signs 723 split foo 724 set buftype=nofile 725 sign place 25 line=76 name=sign1 priority=99 file=foo 726 let a = execute('sign place') 727 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" . 728 \ " line=10 id=5 name=sign1 priority=10\n" . 729 \ "Signs for foo:\n" . 730 \ " line=76 id=25 name=sign1 priority=99\n", a) 731 close 732 bwipe foo 733 734 " :sign place group={group} 735 let a = execute('sign place group=g1') 736 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" . 737 \ " line=11 id=5 group=g1 name=sign1 priority=10\n", a) 738 739 " :sign place group=* 740 let a = execute('sign place group=*') 741 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" . 742 \ " line=10 id=5 name=sign1 priority=10\n" . 743 \ " line=11 id=5 group=g1 name=sign1 priority=10\n" . 744 \ " line=12 id=5 group=g2 name=sign1 priority=10\n", a) 745 746 " Test for ':sign jump' command with groups 747 sign jump 5 group=g1 file=Xsign 748 call assert_equal(11, line('.')) 749 call assert_equal('Xsign', bufname('')) 750 sign jump 5 group=g2 file=Xsign 751 call assert_equal(12, line('.')) 752 753 " Test for :sign jump command without the filename or buffer 754 sign jump 5 755 call assert_equal(10, line('.')) 756 sign jump 5 group=g1 757 call assert_equal(11, line('.')) 758 759 " Error cases 760 call assert_fails("sign place 3 group= name=sign1 buffer=" . bnum, 'E474:') 761 762 call delete("Xsign") 763 call sign_unplace('*') 764 call sign_undefine() 765 enew | only 766endfunc 767 768" Place signs used for ":sign unplace" command test 769func Place_signs_for_test() 770 call sign_unplace('*') 771 772 sign place 3 line=10 name=sign1 file=Xsign1 773 sign place 3 group=g1 line=11 name=sign1 file=Xsign1 774 sign place 3 group=g2 line=12 name=sign1 file=Xsign1 775 sign place 4 line=15 name=sign1 file=Xsign1 776 sign place 4 group=g1 line=16 name=sign1 file=Xsign1 777 sign place 4 group=g2 line=17 name=sign1 file=Xsign1 778 sign place 5 line=20 name=sign1 file=Xsign2 779 sign place 5 group=g1 line=21 name=sign1 file=Xsign2 780 sign place 5 group=g2 line=22 name=sign1 file=Xsign2 781 sign place 6 line=25 name=sign1 file=Xsign2 782 sign place 6 group=g1 line=26 name=sign1 file=Xsign2 783 sign place 6 group=g2 line=27 name=sign1 file=Xsign2 784endfunc 785 786" Place multiple signs in a single line for test 787func Place_signs_at_line_for_test() 788 call sign_unplace('*') 789 sign place 3 line=13 name=sign1 file=Xsign1 790 sign place 3 group=g1 line=13 name=sign1 file=Xsign1 791 sign place 3 group=g2 line=13 name=sign1 file=Xsign1 792 sign place 4 line=13 name=sign1 file=Xsign1 793 sign place 4 group=g1 line=13 name=sign1 file=Xsign1 794 sign place 4 group=g2 line=13 name=sign1 file=Xsign1 795endfunc 796 797" Tests for the ':sign unplace' command 798func Test_sign_unplace() 799 enew | only 800 " Remove all the signs 801 call sign_unplace('*') 802 call sign_undefine() 803 804 " Create two files and define signs 805 call writefile(repeat(["Sun is shining"], 30), "Xsign1") 806 call writefile(repeat(["It is beautiful"], 30), "Xsign2") 807 808 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'} 809 call sign_define("sign1", attr) 810 811 edit Xsign1 812 let bnum1 = bufnr('%') 813 split Xsign2 814 let bnum2 = bufnr('%') 815 816 let signs1 = [{'id' : 3, 'name' : 'sign1', 'lnum' : 10, 'group' : '', 817 \ 'priority' : 10}, 818 \ {'id' : 3, 'name' : 'sign1', 'lnum' : 11, 'group' : 'g1', 819 \ 'priority' : 10}, 820 \ {'id' : 3, 'name' : 'sign1', 'lnum' : 12, 'group' : 'g2', 821 \ 'priority' : 10}, 822 \ {'id' : 4, 'name' : 'sign1', 'lnum' : 15, 'group' : '', 823 \ 'priority' : 10}, 824 \ {'id' : 4, 'name' : 'sign1', 'lnum' : 16, 'group' : 'g1', 825 \ 'priority' : 10}, 826 \ {'id' : 4, 'name' : 'sign1', 'lnum' : 17, 'group' : 'g2', 827 \ 'priority' : 10},] 828 let signs2 = [{'id' : 5, 'name' : 'sign1', 'lnum' : 20, 'group' : '', 829 \ 'priority' : 10}, 830 \ {'id' : 5, 'name' : 'sign1', 'lnum' : 21, 'group' : 'g1', 831 \ 'priority' : 10}, 832 \ {'id' : 5, 'name' : 'sign1', 'lnum' : 22, 'group' : 'g2', 833 \ 'priority' : 10}, 834 \ {'id' : 6, 'name' : 'sign1', 'lnum' : 25, 'group' : '', 835 \ 'priority' : 10}, 836 \ {'id' : 6, 'name' : 'sign1', 'lnum' : 26, 'group' : 'g1', 837 \ 'priority' : 10}, 838 \ {'id' : 6, 'name' : 'sign1', 'lnum' : 27, 'group' : 'g2', 839 \ 'priority' : 10},] 840 841 " Test for :sign unplace {id} file={fname} 842 call Place_signs_for_test() 843 sign unplace 3 file=Xsign1 844 sign unplace 6 file=Xsign2 845 call assert_equal( 846 \ filter(copy(signs1), 847 \ {idx, val -> val.id != 3 || val.group != ''}), 848 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 849 call assert_equal( 850 \ filter(copy(signs2), 851 \ {idx, val -> val.id != 6 || val.group != ''}), 852 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs) 853 854 " Test for :sign unplace {id} group={group} file={fname} 855 call Place_signs_for_test() 856 sign unplace 4 group=g1 file=Xsign1 857 sign unplace 5 group=g2 file=Xsign2 858 call assert_equal( 859 \ filter(copy(signs1), 860 \ {idx, val -> val.id != 4 || val.group != 'g1'}), 861 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 862 call assert_equal( 863 \ filter(copy(signs2), 864 \ {idx, val -> val.id != 5 || val.group != 'g2'}), 865 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs) 866 867 " Test for :sign unplace {id} group=* file={fname} 868 call Place_signs_for_test() 869 sign unplace 3 group=* file=Xsign1 870 sign unplace 6 group=* file=Xsign2 871 call assert_equal( 872 \ filter(copy(signs1), 873 \ {idx, val -> val.id != 3}), 874 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 875 call assert_equal( 876 \ filter(copy(signs2), 877 \ {idx, val -> val.id != 6}), 878 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs) 879 880 " Test for :sign unplace * file={fname} 881 call Place_signs_for_test() 882 sign unplace * file=Xsign1 883 call assert_equal( 884 \ filter(copy(signs1), 885 \ {idx, val -> val.group != ''}), 886 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 887 call assert_equal(signs2, sign_getplaced('Xsign2', {'group' : '*'})[0].signs) 888 889 " Test for :sign unplace * group={group} file={fname} 890 call Place_signs_for_test() 891 sign unplace * group=g1 file=Xsign1 892 sign unplace * group=g2 file=Xsign2 893 call assert_equal( 894 \ filter(copy(signs1), 895 \ {idx, val -> val.group != 'g1'}), 896 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 897 call assert_equal( 898 \ filter(copy(signs2), 899 \ {idx, val -> val.group != 'g2'}), 900 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs) 901 902 " Test for :sign unplace * group=* file={fname} 903 call Place_signs_for_test() 904 sign unplace * group=* file=Xsign2 905 call assert_equal(signs1, sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 906 call assert_equal([], sign_getplaced('Xsign2', {'group' : '*'})[0].signs) 907 908 " Test for :sign unplace {id} buffer={nr} 909 call Place_signs_for_test() 910 exe 'sign unplace 3 buffer=' . bnum1 911 exe 'sign unplace 6 buffer=' . bnum2 912 call assert_equal( 913 \ filter(copy(signs1), 914 \ {idx, val -> val.id != 3 || val.group != ''}), 915 \ sign_getplaced(bnum1, {'group' : '*'})[0].signs) 916 call assert_equal( 917 \ filter(copy(signs2), 918 \ {idx, val -> val.id != 6 || val.group != ''}), 919 \ sign_getplaced(bnum2, {'group' : '*'})[0].signs) 920 921 " Test for :sign unplace {id} group={group} buffer={nr} 922 call Place_signs_for_test() 923 exe 'sign unplace 4 group=g1 buffer=' . bnum1 924 exe 'sign unplace 5 group=g2 buffer=' . bnum2 925 call assert_equal( 926 \ filter(copy(signs1), 927 \ {idx, val -> val.id != 4 || val.group != 'g1'}), 928 \ sign_getplaced(bnum1, {'group' : '*'})[0].signs) 929 call assert_equal( 930 \ filter(copy(signs2), 931 \ {idx, val -> val.id != 5 || val.group != 'g2'}), 932 \ sign_getplaced(bnum2, {'group' : '*'})[0].signs) 933 934 " Test for :sign unplace {id} group=* buffer={nr} 935 call Place_signs_for_test() 936 exe 'sign unplace 3 group=* buffer=' . bnum1 937 exe 'sign unplace 6 group=* buffer=' . bnum2 938 call assert_equal( 939 \ filter(copy(signs1), 940 \ {idx, val -> val.id != 3}), 941 \ sign_getplaced(bnum1, {'group' : '*'})[0].signs) 942 call assert_equal( 943 \ filter(copy(signs2), 944 \ {idx, val -> val.id != 6}), 945 \ sign_getplaced(bnum2, {'group' : '*'})[0].signs) 946 947 " Test for :sign unplace * buffer={nr} 948 call Place_signs_for_test() 949 exe 'sign unplace * buffer=' . bnum1 950 call assert_equal( 951 \ filter(copy(signs1), 952 \ {idx, val -> val.group != ''}), 953 \ sign_getplaced(bnum1, {'group' : '*'})[0].signs) 954 call assert_equal(signs2, sign_getplaced(bnum2, {'group' : '*'})[0].signs) 955 956 " Test for :sign unplace * group={group} buffer={nr} 957 call Place_signs_for_test() 958 exe 'sign unplace * group=g1 buffer=' . bnum1 959 exe 'sign unplace * group=g2 buffer=' . bnum2 960 call assert_equal( 961 \ filter(copy(signs1), 962 \ {idx, val -> val.group != 'g1'}), 963 \ sign_getplaced(bnum1, {'group' : '*'})[0].signs) 964 call assert_equal( 965 \ filter(copy(signs2), 966 \ {idx, val -> val.group != 'g2'}), 967 \ sign_getplaced(bnum2, {'group' : '*'})[0].signs) 968 969 " Test for :sign unplace * group=* buffer={nr} 970 call Place_signs_for_test() 971 exe 'sign unplace * group=* buffer=' . bnum2 972 call assert_equal(signs1, sign_getplaced(bnum1, {'group' : '*'})[0].signs) 973 call assert_equal([], sign_getplaced(bnum2, {'group' : '*'})[0].signs) 974 975 " Test for :sign unplace {id} 976 call Place_signs_for_test() 977 sign unplace 4 978 sign unplace 6 979 call assert_equal( 980 \ filter(copy(signs1), 981 \ {idx, val -> val.id != 4 || val.group != ''}), 982 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 983 call assert_equal( 984 \ filter(copy(signs2), 985 \ {idx, val -> val.id != 6 || val.group != ''}), 986 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs) 987 988 " Test for :sign unplace {id} group={group} 989 call Place_signs_for_test() 990 sign unplace 4 group=g1 991 sign unplace 6 group=g2 992 call assert_equal( 993 \ filter(copy(signs1), 994 \ {idx, val -> val.id != 4 || val.group != 'g1'}), 995 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 996 call assert_equal( 997 \ filter(copy(signs2), 998 \ {idx, val -> val.id != 6 || val.group != 'g2'}), 999 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs) 1000 1001 " Test for :sign unplace {id} group=* 1002 call Place_signs_for_test() 1003 sign unplace 3 group=* 1004 sign unplace 5 group=* 1005 call assert_equal( 1006 \ filter(copy(signs1), 1007 \ {idx, val -> val.id != 3}), 1008 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 1009 call assert_equal( 1010 \ filter(copy(signs2), 1011 \ {idx, val -> val.id != 5}), 1012 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs) 1013 1014 " Test for :sign unplace * 1015 call Place_signs_for_test() 1016 sign unplace * 1017 call assert_equal( 1018 \ filter(copy(signs1), 1019 \ {idx, val -> val.group != ''}), 1020 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 1021 call assert_equal( 1022 \ filter(copy(signs2), 1023 \ {idx, val -> val.group != ''}), 1024 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs) 1025 1026 " Test for :sign unplace * group={group} 1027 call Place_signs_for_test() 1028 sign unplace * group=g1 1029 call assert_equal( 1030 \ filter(copy(signs1), 1031 \ {idx, val -> val.group != 'g1'}), 1032 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 1033 call assert_equal( 1034 \ filter(copy(signs2), 1035 \ {idx, val -> val.group != 'g1'}), 1036 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs) 1037 1038 " Test for :sign unplace * group=* 1039 call Place_signs_for_test() 1040 sign unplace * group=* 1041 call assert_equal([], sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 1042 call assert_equal([], sign_getplaced('Xsign2', {'group' : '*'})[0].signs) 1043 1044 " Negative test cases 1045 call Place_signs_for_test() 1046 sign unplace 3 group=xy file=Xsign1 1047 sign unplace * group=xy file=Xsign1 1048 silent! sign unplace * group=* file=FileNotPresent 1049 call assert_equal(signs1, sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 1050 call assert_equal(signs2, sign_getplaced('Xsign2', {'group' : '*'})[0].signs) 1051 1052 " Tests for removing sign at the current cursor position 1053 1054 " Test for ':sign unplace' 1055 let signs1 = [{'id' : 4, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g2', 1056 \ 'priority' : 10}, 1057 \ {'id' : 4, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g1', 1058 \ 'priority' : 10}, 1059 \ {'id' : 4, 'name' : 'sign1', 'lnum' : 13, 'group' : '', 1060 \ 'priority' : 10}, 1061 \ {'id' : 3, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g2', 1062 \ 'priority' : 10}, 1063 \ {'id' : 3, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g1', 1064 \ 'priority' : 10}, 1065 \ {'id' : 3, 'name' : 'sign1', 'lnum' : 13, 'group' : '', 1066 \ 'priority' : 10},] 1067 exe bufwinnr('Xsign1') . 'wincmd w' 1068 call cursor(13, 1) 1069 1070 " Should remove only one sign in the global group 1071 call Place_signs_at_line_for_test() 1072 sign unplace 1073 call assert_equal( 1074 \ filter(copy(signs1), 1075 \ {idx, val -> val.id != 4 || val.group != ''}), 1076 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 1077 " Should remove the second sign in the global group 1078 sign unplace 1079 call assert_equal( 1080 \ filter(copy(signs1), 1081 \ {idx, val -> val.group != ''}), 1082 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 1083 1084 " Test for ':sign unplace group={group}' 1085 call Place_signs_at_line_for_test() 1086 " Should remove only one sign in group g1 1087 sign unplace group=g1 1088 call assert_equal( 1089 \ filter(copy(signs1), 1090 \ {idx, val -> val.id != 4 || val.group != 'g1'}), 1091 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 1092 sign unplace group=g2 1093 call assert_equal( 1094 \ filter(copy(signs1), 1095 \ {idx, val -> val.id != 4 || val.group == ''}), 1096 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 1097 1098 " Test for ':sign unplace group=*' 1099 call Place_signs_at_line_for_test() 1100 sign unplace group=* 1101 sign unplace group=* 1102 sign unplace group=* 1103 call assert_equal( 1104 \ filter(copy(signs1), 1105 \ {idx, val -> val.id != 4}), 1106 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 1107 sign unplace group=* 1108 sign unplace group=* 1109 sign unplace group=* 1110 call assert_equal([], sign_getplaced('Xsign1', {'group' : '*'})[0].signs) 1111 1112 call sign_unplace('*') 1113 call sign_undefine() 1114 enew | only 1115 call delete("Xsign1") 1116 call delete("Xsign2") 1117endfunc 1118 1119" Tests for auto-generating the sign identifier 1120func Test_sign_id_autogen() 1121 enew | only 1122 call sign_unplace('*') 1123 call sign_undefine() 1124 1125 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'} 1126 call assert_equal(0, sign_define("sign1", attr)) 1127 1128 call writefile(repeat(["Sun is shining"], 30), "Xsign") 1129 edit Xsign 1130 1131 call assert_equal(1, sign_place(0, '', 'sign1', 'Xsign', 1132 \ {'lnum' : 10})) 1133 call assert_equal(2, sign_place(2, '', 'sign1', 'Xsign', 1134 \ {'lnum' : 12})) 1135 call assert_equal(3, sign_place(0, '', 'sign1', 'Xsign', 1136 \ {'lnum' : 14})) 1137 call sign_unplace('', {'buffer' : 'Xsign', 'id' : 2}) 1138 call assert_equal(4, sign_place(0, '', 'sign1', 'Xsign', 1139 \ {'lnum' : 12})) 1140 1141 call assert_equal(1, sign_place(0, 'g1', 'sign1', 'Xsign', 1142 \ {'lnum' : 11})) 1143 " Check for the next generated sign id in this group 1144 call assert_equal(2, sign_place(0, 'g1', 'sign1', 'Xsign', 1145 \ {'lnum' : 12})) 1146 call assert_equal(0, sign_unplace('g1', {'id' : 1})) 1147 call assert_equal(10, 1148 \ sign_getplaced('Xsign', {'id' : 1})[0].signs[0].lnum) 1149 1150 call delete("Xsign") 1151 call sign_unplace('*') 1152 call sign_undefine() 1153 enew | only 1154endfunc 1155 1156" Test for sign priority 1157func Test_sign_priority() 1158 enew | only 1159 call sign_unplace('*') 1160 call sign_undefine() 1161 1162 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Search'} 1163 call sign_define("sign1", attr) 1164 call sign_define("sign2", attr) 1165 call sign_define("sign3", attr) 1166 1167 " Place three signs with different priority in the same line 1168 call writefile(repeat(["Sun is shining"], 30), "Xsign") 1169 edit Xsign 1170 1171 call sign_place(1, 'g1', 'sign1', 'Xsign', 1172 \ {'lnum' : 11, 'priority' : 50}) 1173 call sign_place(2, 'g2', 'sign2', 'Xsign', 1174 \ {'lnum' : 11, 'priority' : 100}) 1175 call sign_place(3, '', 'sign3', 'Xsign', {'lnum' : 11}) 1176 let s = sign_getplaced('Xsign', {'group' : '*'}) 1177 call assert_equal([ 1178 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 11, 'group' : 'g2', 1179 \ 'priority' : 100}, 1180 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 11, 'group' : 'g1', 1181 \ 'priority' : 50}, 1182 \ {'id' : 3, 'name' : 'sign3', 'lnum' : 11, 'group' : '', 1183 \ 'priority' : 10}], 1184 \ s[0].signs) 1185 1186 " Error case 1187 call assert_fails("call sign_place(1, 'g1', 'sign1', 'Xsign', 1188 \ [])", 'E715:') 1189 call assert_fails("call sign_place(1, 'g1', 'sign1', 'Xsign', 1190 \ {'priority' : []})", 'E745:') 1191 call sign_unplace('*') 1192 1193 " Tests for the :sign place command with priority 1194 sign place 5 line=10 name=sign1 priority=30 file=Xsign 1195 sign place 5 group=g1 line=10 name=sign1 priority=20 file=Xsign 1196 sign place 5 group=g2 line=10 name=sign1 priority=25 file=Xsign 1197 let a = execute('sign place group=*') 1198 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" . 1199 \ " line=10 id=5 name=sign1 priority=30\n" . 1200 \ " line=10 id=5 group=g2 name=sign1 priority=25\n" . 1201 \ " line=10 id=5 group=g1 name=sign1 priority=20\n", a) 1202 1203 " Test for :sign place group={group} 1204 let a = execute('sign place group=g1') 1205 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" . 1206 \ " line=10 id=5 group=g1 name=sign1 priority=20\n", a) 1207 1208 call sign_unplace('*') 1209 call sign_undefine() 1210 enew | only 1211 call delete("Xsign") 1212endfunc 1213 1214" Tests for memory allocation failures in sign functions 1215func Test_sign_memfailures() 1216 call writefile(repeat(["Sun is shining"], 30), "Xsign") 1217 edit Xsign 1218 1219 call test_alloc_fail(GetAllocId('sign_getdefined'), 0, 0) 1220 call assert_fails('call sign_getdefined("sign1")', 'E342:') 1221 call test_alloc_fail(GetAllocId('sign_getplaced'), 0, 0) 1222 call assert_fails('call sign_getplaced("Xsign")', 'E342:') 1223 call test_alloc_fail(GetAllocId('sign_define_by_name'), 0, 0) 1224 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'} 1225 call assert_fails('call sign_define("sign1", attr)', 'E342:') 1226 1227 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'} 1228 call sign_define("sign1", attr) 1229 call test_alloc_fail(GetAllocId('sign_getlist'), 0, 0) 1230 call assert_fails('call sign_getdefined("sign1")', 'E342:') 1231 1232 call sign_place(3, 'g1', 'sign1', 'Xsign', {'lnum' : 10}) 1233 call test_alloc_fail(GetAllocId('sign_getplaced_dict'), 0, 0) 1234 call assert_fails('call sign_getplaced("Xsign")', 'E342:') 1235 call test_alloc_fail(GetAllocId('sign_getplaced_list'), 0, 0) 1236 call assert_fails('call sign_getplaced("Xsign")', 'E342:') 1237 1238 call test_alloc_fail(GetAllocId('insert_sign'), 0, 0) 1239 call assert_fails('call sign_place(4, "g1", "sign1", "Xsign", {"lnum" : 11})', 1240 \ 'E342:') 1241 1242 call test_alloc_fail(GetAllocId('sign_getinfo'), 0, 0) 1243 call assert_fails('call getbufinfo()', 'E342:') 1244 call sign_place(4, 'g1', 'sign1', 'Xsign', {'lnum' : 11}) 1245 call test_alloc_fail(GetAllocId('sign_getinfo'), 0, 0) 1246 call assert_fails('let binfo=getbufinfo("Xsign")', 'E342:') 1247 call assert_equal([{'lnum': 11, 'id': 4, 'name': 'sign1', 1248 \ 'priority': 10, 'group': 'g1'}], binfo[0].signs) 1249 1250 call sign_unplace('*') 1251 call sign_undefine() 1252 enew | only 1253 call delete("Xsign") 1254endfunc 1255 1256" Test for auto-adjusting the line number of a placed sign. 1257func Test_sign_lnum_adjust() 1258 enew! | only! 1259 1260 sign define sign1 text=#> linehl=Comment 1261 call setline(1, ['A', 'B', 'C', 'D', 'E']) 1262 exe 'sign place 5 line=3 name=sign1 buffer=' . bufnr('') 1263 let l = sign_getplaced(bufnr('')) 1264 call assert_equal(3, l[0].signs[0].lnum) 1265 1266 " Add some lines before the sign and check the sign line number 1267 call append(2, ['BA', 'BB', 'BC']) 1268 let l = sign_getplaced(bufnr('')) 1269 call assert_equal(6, l[0].signs[0].lnum) 1270 1271 " Delete some lines before the sign and check the sign line number 1272 call deletebufline('%', 1, 2) 1273 let l = sign_getplaced(bufnr('')) 1274 call assert_equal(4, l[0].signs[0].lnum) 1275 1276 " Insert some lines after the sign and check the sign line number 1277 call append(5, ['DA', 'DB']) 1278 let l = sign_getplaced(bufnr('')) 1279 call assert_equal(4, l[0].signs[0].lnum) 1280 1281 " Delete some lines after the sign and check the sign line number 1282 call deletebufline('', 6, 7) 1283 let l = sign_getplaced(bufnr('')) 1284 call assert_equal(4, l[0].signs[0].lnum) 1285 1286 " Break the undo. Otherwise the undo operation below will undo all the 1287 " changes made by this function. 1288 let &undolevels=&undolevels 1289 1290 " Delete the line with the sign 1291 call deletebufline('', 4) 1292 let l = sign_getplaced(bufnr('')) 1293 call assert_equal(4, l[0].signs[0].lnum) 1294 1295 " Undo the delete operation 1296 undo 1297 let l = sign_getplaced(bufnr('')) 1298 call assert_equal(5, l[0].signs[0].lnum) 1299 1300 " Break the undo 1301 let &undolevels=&undolevels 1302 1303 " Delete few lines at the end of the buffer including the line with the sign 1304 " Sign line number should not change (as it is placed outside of the buffer) 1305 call deletebufline('', 3, 6) 1306 let l = sign_getplaced(bufnr('')) 1307 call assert_equal(5, l[0].signs[0].lnum) 1308 1309 " Undo the delete operation. Sign should be restored to the previous line 1310 undo 1311 let l = sign_getplaced(bufnr('')) 1312 call assert_equal(5, l[0].signs[0].lnum) 1313 1314 sign unplace * group=* 1315 sign undefine sign1 1316 enew! 1317endfunc 1318 1319" Test for changing the type of a placed sign 1320func Test_sign_change_type() 1321 enew! | only! 1322 1323 sign define sign1 text=#> linehl=Comment 1324 sign define sign2 text=@@ linehl=Comment 1325 1326 call setline(1, ['A', 'B', 'C', 'D']) 1327 exe 'sign place 4 line=3 name=sign1 buffer=' . bufnr('') 1328 let l = sign_getplaced(bufnr('')) 1329 call assert_equal('sign1', l[0].signs[0].name) 1330 exe 'sign place 4 name=sign2 buffer=' . bufnr('') 1331 let l = sign_getplaced(bufnr('')) 1332 call assert_equal('sign2', l[0].signs[0].name) 1333 call sign_place(4, '', 'sign1', '') 1334 let l = sign_getplaced(bufnr('')) 1335 call assert_equal('sign1', l[0].signs[0].name) 1336 1337 exe 'sign place 4 group=g1 line=4 name=sign1 buffer=' . bufnr('') 1338 let l = sign_getplaced(bufnr(''), {'group' : 'g1'}) 1339 call assert_equal('sign1', l[0].signs[0].name) 1340 exe 'sign place 4 group=g1 name=sign2 buffer=' . bufnr('') 1341 let l = sign_getplaced(bufnr(''), {'group' : 'g1'}) 1342 call assert_equal('sign2', l[0].signs[0].name) 1343 call sign_place(4, 'g1', 'sign1', '') 1344 let l = sign_getplaced(bufnr(''), {'group' : 'g1'}) 1345 call assert_equal('sign1', l[0].signs[0].name) 1346 1347 sign unplace * group=* 1348 sign undefine sign1 1349 sign undefine sign2 1350 enew! 1351endfunc 1352 1353" Test for the sign_jump() function 1354func Test_sign_jump_func() 1355 enew! | only! 1356 1357 sign define sign1 text=#> linehl=Comment 1358 1359 edit foo 1360 set buftype=nofile 1361 call setline(1, ['A', 'B', 'C', 'D', 'E']) 1362 call sign_place(5, '', 'sign1', '', {'lnum' : 2}) 1363 call sign_place(5, 'g1', 'sign1', '', {'lnum' : 3}) 1364 call sign_place(6, '', 'sign1', '', {'lnum' : 4}) 1365 call sign_place(6, 'g1', 'sign1', '', {'lnum' : 5}) 1366 split bar 1367 set buftype=nofile 1368 call setline(1, ['P', 'Q', 'R', 'S', 'T']) 1369 call sign_place(5, '', 'sign1', '', {'lnum' : 2}) 1370 call sign_place(5, 'g1', 'sign1', '', {'lnum' : 3}) 1371 call sign_place(6, '', 'sign1', '', {'lnum' : 4}) 1372 call sign_place(6, 'g1', 'sign1', '', {'lnum' : 5}) 1373 1374 let r = sign_jump(5, '', 'foo') 1375 call assert_equal(2, r) 1376 call assert_equal(2, line('.')) 1377 let r = sign_jump(6, 'g1', 'foo') 1378 call assert_equal(5, r) 1379 call assert_equal(5, line('.')) 1380 let r = sign_jump(5, '', 'bar') 1381 call assert_equal(2, r) 1382 call assert_equal(2, line('.')) 1383 1384 " Error cases 1385 call assert_fails("call sign_jump(99, '', 'bar')", 'E157:') 1386 call assert_fails("call sign_jump(0, '', 'foo')", 'E474:') 1387 call assert_fails("call sign_jump(5, 'g5', 'foo')", 'E157:') 1388 call assert_fails('call sign_jump([], "", "foo")', 'E745:') 1389 call assert_fails('call sign_jump(2, [], "foo")', 'E730:') 1390 call assert_fails('call sign_jump(2, "", {})', 'E158:') 1391 call assert_fails('call sign_jump(2, "", "baz")', 'E158:') 1392 1393 sign unplace * group=* 1394 sign undefine sign1 1395 enew! | only! 1396endfunc 1397