Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 1 | " Test 'statusline' |
| 2 | " |
| 3 | " Not tested yet: |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 4 | " %N |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 5 | |
Christian Brabandt | eb380b9 | 2025-07-07 20:53:55 +0200 | [diff] [blame] | 6 | source util/screendump.vim |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 7 | |
zeertzjq | bb404f5 | 2022-07-23 06:25:29 +0100 | [diff] [blame] | 8 | func SetUp() |
| 9 | set laststatus=2 |
| 10 | endfunc |
| 11 | |
| 12 | func TearDown() |
| 13 | set laststatus& |
| 14 | endfunc |
| 15 | |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 16 | func s:get_statusline() |
Drew Vogel | ea67ba7 | 2025-05-07 22:05:17 +0200 | [diff] [blame] | 17 | if has('gui_running') |
| 18 | redraw! |
| 19 | sleep 1m |
| 20 | endif |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 21 | return ScreenLines(&lines - 1, &columns)[0] |
| 22 | endfunc |
| 23 | |
| 24 | func StatuslineWithCaughtError() |
Bram Moolenaar | a742e08 | 2016-04-05 21:10:38 +0200 | [diff] [blame] | 25 | let s:func_in_statusline_called = 1 |
| 26 | try |
| 27 | call eval('unknown expression') |
| 28 | catch |
| 29 | endtry |
| 30 | return '' |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 31 | endfunc |
Bram Moolenaar | a742e08 | 2016-04-05 21:10:38 +0200 | [diff] [blame] | 32 | |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 33 | func StatuslineWithError() |
Bram Moolenaar | a742e08 | 2016-04-05 21:10:38 +0200 | [diff] [blame] | 34 | let s:func_in_statusline_called = 1 |
| 35 | call eval('unknown expression') |
| 36 | return '' |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 37 | endfunc |
Bram Moolenaar | a742e08 | 2016-04-05 21:10:38 +0200 | [diff] [blame] | 38 | |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 39 | " Function used to display syntax group. |
| 40 | func SyntaxItem() |
Bram Moolenaar | 1c6fd1e | 2019-05-23 22:11:59 +0200 | [diff] [blame] | 41 | call assert_equal(s:expected_curbuf, g:actual_curbuf) |
| 42 | call assert_equal(s:expected_curwin, g:actual_curwin) |
| 43 | return synIDattr(synID(line("."), col("."),1), "name") |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 44 | endfunc |
| 45 | |
| 46 | func Test_caught_error_in_statusline() |
Bram Moolenaar | a742e08 | 2016-04-05 21:10:38 +0200 | [diff] [blame] | 47 | let s:func_in_statusline_called = 0 |
Bram Moolenaar | a742e08 | 2016-04-05 21:10:38 +0200 | [diff] [blame] | 48 | let statusline = '%{StatuslineWithCaughtError()}' |
| 49 | let &statusline = statusline |
| 50 | redrawstatus |
| 51 | call assert_true(s:func_in_statusline_called) |
| 52 | call assert_equal(statusline, &statusline) |
| 53 | set statusline= |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 54 | endfunc |
Bram Moolenaar | a742e08 | 2016-04-05 21:10:38 +0200 | [diff] [blame] | 55 | |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 56 | func Test_statusline_will_be_disabled_with_error() |
Bram Moolenaar | a742e08 | 2016-04-05 21:10:38 +0200 | [diff] [blame] | 57 | let s:func_in_statusline_called = 0 |
Bram Moolenaar | a742e08 | 2016-04-05 21:10:38 +0200 | [diff] [blame] | 58 | let statusline = '%{StatuslineWithError()}' |
| 59 | try |
| 60 | let &statusline = statusline |
| 61 | redrawstatus |
| 62 | catch |
| 63 | endtry |
| 64 | call assert_true(s:func_in_statusline_called) |
| 65 | call assert_equal('', &statusline) |
| 66 | set statusline= |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 67 | endfunc |
| 68 | |
| 69 | func Test_statusline() |
Bram Moolenaar | 5a4c308 | 2019-12-01 15:23:11 +0100 | [diff] [blame] | 70 | CheckFeature quickfix |
| 71 | |
Bram Moolenaar | 4014e2c | 2020-06-23 20:00:50 +0200 | [diff] [blame] | 72 | " %a: Argument list ({current} of {max}) |
| 73 | set statusline=%a |
| 74 | call assert_match('^\s*$', s:get_statusline()) |
| 75 | arglocal a1 a2 |
| 76 | rewind |
| 77 | call assert_match('^ (1 of 2)\s*$', s:get_statusline()) |
| 78 | next |
| 79 | call assert_match('^ (2 of 2)\s*$', s:get_statusline()) |
| 80 | e Xstatusline |
| 81 | call assert_match('^ ((2) of 2)\s*$', s:get_statusline()) |
| 82 | |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 83 | only |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 84 | set splitbelow |
Bram Moolenaar | 316c167 | 2019-04-14 13:23:40 +0200 | [diff] [blame] | 85 | call setline(1, range(1, 10000)) |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 86 | |
| 87 | " %b: Value of character under cursor. |
| 88 | " %B: As above, in hexadecimal. |
Bram Moolenaar | 316c167 | 2019-04-14 13:23:40 +0200 | [diff] [blame] | 89 | call cursor(9000, 1) |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 90 | set statusline=%b,%B |
Bram Moolenaar | 316c167 | 2019-04-14 13:23:40 +0200 | [diff] [blame] | 91 | call assert_match('^57,39\s*$', s:get_statusline()) |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 92 | |
| 93 | " %o: Byte number in file of byte under cursor, first byte is 1. |
| 94 | " %O: As above, in hexadecimal. |
| 95 | set statusline=%o,%O |
| 96 | set fileformat=dos |
Bram Moolenaar | 316c167 | 2019-04-14 13:23:40 +0200 | [diff] [blame] | 97 | call assert_match('^52888,CE98\s*$', s:get_statusline()) |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 98 | set fileformat=mac |
Bram Moolenaar | 316c167 | 2019-04-14 13:23:40 +0200 | [diff] [blame] | 99 | call assert_match('^43889,AB71\s*$', s:get_statusline()) |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 100 | set fileformat=unix |
Bram Moolenaar | 316c167 | 2019-04-14 13:23:40 +0200 | [diff] [blame] | 101 | call assert_match('^43889,AB71\s*$', s:get_statusline()) |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 102 | set fileformat& |
| 103 | |
| 104 | " %f: Path to the file in the buffer, as typed or relative to current dir. |
| 105 | set statusline=%f |
| 106 | call assert_match('^Xstatusline\s*$', s:get_statusline()) |
| 107 | |
| 108 | " %F: Full path to the file in the buffer. |
| 109 | set statusline=%F |
| 110 | call assert_match('/testdir/Xstatusline\s*$', s:get_statusline()) |
| 111 | |
Bram Moolenaar | 832adf9 | 2020-06-25 19:01:36 +0200 | [diff] [blame] | 112 | " Test for min and max width with %(. For some reason, if this test is moved |
| 113 | " after the below test for the help buffer flag, then the code to truncate |
| 114 | " the string is not executed. |
| 115 | set statusline=%015(%f%) |
| 116 | call assert_match('^ Xstatusline\s*$', s:get_statusline()) |
| 117 | set statusline=%.6(%f%) |
| 118 | call assert_match('^<sline\s*$', s:get_statusline()) |
| 119 | set statusline=%14f |
| 120 | call assert_match('^ Xstatusline\s*$', s:get_statusline()) |
| 121 | set statusline=%.4L |
| 122 | call assert_match('^10>3\s*$', s:get_statusline()) |
| 123 | |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 124 | " %h: Help buffer flag, text is "[help]". |
| 125 | " %H: Help buffer flag, text is ",HLP". |
| 126 | set statusline=%h,%H |
| 127 | call assert_match('^,\s*$', s:get_statusline()) |
| 128 | help |
| 129 | call assert_match('^\[Help\],HLP\s*$', s:get_statusline()) |
| 130 | helpclose |
| 131 | |
| 132 | " %k: Value of "b:keymap_name" or 'keymap' |
| 133 | " when :lmap mappings are being used: <keymap>" |
| 134 | set statusline=%k |
| 135 | if has('keymap') |
| 136 | set keymap=esperanto |
| 137 | call assert_match('^<Eo>\s*$', s:get_statusline()) |
| 138 | set keymap& |
| 139 | else |
| 140 | call assert_match('^\s*$', s:get_statusline()) |
| 141 | endif |
| 142 | |
| 143 | " %l: Line number. |
| 144 | " %L: Number of line in buffer. |
| 145 | " %c: Column number. |
| 146 | set statusline=%l/%L,%c |
Bram Moolenaar | 316c167 | 2019-04-14 13:23:40 +0200 | [diff] [blame] | 147 | call assert_match('^9000/10000,1\s*$', s:get_statusline()) |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 148 | |
| 149 | " %m: Modified flag, text is "[+]", "[-]" if 'modifiable' is off. |
| 150 | " %M: Modified flag, text is ",+" or ",-". |
| 151 | set statusline=%m%M |
| 152 | call assert_match('^\[+\],+\s*$', s:get_statusline()) |
| 153 | set nomodifiable |
| 154 | call assert_match('^\[+-\],+-\s*$', s:get_statusline()) |
| 155 | write |
| 156 | call assert_match('^\[-\],-\s*$', s:get_statusline()) |
| 157 | set modifiable& |
| 158 | call assert_match('^\s*$', s:get_statusline()) |
| 159 | |
| 160 | " %n: Buffer number. |
| 161 | set statusline=%n |
| 162 | call assert_match('^'.bufnr('%').'\s*$', s:get_statusline()) |
| 163 | |
| 164 | " %p: Percentage through file in lines as in CTRL-G. |
| 165 | " %P: Percentage through file of displayed window. |
| 166 | set statusline=%p,%P |
| 167 | 0 |
| 168 | call assert_match('^0,Top\s*$', s:get_statusline()) |
| 169 | norm G |
| 170 | call assert_match('^100,Bot\s*$', s:get_statusline()) |
Bram Moolenaar | 316c167 | 2019-04-14 13:23:40 +0200 | [diff] [blame] | 171 | 9000 |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 172 | " Don't check the exact percentage as it depends on the window size |
| 173 | call assert_match('^90,\(Top\|Bot\|\d\+%\)\s*$', s:get_statusline()) |
| 174 | |
| 175 | " %q: "[Quickfix List]", "[Location List]" or empty. |
| 176 | set statusline=%q |
| 177 | call assert_match('^\s*$', s:get_statusline()) |
| 178 | copen |
| 179 | call assert_match('^\[Quickfix List\]\s*$', s:get_statusline()) |
| 180 | cclose |
| 181 | lexpr getline(1, 2) |
| 182 | lopen |
| 183 | call assert_match('^\[Location List\]\s*$', s:get_statusline()) |
| 184 | lclose |
| 185 | |
| 186 | " %r: Readonly flag, text is "[RO]". |
| 187 | " %R: Readonly flag, text is ",RO". |
| 188 | set statusline=%r,%R |
| 189 | call assert_match('^,\s*$', s:get_statusline()) |
| 190 | help |
| 191 | call assert_match('^\[RO\],RO\s*$', s:get_statusline()) |
| 192 | helpclose |
| 193 | |
| 194 | " %t: File name (tail) of file in the buffer. |
| 195 | set statusline=%t |
| 196 | call assert_match('^Xstatusline\s*$', s:get_statusline()) |
| 197 | |
| 198 | " %v: Virtual column number. |
| 199 | " %V: Virtual column number as -{num}. Not displayed if equal to 'c'. |
Bram Moolenaar | 316c167 | 2019-04-14 13:23:40 +0200 | [diff] [blame] | 200 | call cursor(9000, 2) |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 201 | set statusline=%v,%V |
| 202 | call assert_match('^2,\s*$', s:get_statusline()) |
| 203 | set virtualedit=all |
| 204 | norm 10| |
| 205 | call assert_match('^10,-10\s*$', s:get_statusline()) |
zeertzjq | 0f11205 | 2022-01-14 20:11:38 +0000 | [diff] [blame] | 206 | set list |
| 207 | call assert_match('^10,-10\s*$', s:get_statusline()) |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 208 | set virtualedit& |
zeertzjq | 0f11205 | 2022-01-14 20:11:38 +0000 | [diff] [blame] | 209 | exe "norm A\<Tab>\<Tab>a\<Esc>" |
| 210 | " In list mode a <Tab> is shown as "^I", which is 2-wide. |
| 211 | call assert_match('^9,-9\s*$', s:get_statusline()) |
| 212 | set list& |
| 213 | " Now the second <Tab> ends at the 16th screen column. |
| 214 | call assert_match('^17,-17\s*$', s:get_statusline()) |
| 215 | undo |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 216 | |
| 217 | " %w: Preview window flag, text is "[Preview]". |
| 218 | " %W: Preview window flag, text is ",PRV". |
| 219 | set statusline=%w%W |
| 220 | call assert_match('^\s*$', s:get_statusline()) |
| 221 | pedit |
| 222 | wincmd j |
| 223 | call assert_match('^\[Preview\],PRV\s*$', s:get_statusline()) |
| 224 | pclose |
Yinzuo Jiang | a2a2fe8 | 2024-12-16 21:22:09 +0100 | [diff] [blame] | 225 | pbuffer |
| 226 | wincmd j |
| 227 | call assert_match('^\[Preview\],PRV\s*$', s:get_statusline()) |
| 228 | pclose |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 229 | |
| 230 | " %y: Type of file in the buffer, e.g., "[vim]". See 'filetype'. |
| 231 | " %Y: Type of file in the buffer, e.g., ",VIM". See 'filetype'. |
| 232 | set statusline=%y\ %Y |
| 233 | call assert_match('^\s*$', s:get_statusline()) |
| 234 | setfiletype vim |
| 235 | call assert_match('^\[vim\] VIM\s*$', s:get_statusline()) |
| 236 | |
| 237 | " %=: Separation point between left and right aligned items. |
| 238 | set statusline=foo%=bar |
| 239 | call assert_match('^foo\s\+bar\s*$', s:get_statusline()) |
Yegappan Lakshmanan | 3ec78f9 | 2023-02-11 11:15:25 +0000 | [diff] [blame] | 240 | set statusline=foo%=bar%=baz |
| 241 | call assert_match('^foo\s\+bar\s\+baz\s*$', s:get_statusline()) |
| 242 | set statusline=foo%=bar%=baz%=qux |
| 243 | call assert_match('^foo\s\+bar\s\+baz\s\+qux\s*$', s:get_statusline()) |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 244 | |
| 245 | " Test min/max width, leading zeroes, left/right justify. |
| 246 | set statusline=%04B |
Bram Moolenaar | 316c167 | 2019-04-14 13:23:40 +0200 | [diff] [blame] | 247 | call cursor(9000, 1) |
| 248 | call assert_match('^0039\s*$', s:get_statusline()) |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 249 | set statusline=#%4B# |
Bram Moolenaar | 316c167 | 2019-04-14 13:23:40 +0200 | [diff] [blame] | 250 | call assert_match('^# 39#\s*$', s:get_statusline()) |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 251 | set statusline=#%-4B# |
Bram Moolenaar | 316c167 | 2019-04-14 13:23:40 +0200 | [diff] [blame] | 252 | call assert_match('^#39 #\s*$', s:get_statusline()) |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 253 | set statusline=%.6f |
| 254 | call assert_match('^<sline\s*$', s:get_statusline()) |
| 255 | |
| 256 | " %<: Where to truncate. |
Bram Moolenaar | 316c167 | 2019-04-14 13:23:40 +0200 | [diff] [blame] | 257 | " First check with when %< should not truncate with many columns |
| 258 | exe 'set statusline=a%<b' . repeat('c', &columns - 3) . 'd' |
| 259 | call assert_match('^abc\+d$', s:get_statusline()) |
| 260 | exe 'set statusline=a' . repeat('b', &columns - 2) . '%<c' |
| 261 | call assert_match('^ab\+c$', s:get_statusline()) |
| 262 | " Then check when %< should truncate when there with too few columns. |
| 263 | exe 'set statusline=a%<b' . repeat('c', &columns - 2) . 'd' |
| 264 | call assert_match('^a<c\+d$', s:get_statusline()) |
| 265 | exe 'set statusline=a' . repeat('b', &columns - 1) . '%<c' |
| 266 | call assert_match('^ab\+>$', s:get_statusline()) |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 267 | |
| 268 | "%{: Evaluate expression between '%{' and '}' and substitute result. |
| 269 | syntax on |
Bram Moolenaar | 1c6fd1e | 2019-05-23 22:11:59 +0200 | [diff] [blame] | 270 | let s:expected_curbuf = string(bufnr('')) |
| 271 | let s:expected_curwin = string(win_getid()) |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 272 | set statusline=%{SyntaxItem()} |
| 273 | call assert_match('^vimNumber\s*$', s:get_statusline()) |
| 274 | s/^/"/ |
| 275 | call assert_match('^vimLineComment\s*$', s:get_statusline()) |
| 276 | syntax off |
| 277 | |
Dominique Pelle | 81b573d | 2022-03-22 21:14:55 +0000 | [diff] [blame] | 278 | "%{%expr%}: evaluates expressions present in result of expr |
shadmansaleh | 30e3de2 | 2021-05-15 17:23:28 +0200 | [diff] [blame] | 279 | func! Inner_eval() |
| 280 | return '%n some other text' |
| 281 | endfunc |
| 282 | func! Outer_eval() |
| 283 | return 'some text %{%Inner_eval()%}' |
| 284 | endfunc |
| 285 | set statusline=%{%Outer_eval()%} |
| 286 | call assert_match('^some text ' . bufnr() . ' some other text\s*$', s:get_statusline()) |
| 287 | delfunc Inner_eval |
| 288 | delfunc Outer_eval |
| 289 | |
| 290 | "%{%expr%}: Doesn't get stuck in recursion |
| 291 | func! Recurse_eval() |
| 292 | return '%{%Recurse_eval()%}' |
| 293 | endfunc |
| 294 | set statusline=%{%Recurse_eval()%} |
| 295 | call assert_match('^%{%Recurse_eval()%}\s*$', s:get_statusline()) |
| 296 | delfunc Recurse_eval |
| 297 | |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 298 | "%(: Start of item group. |
| 299 | set statusline=ab%(cd%q%)de |
| 300 | call assert_match('^abde\s*$', s:get_statusline()) |
| 301 | copen |
Bram Moolenaar | 1ef9bbe | 2017-06-17 20:08:20 +0200 | [diff] [blame] | 302 | call assert_match('^abcd\[Quickfix List]de\s*$', s:get_statusline()) |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 303 | cclose |
| 304 | |
| 305 | " %#: Set highlight group. The name must follow and then a # again. |
| 306 | set statusline=ab%#Todo#cd%#Error#ef |
| 307 | call assert_match('^abcdef\s*$', s:get_statusline()) |
| 308 | let sa1=screenattr(&lines - 1, 1) |
| 309 | let sa2=screenattr(&lines - 1, 3) |
| 310 | let sa3=screenattr(&lines - 1, 5) |
| 311 | call assert_notequal(sa1, sa2) |
| 312 | call assert_notequal(sa1, sa3) |
| 313 | call assert_notequal(sa2, sa3) |
| 314 | call assert_equal(sa1, screenattr(&lines - 1, 2)) |
| 315 | call assert_equal(sa2, screenattr(&lines - 1, 4)) |
| 316 | call assert_equal(sa3, screenattr(&lines - 1, 6)) |
| 317 | call assert_equal(sa3, screenattr(&lines - 1, 7)) |
| 318 | |
| 319 | " %*: Set highlight group to User{N} |
| 320 | set statusline=a%1*b%0*c |
| 321 | call assert_match('^abc\s*$', s:get_statusline()) |
| 322 | let sa1=screenattr(&lines - 1, 1) |
| 323 | let sa2=screenattr(&lines - 1, 2) |
| 324 | let sa3=screenattr(&lines - 1, 3) |
| 325 | call assert_equal(sa1, sa3) |
| 326 | call assert_notequal(sa1, sa2) |
| 327 | |
Bram Moolenaar | 6b89dbb | 2017-10-22 14:22:16 +0200 | [diff] [blame] | 328 | " An empty group that contains highlight changes |
| 329 | let g:a = '' |
| 330 | set statusline=ab%(cd%1*%{g:a}%*%)de |
| 331 | call assert_match('^abde\s*$', s:get_statusline()) |
| 332 | let sa1=screenattr(&lines - 1, 1) |
| 333 | let sa2=screenattr(&lines - 1, 4) |
| 334 | call assert_equal(sa1, sa2) |
| 335 | let g:a = 'X' |
| 336 | call assert_match('^abcdXde\s*$', s:get_statusline()) |
| 337 | let sa1=screenattr(&lines - 1, 1) |
| 338 | let sa2=screenattr(&lines - 1, 5) |
| 339 | let sa3=screenattr(&lines - 1, 7) |
| 340 | call assert_equal(sa1, sa3) |
| 341 | call assert_notequal(sa1, sa2) |
| 342 | |
| 343 | let g:a = '' |
| 344 | set statusline=ab%1*%(cd%*%{g:a}%1*%)de |
| 345 | call assert_match('^abde\s*$', s:get_statusline()) |
| 346 | let sa1=screenattr(&lines - 1, 1) |
| 347 | let sa2=screenattr(&lines - 1, 4) |
| 348 | call assert_notequal(sa1, sa2) |
| 349 | let g:a = 'X' |
| 350 | call assert_match('^abcdXde\s*$', s:get_statusline()) |
| 351 | let sa1=screenattr(&lines - 1, 1) |
| 352 | let sa2=screenattr(&lines - 1, 3) |
| 353 | let sa3=screenattr(&lines - 1, 5) |
| 354 | let sa4=screenattr(&lines - 1, 7) |
| 355 | call assert_notequal(sa1, sa2) |
| 356 | call assert_equal(sa1, sa3) |
| 357 | call assert_equal(sa2, sa4) |
| 358 | |
| 359 | " An empty group that contains highlight changes and doesn't reset them |
| 360 | let g:a = '' |
| 361 | set statusline=ab%(cd%1*%{g:a}%)de |
| 362 | call assert_match('^abcdde\s*$', s:get_statusline()) |
| 363 | let sa1=screenattr(&lines - 1, 1) |
| 364 | let sa2=screenattr(&lines - 1, 5) |
| 365 | call assert_notequal(sa1, sa2) |
| 366 | let g:a = 'X' |
| 367 | call assert_match('^abcdXde\s*$', s:get_statusline()) |
| 368 | let sa1=screenattr(&lines - 1, 1) |
| 369 | let sa2=screenattr(&lines - 1, 5) |
| 370 | let sa3=screenattr(&lines - 1, 7) |
| 371 | call assert_notequal(sa1, sa2) |
| 372 | call assert_equal(sa2, sa3) |
| 373 | |
| 374 | let g:a = '' |
| 375 | set statusline=ab%1*%(cd%*%{g:a}%)de |
| 376 | call assert_match('^abcdde\s*$', s:get_statusline()) |
| 377 | let sa1=screenattr(&lines - 1, 1) |
| 378 | let sa2=screenattr(&lines - 1, 3) |
| 379 | let sa3=screenattr(&lines - 1, 5) |
| 380 | call assert_notequal(sa1, sa2) |
| 381 | call assert_equal(sa1, sa3) |
| 382 | let g:a = 'X' |
| 383 | call assert_match('^abcdXde\s*$', s:get_statusline()) |
| 384 | let sa1=screenattr(&lines - 1, 1) |
| 385 | let sa2=screenattr(&lines - 1, 3) |
| 386 | let sa3=screenattr(&lines - 1, 5) |
| 387 | let sa4=screenattr(&lines - 1, 7) |
| 388 | call assert_notequal(sa1, sa2) |
| 389 | call assert_equal(sa1, sa3) |
| 390 | call assert_equal(sa1, sa4) |
| 391 | |
Bram Moolenaar | 235dddf | 2017-10-26 18:21:24 +0200 | [diff] [blame] | 392 | let g:a = '' |
| 393 | set statusline=%#Error#{%(\ %{g:a}\ %)} |
| 394 | call assert_match('^{}\s*$', s:get_statusline()) |
| 395 | let g:a = 'X' |
| 396 | call assert_match('^{ X }\s*$', s:get_statusline()) |
| 397 | |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 398 | " %%: a percent sign. |
| 399 | set statusline=10%% |
| 400 | call assert_match('^10%\s*$', s:get_statusline()) |
| 401 | |
| 402 | " %!: evaluated expression is used as the option value |
| 403 | set statusline=%!2*3+1 |
| 404 | call assert_match('7\s*$', s:get_statusline()) |
| 405 | |
Bram Moolenaar | 1c6fd1e | 2019-05-23 22:11:59 +0200 | [diff] [blame] | 406 | func GetNested() |
| 407 | call assert_equal(string(win_getid()), g:actual_curwin) |
| 408 | call assert_equal(string(bufnr('')), g:actual_curbuf) |
| 409 | return 'nested' |
| 410 | endfunc |
| 411 | func GetStatusLine() |
| 412 | call assert_equal(win_getid(), g:statusline_winid) |
| 413 | return 'the %{GetNested()} line' |
| 414 | endfunc |
| 415 | set statusline=%!GetStatusLine() |
| 416 | call assert_match('the nested line', s:get_statusline()) |
| 417 | call assert_false(exists('g:actual_curwin')) |
| 418 | call assert_false(exists('g:actual_curbuf')) |
| 419 | call assert_false(exists('g:statusline_winid')) |
| 420 | delfunc GetNested |
| 421 | delfunc GetStatusLine |
| 422 | |
Bram Moolenaar | 8133cc6 | 2020-10-26 21:05:27 +0100 | [diff] [blame] | 423 | " Test statusline works with 80+ items |
| 424 | function! StatusLabel() |
| 425 | redrawstatus |
Bram Moolenaar | 94722c5 | 2023-01-28 19:19:03 +0000 | [diff] [blame] | 426 | return '[label]' |
Bram Moolenaar | 8133cc6 | 2020-10-26 21:05:27 +0100 | [diff] [blame] | 427 | endfunc |
| 428 | let statusline = '%{StatusLabel()}' |
| 429 | for i in range(150) |
| 430 | let statusline .= '%#TabLine' . (i % 2 == 0 ? 'Fill' : 'Sel') . '#' . string(i)[0] |
| 431 | endfor |
| 432 | let &statusline = statusline |
| 433 | redrawstatus |
| 434 | set statusline& |
| 435 | delfunc StatusLabel |
| 436 | |
| 437 | |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 438 | " Check statusline in current and non-current window |
| 439 | " with the 'fillchars' option. |
| 440 | set fillchars=stl:^,stlnc:=,vert:\|,fold:-,diff:- |
| 441 | vsplit |
| 442 | set statusline=x%=y |
| 443 | call assert_match('^x^\+y^x=\+y$', s:get_statusline()) |
| 444 | set fillchars& |
| 445 | close |
| 446 | |
| 447 | %bw! |
| 448 | call delete('Xstatusline') |
| 449 | set statusline& |
Bram Moolenaar | 300af82 | 2017-03-06 20:28:10 +0100 | [diff] [blame] | 450 | set splitbelow& |
| 451 | endfunc |
Bram Moolenaar | dee50a5 | 2019-11-30 15:05:22 +0100 | [diff] [blame] | 452 | |
Bram Moolenaar | 7b17eb4 | 2023-01-04 14:31:49 +0000 | [diff] [blame] | 453 | func Test_statusline_trailing_percent_zero() |
| 454 | " this was causing illegal memory access |
| 455 | set laststatus=2 stl=%!%0 |
| 456 | call assert_fails('redraw', 'E15: Invalid expression: "%0"') |
| 457 | set laststatus& stl& |
| 458 | endfunc |
| 459 | |
Bram Moolenaar | dee50a5 | 2019-11-30 15:05:22 +0100 | [diff] [blame] | 460 | func Test_statusline_visual() |
| 461 | func CallWordcount() |
| 462 | call wordcount() |
| 463 | endfunc |
| 464 | new x1 |
| 465 | setl statusline=count=%{CallWordcount()} |
| 466 | " buffer must not be empty |
| 467 | call setline(1, 'hello') |
| 468 | |
| 469 | " window with more lines than x1 |
| 470 | new x2 |
| 471 | call setline(1, range(10)) |
| 472 | $ |
| 473 | " Visual mode in line below liast line in x1 should not give ml_get error |
| 474 | call feedkeys("\<C-V>", "xt") |
| 475 | redraw |
| 476 | |
| 477 | delfunc CallWordcount |
| 478 | bwipe! x1 |
| 479 | bwipe! x2 |
| 480 | endfunc |
Bram Moolenaar | dbe5d36 | 2020-02-08 18:35:31 +0100 | [diff] [blame] | 481 | |
| 482 | func Test_statusline_removed_group() |
| 483 | CheckScreendump |
| 484 | |
| 485 | let lines =<< trim END |
| 486 | scriptencoding utf-8 |
| 487 | set laststatus=2 |
| 488 | let &statusline = '%#StatColorHi2#%(✓%#StatColorHi2#%) Q≡' |
| 489 | END |
Bram Moolenaar | 5656496 | 2022-10-10 22:39:42 +0100 | [diff] [blame] | 490 | call writefile(lines, 'XTest_statusline', 'D') |
Bram Moolenaar | dbe5d36 | 2020-02-08 18:35:31 +0100 | [diff] [blame] | 491 | |
| 492 | let buf = RunVimInTerminal('-S XTest_statusline', {'rows': 10, 'cols': 50}) |
Bram Moolenaar | dbe5d36 | 2020-02-08 18:35:31 +0100 | [diff] [blame] | 493 | call VerifyScreenDump(buf, 'Test_statusline_1', {}) |
| 494 | |
| 495 | " clean up |
| 496 | call StopVimInTerminal(buf) |
Bram Moolenaar | dbe5d36 | 2020-02-08 18:35:31 +0100 | [diff] [blame] | 497 | endfunc |
Bram Moolenaar | 832adf9 | 2020-06-25 19:01:36 +0200 | [diff] [blame] | 498 | |
Bram Moolenaar | ce0b757 | 2021-04-01 18:47:14 +0200 | [diff] [blame] | 499 | func Test_statusline_using_mode() |
| 500 | CheckScreendump |
| 501 | |
| 502 | let lines =<< trim END |
Bram Moolenaar | d8db838 | 2021-04-08 18:27:53 +0200 | [diff] [blame] | 503 | setlocal statusline=-%{mode()}- |
| 504 | split |
| 505 | setlocal statusline=+%{mode()}+ |
Bram Moolenaar | ce0b757 | 2021-04-01 18:47:14 +0200 | [diff] [blame] | 506 | END |
Bram Moolenaar | 5656496 | 2022-10-10 22:39:42 +0100 | [diff] [blame] | 507 | call writefile(lines, 'XTest_statusline', 'D') |
Bram Moolenaar | ce0b757 | 2021-04-01 18:47:14 +0200 | [diff] [blame] | 508 | |
Bram Moolenaar | d8db838 | 2021-04-08 18:27:53 +0200 | [diff] [blame] | 509 | let buf = RunVimInTerminal('-S XTest_statusline', {'rows': 7, 'cols': 50}) |
Bram Moolenaar | ce0b757 | 2021-04-01 18:47:14 +0200 | [diff] [blame] | 510 | call VerifyScreenDump(buf, 'Test_statusline_mode_1', {}) |
| 511 | |
| 512 | call term_sendkeys(buf, ":") |
| 513 | call VerifyScreenDump(buf, 'Test_statusline_mode_2', {}) |
| 514 | |
| 515 | " clean up |
Bram Moolenaar | d8db838 | 2021-04-08 18:27:53 +0200 | [diff] [blame] | 516 | call term_sendkeys(buf, "close\<CR>") |
Bram Moolenaar | ce0b757 | 2021-04-01 18:47:14 +0200 | [diff] [blame] | 517 | call StopVimInTerminal(buf) |
Bram Moolenaar | ce0b757 | 2021-04-01 18:47:14 +0200 | [diff] [blame] | 518 | endfunc |
| 519 | |
Bram Moolenaar | 668008b | 2020-10-01 19:06:35 +0200 | [diff] [blame] | 520 | func Test_statusline_after_split_vsplit() |
| 521 | only |
| 522 | |
| 523 | " Make the status line of each window show the window number. |
| 524 | set ls=2 stl=%{winnr()} |
| 525 | |
| 526 | split | redraw |
| 527 | vsplit | redraw |
| 528 | |
| 529 | " The status line of the third window should read '3' here. |
| 530 | call assert_equal('3', nr2char(screenchar(&lines - 1, 1))) |
| 531 | |
| 532 | only |
| 533 | set ls& stl& |
| 534 | endfunc |
| 535 | |
Bram Moolenaar | 008bff9 | 2021-03-04 21:55:58 +0100 | [diff] [blame] | 536 | " Test using a multibyte character for 'stl' and 'stlnc' items in 'fillchars' |
| 537 | " with a custom 'statusline' |
| 538 | func Test_statusline_mbyte_fillchar() |
| 539 | only |
Bram Moolenaar | 008bff9 | 2021-03-04 21:55:58 +0100 | [diff] [blame] | 540 | set fillchars=vert:\|,fold:-,stl:━,stlnc:═ |
| 541 | set statusline=a%=b |
| 542 | call assert_match('^a\+━\+b$', s:get_statusline()) |
| 543 | vnew |
| 544 | call assert_match('^a\+━\+b━a\+═\+b$', s:get_statusline()) |
| 545 | wincmd w |
| 546 | call assert_match('^a\+═\+b═a\+━\+b$', s:get_statusline()) |
zeertzjq | bb404f5 | 2022-07-23 06:25:29 +0100 | [diff] [blame] | 547 | set statusline& fillchars& |
Bram Moolenaar | 008bff9 | 2021-03-04 21:55:58 +0100 | [diff] [blame] | 548 | %bw! |
| 549 | endfunc |
Bram Moolenaar | 668008b | 2020-10-01 19:06:35 +0200 | [diff] [blame] | 550 | |
Bram Moolenaar | 826bfe4 | 2021-10-08 18:39:28 +0100 | [diff] [blame] | 551 | " Used to write beyond allocated memory. This assumes MAXPATHL is 4096 bytes. |
| 552 | func Test_statusline_verylong_filename() |
| 553 | let fname = repeat('x', 4090) |
| 554 | exe "new " .. fname |
| 555 | set buftype=help |
| 556 | set previewwindow |
| 557 | redraw |
| 558 | bwipe! |
| 559 | endfunc |
| 560 | |
LemonBoy | 57ff526 | 2022-05-09 21:03:47 +0100 | [diff] [blame] | 561 | func Test_statusline_highlight_truncate() |
| 562 | CheckScreendump |
| 563 | |
| 564 | let lines =<< trim END |
| 565 | set laststatus=2 |
| 566 | hi! link User1 Directory |
| 567 | hi! link User2 ErrorMsg |
| 568 | set statusline=%.5(%1*ABC%2*DEF%1*GHI%) |
| 569 | END |
Bram Moolenaar | 5656496 | 2022-10-10 22:39:42 +0100 | [diff] [blame] | 570 | call writefile(lines, 'XTest_statusline', 'D') |
LemonBoy | 57ff526 | 2022-05-09 21:03:47 +0100 | [diff] [blame] | 571 | |
| 572 | let buf = RunVimInTerminal('-S XTest_statusline', {'rows': 6}) |
| 573 | call VerifyScreenDump(buf, 'Test_statusline_hl', {}) |
| 574 | |
| 575 | call StopVimInTerminal(buf) |
LemonBoy | 57ff526 | 2022-05-09 21:03:47 +0100 | [diff] [blame] | 576 | endfunc |
| 577 | |
Luuk van Baal | ba936f6 | 2022-12-15 13:15:39 +0000 | [diff] [blame] | 578 | func Test_statusline_showcmd() |
| 579 | CheckScreendump |
| 580 | |
| 581 | let lines =<< trim END |
zeertzjq | 378e6c0 | 2023-01-14 11:46:49 +0000 | [diff] [blame] | 582 | func MyStatusLine() |
| 583 | return '%S' |
| 584 | endfunc |
| 585 | |
Luuk van Baal | ba936f6 | 2022-12-15 13:15:39 +0000 | [diff] [blame] | 586 | set laststatus=2 |
zeertzjq | 378e6c0 | 2023-01-14 11:46:49 +0000 | [diff] [blame] | 587 | set statusline=%!MyStatusLine() |
Luuk van Baal | ba936f6 | 2022-12-15 13:15:39 +0000 | [diff] [blame] | 588 | set showcmdloc=statusline |
| 589 | call setline(1, ['a', 'b', 'c']) |
zeertzjq | 378e6c0 | 2023-01-14 11:46:49 +0000 | [diff] [blame] | 590 | set foldopen+=jump |
| 591 | 1,2fold |
| 592 | 3 |
Luuk van Baal | ba936f6 | 2022-12-15 13:15:39 +0000 | [diff] [blame] | 593 | END |
| 594 | call writefile(lines, 'XTest_statusline', 'D') |
| 595 | |
| 596 | let buf = RunVimInTerminal('-S XTest_statusline', {'rows': 6}) |
zeertzjq | 378e6c0 | 2023-01-14 11:46:49 +0000 | [diff] [blame] | 597 | |
| 598 | call term_sendkeys(buf, "g") |
Luuk van Baal | ba936f6 | 2022-12-15 13:15:39 +0000 | [diff] [blame] | 599 | call VerifyScreenDump(buf, 'Test_statusline_showcmd_1', {}) |
| 600 | |
zeertzjq | 378e6c0 | 2023-01-14 11:46:49 +0000 | [diff] [blame] | 601 | " typing "gg" should open the fold |
| 602 | call term_sendkeys(buf, "g") |
Luuk van Baal | ba936f6 | 2022-12-15 13:15:39 +0000 | [diff] [blame] | 603 | call VerifyScreenDump(buf, 'Test_statusline_showcmd_2', {}) |
| 604 | |
zeertzjq | 378e6c0 | 2023-01-14 11:46:49 +0000 | [diff] [blame] | 605 | call term_sendkeys(buf, "\<C-V>Gl") |
Luuk van Baal | ba936f6 | 2022-12-15 13:15:39 +0000 | [diff] [blame] | 606 | call VerifyScreenDump(buf, 'Test_statusline_showcmd_3', {}) |
zeertzjq | 378e6c0 | 2023-01-14 11:46:49 +0000 | [diff] [blame] | 607 | |
| 608 | call term_sendkeys(buf, "\<Esc>1234") |
| 609 | call VerifyScreenDump(buf, 'Test_statusline_showcmd_4', {}) |
| 610 | |
| 611 | call term_sendkeys(buf, "\<Esc>:set statusline=\<CR>") |
| 612 | call term_sendkeys(buf, ":\<CR>") |
| 613 | call term_sendkeys(buf, "1234") |
| 614 | call VerifyScreenDump(buf, 'Test_statusline_showcmd_5', {}) |
| 615 | |
| 616 | call StopVimInTerminal(buf) |
Luuk van Baal | ba936f6 | 2022-12-15 13:15:39 +0000 | [diff] [blame] | 617 | endfunc |
| 618 | |
Christian Brabandt | 6a650bf | 2023-11-08 21:23:29 +0100 | [diff] [blame] | 619 | func Test_statusline_highlight_group_cleared() |
| 620 | CheckScreendump |
| 621 | |
| 622 | " the laststatus option is there to prevent |
| 623 | " the code-style test from complaining about |
| 624 | " trailing whitespace |
| 625 | let lines =<< trim END |
| 626 | set fillchars=stl:\ ,stlnc:\ laststatus=2 |
| 627 | split |
| 628 | hi clear StatusLine |
| 629 | hi clear StatusLineNC |
| 630 | END |
| 631 | call writefile(lines, 'XTest_statusline_stl', 'D') |
| 632 | |
| 633 | let buf = RunVimInTerminal('-S XTest_statusline_stl', {}) |
| 634 | |
| 635 | call VerifyScreenDump(buf, 'Test_statusline_stl_1', {}) |
| 636 | |
| 637 | call StopVimInTerminal(buf) |
| 638 | endfunc |
| 639 | |
Bram Moolenaar | 832adf9 | 2020-06-25 19:01:36 +0200 | [diff] [blame] | 640 | " vim: shiftwidth=2 sts=2 expandtab |