1" Test 'statusline' 2" 3" Not tested yet: 4" %a 5" %N 6" %T 7" %X 8 9source view_util.vim 10source check.vim 11source screendump.vim 12 13func s:get_statusline() 14 return ScreenLines(&lines - 1, &columns)[0] 15endfunc 16 17func StatuslineWithCaughtError() 18 let s:func_in_statusline_called = 1 19 try 20 call eval('unknown expression') 21 catch 22 endtry 23 return '' 24endfunc 25 26func StatuslineWithError() 27 let s:func_in_statusline_called = 1 28 call eval('unknown expression') 29 return '' 30endfunc 31 32" Function used to display syntax group. 33func SyntaxItem() 34 call assert_equal(s:expected_curbuf, g:actual_curbuf) 35 call assert_equal(s:expected_curwin, g:actual_curwin) 36 return synIDattr(synID(line("."), col("."),1), "name") 37endfunc 38 39func Test_caught_error_in_statusline() 40 let s:func_in_statusline_called = 0 41 set laststatus=2 42 let statusline = '%{StatuslineWithCaughtError()}' 43 let &statusline = statusline 44 redrawstatus 45 call assert_true(s:func_in_statusline_called) 46 call assert_equal(statusline, &statusline) 47 set statusline= 48endfunc 49 50func Test_statusline_will_be_disabled_with_error() 51 let s:func_in_statusline_called = 0 52 set laststatus=2 53 let statusline = '%{StatuslineWithError()}' 54 try 55 let &statusline = statusline 56 redrawstatus 57 catch 58 endtry 59 call assert_true(s:func_in_statusline_called) 60 call assert_equal('', &statusline) 61 set statusline= 62endfunc 63 64func Test_statusline() 65 CheckFeature quickfix 66 67 new Xstatusline 68 only 69 set laststatus=2 70 set splitbelow 71 call setline(1, range(1, 10000)) 72 73 " %b: Value of character under cursor. 74 " %B: As above, in hexadecimal. 75 call cursor(9000, 1) 76 set statusline=%b,%B 77 call assert_match('^57,39\s*$', s:get_statusline()) 78 79 " %o: Byte number in file of byte under cursor, first byte is 1. 80 " %O: As above, in hexadecimal. 81 set statusline=%o,%O 82 set fileformat=dos 83 call assert_match('^52888,CE98\s*$', s:get_statusline()) 84 set fileformat=mac 85 call assert_match('^43889,AB71\s*$', s:get_statusline()) 86 set fileformat=unix 87 call assert_match('^43889,AB71\s*$', s:get_statusline()) 88 set fileformat& 89 90 " %f: Path to the file in the buffer, as typed or relative to current dir. 91 set statusline=%f 92 call assert_match('^Xstatusline\s*$', s:get_statusline()) 93 94 " %F: Full path to the file in the buffer. 95 set statusline=%F 96 call assert_match('/testdir/Xstatusline\s*$', s:get_statusline()) 97 98 " %h: Help buffer flag, text is "[help]". 99 " %H: Help buffer flag, text is ",HLP". 100 set statusline=%h,%H 101 call assert_match('^,\s*$', s:get_statusline()) 102 help 103 call assert_match('^\[Help\],HLP\s*$', s:get_statusline()) 104 helpclose 105 106 " %k: Value of "b:keymap_name" or 'keymap' 107 " when :lmap mappings are being used: <keymap>" 108 set statusline=%k 109 if has('keymap') 110 set keymap=esperanto 111 call assert_match('^<Eo>\s*$', s:get_statusline()) 112 set keymap& 113 else 114 call assert_match('^\s*$', s:get_statusline()) 115 endif 116 117 " %l: Line number. 118 " %L: Number of line in buffer. 119 " %c: Column number. 120 set statusline=%l/%L,%c 121 call assert_match('^9000/10000,1\s*$', s:get_statusline()) 122 123 " %m: Modified flag, text is "[+]", "[-]" if 'modifiable' is off. 124 " %M: Modified flag, text is ",+" or ",-". 125 set statusline=%m%M 126 call assert_match('^\[+\],+\s*$', s:get_statusline()) 127 set nomodifiable 128 call assert_match('^\[+-\],+-\s*$', s:get_statusline()) 129 write 130 call assert_match('^\[-\],-\s*$', s:get_statusline()) 131 set modifiable& 132 call assert_match('^\s*$', s:get_statusline()) 133 134 " %n: Buffer number. 135 set statusline=%n 136 call assert_match('^'.bufnr('%').'\s*$', s:get_statusline()) 137 138 " %p: Percentage through file in lines as in CTRL-G. 139 " %P: Percentage through file of displayed window. 140 set statusline=%p,%P 141 0 142 call assert_match('^0,Top\s*$', s:get_statusline()) 143 norm G 144 call assert_match('^100,Bot\s*$', s:get_statusline()) 145 9000 146 " Don't check the exact percentage as it depends on the window size 147 call assert_match('^90,\(Top\|Bot\|\d\+%\)\s*$', s:get_statusline()) 148 149 " %q: "[Quickfix List]", "[Location List]" or empty. 150 set statusline=%q 151 call assert_match('^\s*$', s:get_statusline()) 152 copen 153 call assert_match('^\[Quickfix List\]\s*$', s:get_statusline()) 154 cclose 155 lexpr getline(1, 2) 156 lopen 157 call assert_match('^\[Location List\]\s*$', s:get_statusline()) 158 lclose 159 160 " %r: Readonly flag, text is "[RO]". 161 " %R: Readonly flag, text is ",RO". 162 set statusline=%r,%R 163 call assert_match('^,\s*$', s:get_statusline()) 164 help 165 call assert_match('^\[RO\],RO\s*$', s:get_statusline()) 166 helpclose 167 168 " %t: File name (tail) of file in the buffer. 169 set statusline=%t 170 call assert_match('^Xstatusline\s*$', s:get_statusline()) 171 172 " %v: Virtual column number. 173 " %V: Virtual column number as -{num}. Not displayed if equal to 'c'. 174 call cursor(9000, 2) 175 set statusline=%v,%V 176 call assert_match('^2,\s*$', s:get_statusline()) 177 set virtualedit=all 178 norm 10| 179 call assert_match('^10,-10\s*$', s:get_statusline()) 180 set virtualedit& 181 182 " %w: Preview window flag, text is "[Preview]". 183 " %W: Preview window flag, text is ",PRV". 184 set statusline=%w%W 185 call assert_match('^\s*$', s:get_statusline()) 186 pedit 187 wincmd j 188 call assert_match('^\[Preview\],PRV\s*$', s:get_statusline()) 189 pclose 190 191 " %y: Type of file in the buffer, e.g., "[vim]". See 'filetype'. 192 " %Y: Type of file in the buffer, e.g., ",VIM". See 'filetype'. 193 set statusline=%y\ %Y 194 call assert_match('^\s*$', s:get_statusline()) 195 setfiletype vim 196 call assert_match('^\[vim\] VIM\s*$', s:get_statusline()) 197 198 " %=: Separation point between left and right aligned items. 199 set statusline=foo%=bar 200 call assert_match('^foo\s\+bar\s*$', s:get_statusline()) 201 202 " Test min/max width, leading zeroes, left/right justify. 203 set statusline=%04B 204 call cursor(9000, 1) 205 call assert_match('^0039\s*$', s:get_statusline()) 206 set statusline=#%4B# 207 call assert_match('^# 39#\s*$', s:get_statusline()) 208 set statusline=#%-4B# 209 call assert_match('^#39 #\s*$', s:get_statusline()) 210 set statusline=%.6f 211 call assert_match('^<sline\s*$', s:get_statusline()) 212 213 " %<: Where to truncate. 214 " First check with when %< should not truncate with many columns 215 exe 'set statusline=a%<b' . repeat('c', &columns - 3) . 'd' 216 call assert_match('^abc\+d$', s:get_statusline()) 217 exe 'set statusline=a' . repeat('b', &columns - 2) . '%<c' 218 call assert_match('^ab\+c$', s:get_statusline()) 219 " Then check when %< should truncate when there with too few columns. 220 exe 'set statusline=a%<b' . repeat('c', &columns - 2) . 'd' 221 call assert_match('^a<c\+d$', s:get_statusline()) 222 exe 'set statusline=a' . repeat('b', &columns - 1) . '%<c' 223 call assert_match('^ab\+>$', s:get_statusline()) 224 225 "%{: Evaluate expression between '%{' and '}' and substitute result. 226 syntax on 227 let s:expected_curbuf = string(bufnr('')) 228 let s:expected_curwin = string(win_getid()) 229 set statusline=%{SyntaxItem()} 230 call assert_match('^vimNumber\s*$', s:get_statusline()) 231 s/^/"/ 232 call assert_match('^vimLineComment\s*$', s:get_statusline()) 233 syntax off 234 235 "%(: Start of item group. 236 set statusline=ab%(cd%q%)de 237 call assert_match('^abde\s*$', s:get_statusline()) 238 copen 239 call assert_match('^abcd\[Quickfix List]de\s*$', s:get_statusline()) 240 cclose 241 242 " %#: Set highlight group. The name must follow and then a # again. 243 set statusline=ab%#Todo#cd%#Error#ef 244 call assert_match('^abcdef\s*$', s:get_statusline()) 245 let sa1=screenattr(&lines - 1, 1) 246 let sa2=screenattr(&lines - 1, 3) 247 let sa3=screenattr(&lines - 1, 5) 248 call assert_notequal(sa1, sa2) 249 call assert_notequal(sa1, sa3) 250 call assert_notequal(sa2, sa3) 251 call assert_equal(sa1, screenattr(&lines - 1, 2)) 252 call assert_equal(sa2, screenattr(&lines - 1, 4)) 253 call assert_equal(sa3, screenattr(&lines - 1, 6)) 254 call assert_equal(sa3, screenattr(&lines - 1, 7)) 255 256 " %*: Set highlight group to User{N} 257 set statusline=a%1*b%0*c 258 call assert_match('^abc\s*$', s:get_statusline()) 259 let sa1=screenattr(&lines - 1, 1) 260 let sa2=screenattr(&lines - 1, 2) 261 let sa3=screenattr(&lines - 1, 3) 262 call assert_equal(sa1, sa3) 263 call assert_notequal(sa1, sa2) 264 265 " An empty group that contains highlight changes 266 let g:a = '' 267 set statusline=ab%(cd%1*%{g:a}%*%)de 268 call assert_match('^abde\s*$', s:get_statusline()) 269 let sa1=screenattr(&lines - 1, 1) 270 let sa2=screenattr(&lines - 1, 4) 271 call assert_equal(sa1, sa2) 272 let g:a = 'X' 273 call assert_match('^abcdXde\s*$', s:get_statusline()) 274 let sa1=screenattr(&lines - 1, 1) 275 let sa2=screenattr(&lines - 1, 5) 276 let sa3=screenattr(&lines - 1, 7) 277 call assert_equal(sa1, sa3) 278 call assert_notequal(sa1, sa2) 279 280 let g:a = '' 281 set statusline=ab%1*%(cd%*%{g:a}%1*%)de 282 call assert_match('^abde\s*$', s:get_statusline()) 283 let sa1=screenattr(&lines - 1, 1) 284 let sa2=screenattr(&lines - 1, 4) 285 call assert_notequal(sa1, sa2) 286 let g:a = 'X' 287 call assert_match('^abcdXde\s*$', s:get_statusline()) 288 let sa1=screenattr(&lines - 1, 1) 289 let sa2=screenattr(&lines - 1, 3) 290 let sa3=screenattr(&lines - 1, 5) 291 let sa4=screenattr(&lines - 1, 7) 292 call assert_notequal(sa1, sa2) 293 call assert_equal(sa1, sa3) 294 call assert_equal(sa2, sa4) 295 296 " An empty group that contains highlight changes and doesn't reset them 297 let g:a = '' 298 set statusline=ab%(cd%1*%{g:a}%)de 299 call assert_match('^abcdde\s*$', s:get_statusline()) 300 let sa1=screenattr(&lines - 1, 1) 301 let sa2=screenattr(&lines - 1, 5) 302 call assert_notequal(sa1, sa2) 303 let g:a = 'X' 304 call assert_match('^abcdXde\s*$', s:get_statusline()) 305 let sa1=screenattr(&lines - 1, 1) 306 let sa2=screenattr(&lines - 1, 5) 307 let sa3=screenattr(&lines - 1, 7) 308 call assert_notequal(sa1, sa2) 309 call assert_equal(sa2, sa3) 310 311 let g:a = '' 312 set statusline=ab%1*%(cd%*%{g:a}%)de 313 call assert_match('^abcdde\s*$', s:get_statusline()) 314 let sa1=screenattr(&lines - 1, 1) 315 let sa2=screenattr(&lines - 1, 3) 316 let sa3=screenattr(&lines - 1, 5) 317 call assert_notequal(sa1, sa2) 318 call assert_equal(sa1, sa3) 319 let g:a = 'X' 320 call assert_match('^abcdXde\s*$', s:get_statusline()) 321 let sa1=screenattr(&lines - 1, 1) 322 let sa2=screenattr(&lines - 1, 3) 323 let sa3=screenattr(&lines - 1, 5) 324 let sa4=screenattr(&lines - 1, 7) 325 call assert_notequal(sa1, sa2) 326 call assert_equal(sa1, sa3) 327 call assert_equal(sa1, sa4) 328 329 let g:a = '' 330 set statusline=%#Error#{%(\ %{g:a}\ %)} 331 call assert_match('^{}\s*$', s:get_statusline()) 332 let g:a = 'X' 333 call assert_match('^{ X }\s*$', s:get_statusline()) 334 335 " %%: a percent sign. 336 set statusline=10%% 337 call assert_match('^10%\s*$', s:get_statusline()) 338 339 " %!: evaluated expression is used as the option value 340 set statusline=%!2*3+1 341 call assert_match('7\s*$', s:get_statusline()) 342 343 func GetNested() 344 call assert_equal(string(win_getid()), g:actual_curwin) 345 call assert_equal(string(bufnr('')), g:actual_curbuf) 346 return 'nested' 347 endfunc 348 func GetStatusLine() 349 call assert_equal(win_getid(), g:statusline_winid) 350 return 'the %{GetNested()} line' 351 endfunc 352 set statusline=%!GetStatusLine() 353 call assert_match('the nested line', s:get_statusline()) 354 call assert_false(exists('g:actual_curwin')) 355 call assert_false(exists('g:actual_curbuf')) 356 call assert_false(exists('g:statusline_winid')) 357 delfunc GetNested 358 delfunc GetStatusLine 359 360 " Check statusline in current and non-current window 361 " with the 'fillchars' option. 362 set fillchars=stl:^,stlnc:=,vert:\|,fold:-,diff:- 363 vsplit 364 set statusline=x%=y 365 call assert_match('^x^\+y^x=\+y$', s:get_statusline()) 366 set fillchars& 367 close 368 369 %bw! 370 call delete('Xstatusline') 371 set statusline& 372 set laststatus& 373 set splitbelow& 374endfunc 375 376func Test_statusline_visual() 377 func CallWordcount() 378 call wordcount() 379 endfunc 380 new x1 381 setl statusline=count=%{CallWordcount()} 382 " buffer must not be empty 383 call setline(1, 'hello') 384 385 " window with more lines than x1 386 new x2 387 call setline(1, range(10)) 388 $ 389 " Visual mode in line below liast line in x1 should not give ml_get error 390 call feedkeys("\<C-V>", "xt") 391 redraw 392 393 delfunc CallWordcount 394 bwipe! x1 395 bwipe! x2 396endfunc 397 398func Test_statusline_removed_group() 399 CheckScreendump 400 401 let lines =<< trim END 402 scriptencoding utf-8 403 set laststatus=2 404 let &statusline = '%#StatColorHi2#%(✓%#StatColorHi2#%) Q≡' 405 END 406 call writefile(lines, 'XTest_statusline') 407 408 let buf = RunVimInTerminal('-S XTest_statusline', {'rows': 10, 'cols': 50}) 409 call term_wait(buf, 100) 410 call VerifyScreenDump(buf, 'Test_statusline_1', {}) 411 412 " clean up 413 call StopVimInTerminal(buf) 414 call delete('XTest_statusline') 415endfunc 416