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