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