blob: af05be58e13907683d55ea4121a1e0d7ae096499 [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
10
11func s:get_statusline()
12 return ScreenLines(&lines - 1, &columns)[0]
13endfunc
14
15func StatuslineWithCaughtError()
Bram Moolenaara742e082016-04-05 21:10:38 +020016 let s:func_in_statusline_called = 1
17 try
18 call eval('unknown expression')
19 catch
20 endtry
21 return ''
Bram Moolenaar300af822017-03-06 20:28:10 +010022endfunc
Bram Moolenaara742e082016-04-05 21:10:38 +020023
Bram Moolenaar300af822017-03-06 20:28:10 +010024func StatuslineWithError()
Bram Moolenaara742e082016-04-05 21:10:38 +020025 let s:func_in_statusline_called = 1
26 call eval('unknown expression')
27 return ''
Bram Moolenaar300af822017-03-06 20:28:10 +010028endfunc
Bram Moolenaara742e082016-04-05 21:10:38 +020029
Bram Moolenaar300af822017-03-06 20:28:10 +010030" Function used to display syntax group.
31func SyntaxItem()
Bram Moolenaar1c6fd1e2019-05-23 22:11:59 +020032 call assert_equal(s:expected_curbuf, g:actual_curbuf)
33 call assert_equal(s:expected_curwin, g:actual_curwin)
34 return synIDattr(synID(line("."), col("."),1), "name")
Bram Moolenaar300af822017-03-06 20:28:10 +010035endfunc
36
37func Test_caught_error_in_statusline()
Bram Moolenaara742e082016-04-05 21:10:38 +020038 let s:func_in_statusline_called = 0
39 set laststatus=2
40 let statusline = '%{StatuslineWithCaughtError()}'
41 let &statusline = statusline
42 redrawstatus
43 call assert_true(s:func_in_statusline_called)
44 call assert_equal(statusline, &statusline)
45 set statusline=
Bram Moolenaar300af822017-03-06 20:28:10 +010046endfunc
Bram Moolenaara742e082016-04-05 21:10:38 +020047
Bram Moolenaar300af822017-03-06 20:28:10 +010048func Test_statusline_will_be_disabled_with_error()
Bram Moolenaara742e082016-04-05 21:10:38 +020049 let s:func_in_statusline_called = 0
50 set laststatus=2
51 let statusline = '%{StatuslineWithError()}'
52 try
53 let &statusline = statusline
54 redrawstatus
55 catch
56 endtry
57 call assert_true(s:func_in_statusline_called)
58 call assert_equal('', &statusline)
59 set statusline=
Bram Moolenaar300af822017-03-06 20:28:10 +010060endfunc
61
62func Test_statusline()
63 new Xstatusline
64 only
65 set laststatus=2
66 set splitbelow
Bram Moolenaar316c1672019-04-14 13:23:40 +020067 call setline(1, range(1, 10000))
Bram Moolenaar300af822017-03-06 20:28:10 +010068
69 " %b: Value of character under cursor.
70 " %B: As above, in hexadecimal.
Bram Moolenaar316c1672019-04-14 13:23:40 +020071 call cursor(9000, 1)
Bram Moolenaar300af822017-03-06 20:28:10 +010072 set statusline=%b,%B
Bram Moolenaar316c1672019-04-14 13:23:40 +020073 call assert_match('^57,39\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +010074
75 " %o: Byte number in file of byte under cursor, first byte is 1.
76 " %O: As above, in hexadecimal.
77 set statusline=%o,%O
78 set fileformat=dos
Bram Moolenaar316c1672019-04-14 13:23:40 +020079 call assert_match('^52888,CE98\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +010080 set fileformat=mac
Bram Moolenaar316c1672019-04-14 13:23:40 +020081 call assert_match('^43889,AB71\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +010082 set fileformat=unix
Bram Moolenaar316c1672019-04-14 13:23:40 +020083 call assert_match('^43889,AB71\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +010084 set fileformat&
85
86 " %f: Path to the file in the buffer, as typed or relative to current dir.
87 set statusline=%f
88 call assert_match('^Xstatusline\s*$', s:get_statusline())
89
90 " %F: Full path to the file in the buffer.
91 set statusline=%F
92 call assert_match('/testdir/Xstatusline\s*$', s:get_statusline())
93
94 " %h: Help buffer flag, text is "[help]".
95 " %H: Help buffer flag, text is ",HLP".
96 set statusline=%h,%H
97 call assert_match('^,\s*$', s:get_statusline())
98 help
99 call assert_match('^\[Help\],HLP\s*$', s:get_statusline())
100 helpclose
101
102 " %k: Value of "b:keymap_name" or 'keymap'
103 " when :lmap mappings are being used: <keymap>"
104 set statusline=%k
105 if has('keymap')
106 set keymap=esperanto
107 call assert_match('^<Eo>\s*$', s:get_statusline())
108 set keymap&
109 else
110 call assert_match('^\s*$', s:get_statusline())
111 endif
112
113 " %l: Line number.
114 " %L: Number of line in buffer.
115 " %c: Column number.
116 set statusline=%l/%L,%c
Bram Moolenaar316c1672019-04-14 13:23:40 +0200117 call assert_match('^9000/10000,1\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +0100118
119 " %m: Modified flag, text is "[+]", "[-]" if 'modifiable' is off.
120 " %M: Modified flag, text is ",+" or ",-".
121 set statusline=%m%M
122 call assert_match('^\[+\],+\s*$', s:get_statusline())
123 set nomodifiable
124 call assert_match('^\[+-\],+-\s*$', s:get_statusline())
125 write
126 call assert_match('^\[-\],-\s*$', s:get_statusline())
127 set modifiable&
128 call assert_match('^\s*$', s:get_statusline())
129
130 " %n: Buffer number.
131 set statusline=%n
132 call assert_match('^'.bufnr('%').'\s*$', s:get_statusline())
133
134 " %p: Percentage through file in lines as in CTRL-G.
135 " %P: Percentage through file of displayed window.
136 set statusline=%p,%P
137 0
138 call assert_match('^0,Top\s*$', s:get_statusline())
139 norm G
140 call assert_match('^100,Bot\s*$', s:get_statusline())
Bram Moolenaar316c1672019-04-14 13:23:40 +0200141 9000
Bram Moolenaar300af822017-03-06 20:28:10 +0100142 " Don't check the exact percentage as it depends on the window size
143 call assert_match('^90,\(Top\|Bot\|\d\+%\)\s*$', s:get_statusline())
144
145 " %q: "[Quickfix List]", "[Location List]" or empty.
146 set statusline=%q
147 call assert_match('^\s*$', s:get_statusline())
148 copen
149 call assert_match('^\[Quickfix List\]\s*$', s:get_statusline())
150 cclose
151 lexpr getline(1, 2)
152 lopen
153 call assert_match('^\[Location List\]\s*$', s:get_statusline())
154 lclose
155
156 " %r: Readonly flag, text is "[RO]".
157 " %R: Readonly flag, text is ",RO".
158 set statusline=%r,%R
159 call assert_match('^,\s*$', s:get_statusline())
160 help
161 call assert_match('^\[RO\],RO\s*$', s:get_statusline())
162 helpclose
163
164 " %t: File name (tail) of file in the buffer.
165 set statusline=%t
166 call assert_match('^Xstatusline\s*$', s:get_statusline())
167
168 " %v: Virtual column number.
169 " %V: Virtual column number as -{num}. Not displayed if equal to 'c'.
Bram Moolenaar316c1672019-04-14 13:23:40 +0200170 call cursor(9000, 2)
Bram Moolenaar300af822017-03-06 20:28:10 +0100171 set statusline=%v,%V
172 call assert_match('^2,\s*$', s:get_statusline())
173 set virtualedit=all
174 norm 10|
175 call assert_match('^10,-10\s*$', s:get_statusline())
176 set virtualedit&
177
178 " %w: Preview window flag, text is "[Preview]".
179 " %W: Preview window flag, text is ",PRV".
180 set statusline=%w%W
181 call assert_match('^\s*$', s:get_statusline())
182 pedit
183 wincmd j
184 call assert_match('^\[Preview\],PRV\s*$', s:get_statusline())
185 pclose
186
187 " %y: Type of file in the buffer, e.g., "[vim]". See 'filetype'.
188 " %Y: Type of file in the buffer, e.g., ",VIM". See 'filetype'.
189 set statusline=%y\ %Y
190 call assert_match('^\s*$', s:get_statusline())
191 setfiletype vim
192 call assert_match('^\[vim\] VIM\s*$', s:get_statusline())
193
194 " %=: Separation point between left and right aligned items.
195 set statusline=foo%=bar
196 call assert_match('^foo\s\+bar\s*$', s:get_statusline())
197
198 " Test min/max width, leading zeroes, left/right justify.
199 set statusline=%04B
Bram Moolenaar316c1672019-04-14 13:23:40 +0200200 call cursor(9000, 1)
201 call assert_match('^0039\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +0100202 set statusline=#%4B#
Bram Moolenaar316c1672019-04-14 13:23:40 +0200203 call assert_match('^# 39#\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +0100204 set statusline=#%-4B#
Bram Moolenaar316c1672019-04-14 13:23:40 +0200205 call assert_match('^#39 #\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +0100206 set statusline=%.6f
207 call assert_match('^<sline\s*$', s:get_statusline())
208
209 " %<: Where to truncate.
Bram Moolenaar316c1672019-04-14 13:23:40 +0200210 " First check with when %< should not truncate with many columns
211 exe 'set statusline=a%<b' . repeat('c', &columns - 3) . 'd'
212 call assert_match('^abc\+d$', s:get_statusline())
213 exe 'set statusline=a' . repeat('b', &columns - 2) . '%<c'
214 call assert_match('^ab\+c$', s:get_statusline())
215 " Then check when %< should truncate when there with too few columns.
216 exe 'set statusline=a%<b' . repeat('c', &columns - 2) . 'd'
217 call assert_match('^a<c\+d$', s:get_statusline())
218 exe 'set statusline=a' . repeat('b', &columns - 1) . '%<c'
219 call assert_match('^ab\+>$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +0100220
221 "%{: Evaluate expression between '%{' and '}' and substitute result.
222 syntax on
Bram Moolenaar1c6fd1e2019-05-23 22:11:59 +0200223 let s:expected_curbuf = string(bufnr(''))
224 let s:expected_curwin = string(win_getid())
Bram Moolenaar300af822017-03-06 20:28:10 +0100225 set statusline=%{SyntaxItem()}
226 call assert_match('^vimNumber\s*$', s:get_statusline())
227 s/^/"/
228 call assert_match('^vimLineComment\s*$', s:get_statusline())
229 syntax off
230
231 "%(: Start of item group.
232 set statusline=ab%(cd%q%)de
233 call assert_match('^abde\s*$', s:get_statusline())
234 copen
Bram Moolenaar1ef9bbe2017-06-17 20:08:20 +0200235 call assert_match('^abcd\[Quickfix List]de\s*$', s:get_statusline())
Bram Moolenaar300af822017-03-06 20:28:10 +0100236 cclose
237
238 " %#: Set highlight group. The name must follow and then a # again.
239 set statusline=ab%#Todo#cd%#Error#ef
240 call assert_match('^abcdef\s*$', s:get_statusline())
241 let sa1=screenattr(&lines - 1, 1)
242 let sa2=screenattr(&lines - 1, 3)
243 let sa3=screenattr(&lines - 1, 5)
244 call assert_notequal(sa1, sa2)
245 call assert_notequal(sa1, sa3)
246 call assert_notequal(sa2, sa3)
247 call assert_equal(sa1, screenattr(&lines - 1, 2))
248 call assert_equal(sa2, screenattr(&lines - 1, 4))
249 call assert_equal(sa3, screenattr(&lines - 1, 6))
250 call assert_equal(sa3, screenattr(&lines - 1, 7))
251
252 " %*: Set highlight group to User{N}
253 set statusline=a%1*b%0*c
254 call assert_match('^abc\s*$', s:get_statusline())
255 let sa1=screenattr(&lines - 1, 1)
256 let sa2=screenattr(&lines - 1, 2)
257 let sa3=screenattr(&lines - 1, 3)
258 call assert_equal(sa1, sa3)
259 call assert_notequal(sa1, sa2)
260
Bram Moolenaar6b89dbb2017-10-22 14:22:16 +0200261 " An empty group that contains highlight changes
262 let g:a = ''
263 set statusline=ab%(cd%1*%{g:a}%*%)de
264 call assert_match('^abde\s*$', s:get_statusline())
265 let sa1=screenattr(&lines - 1, 1)
266 let sa2=screenattr(&lines - 1, 4)
267 call assert_equal(sa1, sa2)
268 let g:a = 'X'
269 call assert_match('^abcdXde\s*$', s:get_statusline())
270 let sa1=screenattr(&lines - 1, 1)
271 let sa2=screenattr(&lines - 1, 5)
272 let sa3=screenattr(&lines - 1, 7)
273 call assert_equal(sa1, sa3)
274 call assert_notequal(sa1, sa2)
275
276 let g:a = ''
277 set statusline=ab%1*%(cd%*%{g:a}%1*%)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_notequal(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, 3)
286 let sa3=screenattr(&lines - 1, 5)
287 let sa4=screenattr(&lines - 1, 7)
288 call assert_notequal(sa1, sa2)
289 call assert_equal(sa1, sa3)
290 call assert_equal(sa2, sa4)
291
292 " An empty group that contains highlight changes and doesn't reset them
293 let g:a = ''
294 set statusline=ab%(cd%1*%{g:a}%)de
295 call assert_match('^abcdde\s*$', s:get_statusline())
296 let sa1=screenattr(&lines - 1, 1)
297 let sa2=screenattr(&lines - 1, 5)
298 call assert_notequal(sa1, sa2)
299 let g:a = 'X'
300 call assert_match('^abcdXde\s*$', s:get_statusline())
301 let sa1=screenattr(&lines - 1, 1)
302 let sa2=screenattr(&lines - 1, 5)
303 let sa3=screenattr(&lines - 1, 7)
304 call assert_notequal(sa1, sa2)
305 call assert_equal(sa2, sa3)
306
307 let g:a = ''
308 set statusline=ab%1*%(cd%*%{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, 3)
312 let sa3=screenattr(&lines - 1, 5)
313 call assert_notequal(sa1, sa2)
314 call assert_equal(sa1, sa3)
315 let g:a = 'X'
316 call assert_match('^abcdXde\s*$', s:get_statusline())
317 let sa1=screenattr(&lines - 1, 1)
318 let sa2=screenattr(&lines - 1, 3)
319 let sa3=screenattr(&lines - 1, 5)
320 let sa4=screenattr(&lines - 1, 7)
321 call assert_notequal(sa1, sa2)
322 call assert_equal(sa1, sa3)
323 call assert_equal(sa1, sa4)
324
Bram Moolenaar235dddf2017-10-26 18:21:24 +0200325 let g:a = ''
326 set statusline=%#Error#{%(\ %{g:a}\ %)}
327 call assert_match('^{}\s*$', s:get_statusline())
328 let g:a = 'X'
329 call assert_match('^{ X }\s*$', s:get_statusline())
330
Bram Moolenaar300af822017-03-06 20:28:10 +0100331 " %%: a percent sign.
332 set statusline=10%%
333 call assert_match('^10%\s*$', s:get_statusline())
334
335 " %!: evaluated expression is used as the option value
336 set statusline=%!2*3+1
337 call assert_match('7\s*$', s:get_statusline())
338
Bram Moolenaar1c6fd1e2019-05-23 22:11:59 +0200339 func GetNested()
340 call assert_equal(string(win_getid()), g:actual_curwin)
341 call assert_equal(string(bufnr('')), g:actual_curbuf)
342 return 'nested'
343 endfunc
344 func GetStatusLine()
345 call assert_equal(win_getid(), g:statusline_winid)
346 return 'the %{GetNested()} line'
347 endfunc
348 set statusline=%!GetStatusLine()
349 call assert_match('the nested line', s:get_statusline())
350 call assert_false(exists('g:actual_curwin'))
351 call assert_false(exists('g:actual_curbuf'))
352 call assert_false(exists('g:statusline_winid'))
353 delfunc GetNested
354 delfunc GetStatusLine
355
Bram Moolenaar300af822017-03-06 20:28:10 +0100356 " Check statusline in current and non-current window
357 " with the 'fillchars' option.
358 set fillchars=stl:^,stlnc:=,vert:\|,fold:-,diff:-
359 vsplit
360 set statusline=x%=y
361 call assert_match('^x^\+y^x=\+y$', s:get_statusline())
362 set fillchars&
363 close
364
365 %bw!
366 call delete('Xstatusline')
367 set statusline&
368 set laststatus&
369 set splitbelow&
370endfunc
Bram Moolenaardee50a52019-11-30 15:05:22 +0100371
372func Test_statusline_visual()
373 func CallWordcount()
374 call wordcount()
375 endfunc
376 new x1
377 setl statusline=count=%{CallWordcount()}
378 " buffer must not be empty
379 call setline(1, 'hello')
380
381 " window with more lines than x1
382 new x2
383 call setline(1, range(10))
384 $
385 " Visual mode in line below liast line in x1 should not give ml_get error
386 call feedkeys("\<C-V>", "xt")
387 redraw
388
389 delfunc CallWordcount
390 bwipe! x1
391 bwipe! x2
392endfunc