blob: 1f705b847ff04b9a354a4bb51ac91c453a787e28 [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 Moolenaar300af822017-03-06 20:28:10 +010011
12func s:get_statusline()
13 return ScreenLines(&lines - 1, &columns)[0]
14endfunc
15
16func StatuslineWithCaughtError()
Bram Moolenaara742e082016-04-05 21:10:38 +020017 let s:func_in_statusline_called = 1
18 try
19 call eval('unknown expression')
20 catch
21 endtry
22 return ''
Bram Moolenaar300af822017-03-06 20:28:10 +010023endfunc
Bram Moolenaara742e082016-04-05 21:10:38 +020024
Bram Moolenaar300af822017-03-06 20:28:10 +010025func StatuslineWithError()
Bram Moolenaara742e082016-04-05 21:10:38 +020026 let s:func_in_statusline_called = 1
27 call eval('unknown expression')
28 return ''
Bram Moolenaar300af822017-03-06 20:28:10 +010029endfunc
Bram Moolenaara742e082016-04-05 21:10:38 +020030
Bram Moolenaar300af822017-03-06 20:28:10 +010031" Function used to display syntax group.
32func SyntaxItem()
Bram Moolenaar1c6fd1e2019-05-23 22:11:59 +020033 call assert_equal(s:expected_curbuf, g:actual_curbuf)
34 call assert_equal(s:expected_curwin, g:actual_curwin)
35 return synIDattr(synID(line("."), col("."),1), "name")
Bram Moolenaar300af822017-03-06 20:28:10 +010036endfunc
37
38func Test_caught_error_in_statusline()
Bram Moolenaara742e082016-04-05 21:10:38 +020039 let s:func_in_statusline_called = 0
40 set laststatus=2
41 let statusline = '%{StatuslineWithCaughtError()}'
42 let &statusline = statusline
43 redrawstatus
44 call assert_true(s:func_in_statusline_called)
45 call assert_equal(statusline, &statusline)
46 set statusline=
Bram Moolenaar300af822017-03-06 20:28:10 +010047endfunc
Bram Moolenaara742e082016-04-05 21:10:38 +020048
Bram Moolenaar300af822017-03-06 20:28:10 +010049func Test_statusline_will_be_disabled_with_error()
Bram Moolenaara742e082016-04-05 21:10:38 +020050 let s:func_in_statusline_called = 0
51 set laststatus=2
52 let statusline = '%{StatuslineWithError()}'
53 try
54 let &statusline = statusline
55 redrawstatus
56 catch
57 endtry
58 call assert_true(s:func_in_statusline_called)
59 call assert_equal('', &statusline)
60 set statusline=
Bram Moolenaar300af822017-03-06 20:28:10 +010061endfunc
62
63func Test_statusline()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +010064 CheckFeature quickfix
65
Bram Moolenaar300af822017-03-06 20:28:10 +010066 new Xstatusline
67 only
68 set laststatus=2
69 set splitbelow
Bram Moolenaar316c1672019-04-14 13:23:40 +020070 call setline(1, range(1, 10000))
Bram Moolenaar300af822017-03-06 20:28:10 +010071
72 " %b: Value of character under cursor.
73 " %B: As above, in hexadecimal.
Bram Moolenaar316c1672019-04-14 13:23:40 +020074 call cursor(9000, 1)
Bram Moolenaar300af822017-03-06 20:28:10 +010075 set statusline=%b,%B
Bram Moolenaar316c1672019-04-14 13:23:40 +020076 call assert_match('^57,39\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +010077
78 " %o: Byte number in file of byte under cursor, first byte is 1.
79 " %O: As above, in hexadecimal.
80 set statusline=%o,%O
81 set fileformat=dos
Bram Moolenaar316c1672019-04-14 13:23:40 +020082 call assert_match('^52888,CE98\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +010083 set fileformat=mac
Bram Moolenaar316c1672019-04-14 13:23:40 +020084 call assert_match('^43889,AB71\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +010085 set fileformat=unix
Bram Moolenaar316c1672019-04-14 13:23:40 +020086 call assert_match('^43889,AB71\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +010087 set fileformat&
88
89 " %f: Path to the file in the buffer, as typed or relative to current dir.
90 set statusline=%f
91 call assert_match('^Xstatusline\s*$', s:get_statusline())
92
93 " %F: Full path to the file in the buffer.
94 set statusline=%F
95 call assert_match('/testdir/Xstatusline\s*$', s:get_statusline())
96
97 " %h: Help buffer flag, text is "[help]".
98 " %H: Help buffer flag, text is ",HLP".
99 set statusline=%h,%H
100 call assert_match('^,\s*$', s:get_statusline())
101 help
102 call assert_match('^\[Help\],HLP\s*$', s:get_statusline())
103 helpclose
104
105 " %k: Value of "b:keymap_name" or 'keymap'
106 " when :lmap mappings are being used: <keymap>"
107 set statusline=%k
108 if has('keymap')
109 set keymap=esperanto
110 call assert_match('^<Eo>\s*$', s:get_statusline())
111 set keymap&
112 else
113 call assert_match('^\s*$', s:get_statusline())
114 endif
115
116 " %l: Line number.
117 " %L: Number of line in buffer.
118 " %c: Column number.
119 set statusline=%l/%L,%c
Bram Moolenaar316c1672019-04-14 13:23:40 +0200120 call assert_match('^9000/10000,1\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +0100121
122 " %m: Modified flag, text is "[+]", "[-]" if 'modifiable' is off.
123 " %M: Modified flag, text is ",+" or ",-".
124 set statusline=%m%M
125 call assert_match('^\[+\],+\s*$', s:get_statusline())
126 set nomodifiable
127 call assert_match('^\[+-\],+-\s*$', s:get_statusline())
128 write
129 call assert_match('^\[-\],-\s*$', s:get_statusline())
130 set modifiable&
131 call assert_match('^\s*$', s:get_statusline())
132
133 " %n: Buffer number.
134 set statusline=%n
135 call assert_match('^'.bufnr('%').'\s*$', s:get_statusline())
136
137 " %p: Percentage through file in lines as in CTRL-G.
138 " %P: Percentage through file of displayed window.
139 set statusline=%p,%P
140 0
141 call assert_match('^0,Top\s*$', s:get_statusline())
142 norm G
143 call assert_match('^100,Bot\s*$', s:get_statusline())
Bram Moolenaar316c1672019-04-14 13:23:40 +0200144 9000
Bram Moolenaar300af822017-03-06 20:28:10 +0100145 " Don't check the exact percentage as it depends on the window size
146 call assert_match('^90,\(Top\|Bot\|\d\+%\)\s*$', s:get_statusline())
147
148 " %q: "[Quickfix List]", "[Location List]" or empty.
149 set statusline=%q
150 call assert_match('^\s*$', s:get_statusline())
151 copen
152 call assert_match('^\[Quickfix List\]\s*$', s:get_statusline())
153 cclose
154 lexpr getline(1, 2)
155 lopen
156 call assert_match('^\[Location List\]\s*$', s:get_statusline())
157 lclose
158
159 " %r: Readonly flag, text is "[RO]".
160 " %R: Readonly flag, text is ",RO".
161 set statusline=%r,%R
162 call assert_match('^,\s*$', s:get_statusline())
163 help
164 call assert_match('^\[RO\],RO\s*$', s:get_statusline())
165 helpclose
166
167 " %t: File name (tail) of file in the buffer.
168 set statusline=%t
169 call assert_match('^Xstatusline\s*$', s:get_statusline())
170
171 " %v: Virtual column number.
172 " %V: Virtual column number as -{num}. Not displayed if equal to 'c'.
Bram Moolenaar316c1672019-04-14 13:23:40 +0200173 call cursor(9000, 2)
Bram Moolenaar300af822017-03-06 20:28:10 +0100174 set statusline=%v,%V
175 call assert_match('^2,\s*$', s:get_statusline())
176 set virtualedit=all
177 norm 10|
178 call assert_match('^10,-10\s*$', s:get_statusline())
179 set virtualedit&
180
181 " %w: Preview window flag, text is "[Preview]".
182 " %W: Preview window flag, text is ",PRV".
183 set statusline=%w%W
184 call assert_match('^\s*$', s:get_statusline())
185 pedit
186 wincmd j
187 call assert_match('^\[Preview\],PRV\s*$', s:get_statusline())
188 pclose
189
190 " %y: Type of file in the buffer, e.g., "[vim]". See 'filetype'.
191 " %Y: Type of file in the buffer, e.g., ",VIM". See 'filetype'.
192 set statusline=%y\ %Y
193 call assert_match('^\s*$', s:get_statusline())
194 setfiletype vim
195 call assert_match('^\[vim\] VIM\s*$', s:get_statusline())
196
197 " %=: Separation point between left and right aligned items.
198 set statusline=foo%=bar
199 call assert_match('^foo\s\+bar\s*$', s:get_statusline())
200
201 " Test min/max width, leading zeroes, left/right justify.
202 set statusline=%04B
Bram Moolenaar316c1672019-04-14 13:23:40 +0200203 call cursor(9000, 1)
204 call assert_match('^0039\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +0100205 set statusline=#%4B#
Bram Moolenaar316c1672019-04-14 13:23:40 +0200206 call assert_match('^# 39#\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +0100207 set statusline=#%-4B#
Bram Moolenaar316c1672019-04-14 13:23:40 +0200208 call assert_match('^#39 #\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +0100209 set statusline=%.6f
210 call assert_match('^<sline\s*$', s:get_statusline())
211
212 " %<: Where to truncate.
Bram Moolenaar316c1672019-04-14 13:23:40 +0200213 " First check with when %< should not truncate with many columns
214 exe 'set statusline=a%<b' . repeat('c', &columns - 3) . 'd'
215 call assert_match('^abc\+d$', s:get_statusline())
216 exe 'set statusline=a' . repeat('b', &columns - 2) . '%<c'
217 call assert_match('^ab\+c$', s:get_statusline())
218 " Then check when %< should truncate when there with too few columns.
219 exe 'set statusline=a%<b' . repeat('c', &columns - 2) . 'd'
220 call assert_match('^a<c\+d$', s:get_statusline())
221 exe 'set statusline=a' . repeat('b', &columns - 1) . '%<c'
222 call assert_match('^ab\+>$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +0100223
224 "%{: Evaluate expression between '%{' and '}' and substitute result.
225 syntax on
Bram Moolenaar1c6fd1e2019-05-23 22:11:59 +0200226 let s:expected_curbuf = string(bufnr(''))
227 let s:expected_curwin = string(win_getid())
Bram Moolenaar300af822017-03-06 20:28:10 +0100228 set statusline=%{SyntaxItem()}
229 call assert_match('^vimNumber\s*$', s:get_statusline())
230 s/^/"/
231 call assert_match('^vimLineComment\s*$', s:get_statusline())
232 syntax off
233
234 "%(: Start of item group.
235 set statusline=ab%(cd%q%)de
236 call assert_match('^abde\s*$', s:get_statusline())
237 copen
Bram Moolenaar1ef9bbe2017-06-17 20:08:20 +0200238 call assert_match('^abcd\[Quickfix List]de\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +0100239 cclose
240
241 " %#: Set highlight group. The name must follow and then a # again.
242 set statusline=ab%#Todo#cd%#Error#ef
243 call assert_match('^abcdef\s*$', s:get_statusline())
244 let sa1=screenattr(&lines - 1, 1)
245 let sa2=screenattr(&lines - 1, 3)
246 let sa3=screenattr(&lines - 1, 5)
247 call assert_notequal(sa1, sa2)
248 call assert_notequal(sa1, sa3)
249 call assert_notequal(sa2, sa3)
250 call assert_equal(sa1, screenattr(&lines - 1, 2))
251 call assert_equal(sa2, screenattr(&lines - 1, 4))
252 call assert_equal(sa3, screenattr(&lines - 1, 6))
253 call assert_equal(sa3, screenattr(&lines - 1, 7))
254
255 " %*: Set highlight group to User{N}
256 set statusline=a%1*b%0*c
257 call assert_match('^abc\s*$', s:get_statusline())
258 let sa1=screenattr(&lines - 1, 1)
259 let sa2=screenattr(&lines - 1, 2)
260 let sa3=screenattr(&lines - 1, 3)
261 call assert_equal(sa1, sa3)
262 call assert_notequal(sa1, sa2)
263
Bram Moolenaar6b89dbb2017-10-22 14:22:16 +0200264 " An empty group that contains highlight changes
265 let g:a = ''
266 set statusline=ab%(cd%1*%{g:a}%*%)de
267 call assert_match('^abde\s*$', s:get_statusline())
268 let sa1=screenattr(&lines - 1, 1)
269 let sa2=screenattr(&lines - 1, 4)
270 call assert_equal(sa1, sa2)
271 let g:a = 'X'
272 call assert_match('^abcdXde\s*$', s:get_statusline())
273 let sa1=screenattr(&lines - 1, 1)
274 let sa2=screenattr(&lines - 1, 5)
275 let sa3=screenattr(&lines - 1, 7)
276 call assert_equal(sa1, sa3)
277 call assert_notequal(sa1, sa2)
278
279 let g:a = ''
280 set statusline=ab%1*%(cd%*%{g:a}%1*%)de
281 call assert_match('^abde\s*$', s:get_statusline())
282 let sa1=screenattr(&lines - 1, 1)
283 let sa2=screenattr(&lines - 1, 4)
284 call assert_notequal(sa1, sa2)
285 let g:a = 'X'
286 call assert_match('^abcdXde\s*$', s:get_statusline())
287 let sa1=screenattr(&lines - 1, 1)
288 let sa2=screenattr(&lines - 1, 3)
289 let sa3=screenattr(&lines - 1, 5)
290 let sa4=screenattr(&lines - 1, 7)
291 call assert_notequal(sa1, sa2)
292 call assert_equal(sa1, sa3)
293 call assert_equal(sa2, sa4)
294
295 " An empty group that contains highlight changes and doesn't reset them
296 let g:a = ''
297 set statusline=ab%(cd%1*%{g:a}%)de
298 call assert_match('^abcdde\s*$', s:get_statusline())
299 let sa1=screenattr(&lines - 1, 1)
300 let sa2=screenattr(&lines - 1, 5)
301 call assert_notequal(sa1, sa2)
302 let g:a = 'X'
303 call assert_match('^abcdXde\s*$', s:get_statusline())
304 let sa1=screenattr(&lines - 1, 1)
305 let sa2=screenattr(&lines - 1, 5)
306 let sa3=screenattr(&lines - 1, 7)
307 call assert_notequal(sa1, sa2)
308 call assert_equal(sa2, sa3)
309
310 let g:a = ''
311 set statusline=ab%1*%(cd%*%{g:a}%)de
312 call assert_match('^abcdde\s*$', s:get_statusline())
313 let sa1=screenattr(&lines - 1, 1)
314 let sa2=screenattr(&lines - 1, 3)
315 let sa3=screenattr(&lines - 1, 5)
316 call assert_notequal(sa1, sa2)
317 call assert_equal(sa1, sa3)
318 let g:a = 'X'
319 call assert_match('^abcdXde\s*$', s:get_statusline())
320 let sa1=screenattr(&lines - 1, 1)
321 let sa2=screenattr(&lines - 1, 3)
322 let sa3=screenattr(&lines - 1, 5)
323 let sa4=screenattr(&lines - 1, 7)
324 call assert_notequal(sa1, sa2)
325 call assert_equal(sa1, sa3)
326 call assert_equal(sa1, sa4)
327
Bram Moolenaar235dddf2017-10-26 18:21:24 +0200328 let g:a = ''
329 set statusline=%#Error#{%(\ %{g:a}\ %)}
330 call assert_match('^{}\s*$', s:get_statusline())
331 let g:a = 'X'
332 call assert_match('^{ X }\s*$', s:get_statusline())
333
Bram Moolenaar300af822017-03-06 20:28:10 +0100334 " %%: a percent sign.
335 set statusline=10%%
336 call assert_match('^10%\s*$', s:get_statusline())
337
338 " %!: evaluated expression is used as the option value
339 set statusline=%!2*3+1
340 call assert_match('7\s*$', s:get_statusline())
341
Bram Moolenaar1c6fd1e2019-05-23 22:11:59 +0200342 func GetNested()
343 call assert_equal(string(win_getid()), g:actual_curwin)
344 call assert_equal(string(bufnr('')), g:actual_curbuf)
345 return 'nested'
346 endfunc
347 func GetStatusLine()
348 call assert_equal(win_getid(), g:statusline_winid)
349 return 'the %{GetNested()} line'
350 endfunc
351 set statusline=%!GetStatusLine()
352 call assert_match('the nested line', s:get_statusline())
353 call assert_false(exists('g:actual_curwin'))
354 call assert_false(exists('g:actual_curbuf'))
355 call assert_false(exists('g:statusline_winid'))
356 delfunc GetNested
357 delfunc GetStatusLine
358
Bram Moolenaar300af822017-03-06 20:28:10 +0100359 " Check statusline in current and non-current window
360 " with the 'fillchars' option.
361 set fillchars=stl:^,stlnc:=,vert:\|,fold:-,diff:-
362 vsplit
363 set statusline=x%=y
364 call assert_match('^x^\+y^x=\+y$', s:get_statusline())
365 set fillchars&
366 close
367
368 %bw!
369 call delete('Xstatusline')
370 set statusline&
371 set laststatus&
372 set splitbelow&
373endfunc
Bram Moolenaardee50a52019-11-30 15:05:22 +0100374
375func Test_statusline_visual()
376 func CallWordcount()
377 call wordcount()
378 endfunc
379 new x1
380 setl statusline=count=%{CallWordcount()}
381 " buffer must not be empty
382 call setline(1, 'hello')
383
384 " window with more lines than x1
385 new x2
386 call setline(1, range(10))
387 $
388 " Visual mode in line below liast line in x1 should not give ml_get error
389 call feedkeys("\<C-V>", "xt")
390 redraw
391
392 delfunc CallWordcount
393 bwipe! x1
394 bwipe! x2
395endfunc