statuscolumn_spec.lua (58405B)
1 local t = require('test.testutil') 2 local n = require('test.functional.testnvim')() 3 local Screen = require('test.functional.ui.screen') 4 5 local clear = n.clear 6 local command = n.command 7 local eq = t.eq 8 local exec = n.exec 9 local eval = n.eval 10 local exec_lua = n.exec_lua 11 local feed = n.feed 12 local api = n.api 13 local pcall_err = t.pcall_err 14 local assert_alive = n.assert_alive 15 16 describe('statuscolumn', function() 17 local screen 18 before_each(function() 19 clear('--cmd', 'set number nuw=1 | call setline(1, repeat(["aaaaa"], 16)) | norm GM') 20 screen = Screen.new() 21 screen:add_extra_attr_ids { 22 [100] = { foreground = Screen.colors.Red, background = Screen.colors.LightGray }, 23 [101] = { background = Screen.colors.Gray90, bold = true }, 24 [102] = { foreground = Screen.colors.Brown, background = Screen.colors.Grey }, 25 [103] = { bold = true, background = Screen.colors.Grey, foreground = Screen.colors.Blue1 }, 26 [104] = { undercurl = true, special = Screen.colors.Red }, 27 [105] = { foreground = Screen.colors.Red, underline = true }, 28 [106] = { foreground = Screen.colors.Orange1 }, 29 [107] = { foreground = Screen.colors.LightBlue }, 30 } 31 exec_lua('ns = vim.api.nvim_create_namespace("")') 32 end) 33 34 it("fails with invalid 'statuscolumn'", function() 35 command( 36 [[set stc=%{v:relnum?v:relnum:(v:lnum==5?'truncate':v:lnum)}%{!v:relnum&&v:lnum==5?invalid:''}\ ]] 37 ) 38 screen:expect([[ 39 {8:4 }aaaaa | 40 {8:3 }aaaaa | 41 {8:2 }aaaaa | 42 {8:1 }aaaaa | 43 {8:8 }^aaaaa | 44 {8:1 }aaaaa | 45 {8:2 }aaaaa | 46 {8:3 }aaaaa | 47 {8:4 }aaaaa | 48 {8:5 }aaaaa | 49 {8:6 }aaaaa | 50 {8:7 }aaaaa | 51 {8:8 }aaaaa | 52 | 53 ]]) 54 command('norm 5G') 55 eq('Vim(redraw):E121: Undefined variable: invalid', pcall_err(command, 'redraw!')) 56 eq('', eval('&statuscolumn')) 57 screen:expect([[ 58 {8: 4 }aaaaa | 59 {8: 5 }^aaaaa | 60 {8: 6 }aaaaa | 61 {8: 7 }aaaaa | 62 {8: 8 }aaaaa | 63 {8: 9 }aaaaa | 64 {8:10 }aaaaa | 65 {8:11 }aaaaa | 66 {8:12 }aaaaa | 67 {8:13 }aaaaa | 68 {8:14 }aaaaa | 69 {8:15 }aaaaa | 70 {8:16 }aaaaa | 71 | 72 ]]) 73 end) 74 75 it("widens with irregular 'statuscolumn' width", function() 76 screen:try_resize(screen._width, 4) 77 command([=[ 78 set stc=%{v:relnum?v:relnum:(v:lnum==5?'bbbbb':v:lnum)} 79 let ns = nvim_create_namespace('') 80 call nvim_buf_set_extmark(0, ns, 3, 0, {'virt_text':[['virt_text']]}) 81 norm 5G | redraw! 82 ]=]) 83 screen:expect([[ 84 {8:1 }aaaaa virt_text | 85 {8:bbbbb}a^eaaa | 86 {8:1 }aaaaa | 87 | 88 ]]) 89 -- Doesn't crash when trying to fill click defs that do not fit (#26845) 90 command('norm gg') 91 command([=[ 92 set stc=%@Click@%{v:relnum?v:relnum:(v:lnum==5?'bbbbb':v:lnum)}%T 93 norm 5Gzt | redraw! 94 ]=]) 95 screen:expect([[ 96 {8:bbbbb}a^eaaa | 97 {8:1 }aaaaa | 98 {8:2 }aaaaa | 99 | 100 ]]) 101 -- Doesn't crash when clicking inside padded area without click_defs 102 command('set numberwidth=10') 103 api.nvim_input_mouse('left', 'press', '', 0, 0, 5) 104 assert_alive() 105 end) 106 107 it("works with 'number' and 'relativenumber'", function() 108 screen:expect([[ 109 {8: 4 }aaaaa | 110 {8: 5 }aaaaa | 111 {8: 6 }aaaaa | 112 {8: 7 }aaaaa | 113 {8: 8 }^aaaaa | 114 {8: 9 }aaaaa | 115 {8:10 }aaaaa | 116 {8:11 }aaaaa | 117 {8:12 }aaaaa | 118 {8:13 }aaaaa | 119 {8:14 }aaaaa | 120 {8:15 }aaaaa | 121 {8:16 }aaaaa | 122 | 123 ]]) 124 command([[set stc=%l\ ]]) 125 screen:expect_unchanged() 126 command('set relativenumber') 127 screen:expect([[ 128 {8: 4 }aaaaa | 129 {8: 3 }aaaaa | 130 {8: 2 }aaaaa | 131 {8: 1 }aaaaa | 132 {8:8 }^aaaaa | 133 {8: 1 }aaaaa | 134 {8: 2 }aaaaa | 135 {8: 3 }aaaaa | 136 {8: 4 }aaaaa | 137 {8: 5 }aaaaa | 138 {8: 6 }aaaaa | 139 {8: 7 }aaaaa | 140 {8: 8 }aaaaa | 141 | 142 ]]) 143 command('set stc=') 144 screen:expect_unchanged() 145 command([[set nonu stc=%l\ ]]) 146 screen:expect([[ 147 {8: 4 }aaaaa | 148 {8: 3 }aaaaa | 149 {8: 2 }aaaaa | 150 {8: 1 }aaaaa | 151 {8: 0 }^aaaaa | 152 {8: 1 }aaaaa | 153 {8: 2 }aaaaa | 154 {8: 3 }aaaaa | 155 {8: 4 }aaaaa | 156 {8: 5 }aaaaa | 157 {8: 6 }aaaaa | 158 {8: 7 }aaaaa | 159 {8: 8 }aaaaa | 160 | 161 ]]) 162 command('set nuw=1 stc=') 163 screen:expect_unchanged() 164 -- Correct alignment with items before and after number column 165 command([[set nu stc=foo\ %l\ bar]]) 166 screen:expect([[ 167 {8:foo 4 bar}aaaaa | 168 {8:foo 3 bar}aaaaa | 169 {8:foo 2 bar}aaaaa | 170 {8:foo 1 bar}aaaaa | 171 {8:foo 8 bar}^aaaaa | 172 {8:foo 1 bar}aaaaa | 173 {8:foo 2 bar}aaaaa | 174 {8:foo 3 bar}aaaaa | 175 {8:foo 4 bar}aaaaa | 176 {8:foo 5 bar}aaaaa | 177 {8:foo 6 bar}aaaaa | 178 {8:foo 7 bar}aaaaa | 179 {8:foo 8 bar}aaaaa | 180 | 181 ]]) 182 end) 183 184 it("works with highlighted 'statuscolumn'", function() 185 command( 186 [[set stc=%#NonText#%{&nu?v:lnum:''}]] 187 .. [[%=%{&rnu&&(v:lnum%2)?'\ '.v:relnum:''}]] 188 .. [[%#LineNr#%{&rnu&&!(v:lnum%2)?'\ '.v:relnum:''}│]] 189 ) 190 screen:expect([[ 191 {1:4 }{8:│}aaaaa | 192 {1:5 }{8:│}aaaaa | 193 {1:6 }{8:│}aaaaa | 194 {1:7 }{8:│}aaaaa | 195 {1:8 }{8:│}^aaaaa | 196 {1:9 }{8:│}aaaaa | 197 {1:10}{8:│}aaaaa | 198 {1:11}{8:│}aaaaa | 199 {1:12}{8:│}aaaaa | 200 {1:13}{8:│}aaaaa | 201 {1:14}{8:│}aaaaa | 202 {1:15}{8:│}aaaaa | 203 {1:16}{8:│}aaaaa | 204 | 205 ]]) 206 command('set relativenumber') 207 screen:expect([[ 208 {1:4 }{8: 4│}aaaaa | 209 {1:5 3}{8:│}aaaaa | 210 {1:6 }{8: 2│}aaaaa | 211 {1:7 1}{8:│}aaaaa | 212 {1:8 }{8: 0│}^aaaaa | 213 {1:9 1}{8:│}aaaaa | 214 {1:10 }{8: 2│}aaaaa | 215 {1:11 3}{8:│}aaaaa | 216 {1:12 }{8: 4│}aaaaa | 217 {1:13 5}{8:│}aaaaa | 218 {1:14 }{8: 6│}aaaaa | 219 {1:15 7}{8:│}aaaaa | 220 {1:16 }{8: 8│}aaaaa | 221 | 222 ]]) 223 command('set nonumber') 224 screen:expect([[ 225 {1: }{8:4│}aaaaa | 226 {1: 3}{8:│}aaaaa | 227 {1: }{8:2│}aaaaa | 228 {1: 1}{8:│}aaaaa | 229 {1: }{8:0│}^aaaaa | 230 {1: 1}{8:│}aaaaa | 231 {1: }{8:2│}aaaaa | 232 {1: 3}{8:│}aaaaa | 233 {1: }{8:4│}aaaaa | 234 {1: 5}{8:│}aaaaa | 235 {1: }{8:6│}aaaaa | 236 {1: 7}{8:│}aaaaa | 237 {1: }{8:8│}aaaaa | 238 | 239 ]]) 240 -- Last segment and fillchar are highlighted properly 241 command("set stc=%#Error#%{v:relnum?'Foo':'FooBar'}") 242 screen:expect([[ 243 {9:Foo }aaaaa |*4 244 {9:FooBar}^aaaaa | 245 {9:Foo }aaaaa |*8 246 | 247 ]]) 248 end) 249 250 it('works with wrapped lines, signs and folds', function() 251 command([[set cursorline stc=%C%s%=%{v:virtnum?'':v:lnum}│\ ]]) 252 command("call setline(1,repeat([repeat('aaaaa',10)],16))") 253 command('hi! CursorLine gui=bold') 254 command('sign define num1 numhl=Special') 255 command('sign place 1 line=8 name=num1 buffer=1') 256 screen:expect([[ 257 {8: 4│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 258 {8: │ }a | 259 {8: 5│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 260 {8: │ }a | 261 {8: 6│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 262 {8: │ }a | 263 {8: 7│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 264 {8: │ }a | 265 {29: 8│ }{101:^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 266 {29: │ }{101:a }| 267 {8: 9│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 268 {8: │ }a | 269 {8:10│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa{1:@@@}| 270 | 271 ]]) 272 command([[set stc=%C%s%=%l│\ ]]) 273 screen:expect_unchanged() 274 command('hi! CursorLine guifg=Red guibg=NONE gui=NONE') 275 command('set nocursorline signcolumn=auto:2 foldcolumn=auto') 276 command('sign define piet1 text=>> texthl=LineNr') 277 command('sign define piet2 text=>! texthl=NonText') 278 command('sign place 1 line=4 name=piet1 buffer=1') 279 command('sign place 2 line=5 name=piet2 buffer=1') 280 command('sign place 3 line=6 name=piet1 buffer=1') 281 command('sign place 4 line=6 name=piet2 buffer=1') 282 screen:expect([[ 283 {102:>>}{7: }{8: 4│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 284 {7: }{8: │ }aaaaa | 285 {103:>!}{7: }{8: 5│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 286 {7: }{8: │ }aaaaa | 287 {103:>!}{102:>>}{8: 6│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 288 {7: }{8: │ }aaaaa | 289 {7: }{8: 7│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 290 {7: }{8: │ }aaaaa | 291 {7: }{8: 8│ }^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 292 {7: }{8: │ }aaaaa | 293 {7: }{8: 9│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 294 {7: }{8: │ }aaaaa | 295 {7: }{8:10│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa{1:@@@}| 296 | 297 ]]) 298 command('norm zf$') 299 -- Check that alignment works properly with signs after %= 300 command([[set stc=%C%=%{v:virtnum?'':v:lnum}│%s\ ]]) 301 screen:expect([[ 302 {7: }{8: 4│}{102:>>}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 303 {7: }{8: │}{7: }{8: }aaaaaa | 304 {7: }{8: 5│}{103:>!}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 305 {7: }{8: │}{7: }{8: }aaaaaa | 306 {7: }{8: 6│}{103:>!}{102:>>}{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 307 {7: }{8: │}{7: }{8: }aaaaaa | 308 {7: }{8: 7│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 309 {7: }{8: │}{7: }{8: }aaaaaa | 310 {7:+}{8: 8│}{7: }{8: }{13:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 311 {7: }{8: 9│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 312 {7: }{8: │}{7: }{8: }aaaaaa | 313 {7: }{8:10│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 314 {7: }{8: │}{7: }{8: }aaaaaa | 315 | 316 ]]) 317 command('set cursorline') 318 screen:expect([[ 319 {7: }{8: 4│}{102:>>}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 320 {7: }{8: │}{7: }{8: }aaaaaa | 321 {7: }{8: 5│}{103:>!}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 322 {7: }{8: │}{7: }{8: }aaaaaa | 323 {7: }{8: 6│}{103:>!}{102:>>}{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 324 {7: }{8: │}{7: }{8: }aaaaaa | 325 {7: }{8: 7│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 326 {7: }{8: │}{7: }{8: }aaaaaa | 327 {7:+}{15: 8│}{7: }{15: }{100:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 328 {7: }{8: 9│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 329 {7: }{8: │}{7: }{8: }aaaaaa | 330 {7: }{8:10│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 331 {7: }{8: │}{7: }{8: }aaaaaa | 332 | 333 ]]) 334 -- v:lnum is the same value on wrapped lines 335 command([[set stc=%C%=%{v:lnum}│%s\ ]]) 336 screen:expect([[ 337 {7: }{8: 4│}{102:>>}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 338 {7: }{8: 4│}{7: }{8: }aaaaaa | 339 {7: }{8: 5│}{103:>!}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 340 {7: }{8: 5│}{7: }{8: }aaaaaa | 341 {7: }{8: 6│}{103:>!}{102:>>}{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 342 {7: }{8: 6│}{7: }{8: }aaaaaa | 343 {7: }{8: 7│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 344 {7: }{8: 7│}{7: }{8: }aaaaaa | 345 {7:+}{15: 8│}{7: }{15: }{100:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 346 {7: }{8: 9│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 347 {7: }{8: 9│}{7: }{8: }aaaaaa | 348 {7: }{8:10│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 349 {7: }{8:10│}{7: }{8: }aaaaaa | 350 | 351 ]]) 352 -- v:relnum is the same value on wrapped lines 353 command([[set stc=%C%=\ %{v:relnum}│%s\ ]]) 354 screen:expect([[ 355 {7: }{8: 4│}{102:>>}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 356 {7: }{8: 4│}{7: }{8: }aaaaaaa | 357 {7: }{8: 3│}{103:>!}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 358 {7: }{8: 3│}{7: }{8: }aaaaaaa | 359 {7: }{8: 2│}{103:>!}{102:>>}{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 360 {7: }{8: 2│}{7: }{8: }aaaaaaa | 361 {7: }{8: 1│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 362 {7: }{8: 1│}{7: }{8: }aaaaaaa | 363 {7:+}{15: 0│}{7: }{15: }{100:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 364 {7: }{8: 1│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 365 {7: }{8: 1│}{7: }{8: }aaaaaaa | 366 {7: }{8: 2│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 367 {7: }{8: 2│}{7: }{8: }aaaaaaa | 368 | 369 ]]) 370 command([[set stc=%C%=\ %{v:virtnum?'':v:relnum}│%s\ ]]) 371 screen:expect([[ 372 {7: }{8: 4│}{102:>>}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 373 {7: }{8: │}{7: }{8: }aaaaaaa | 374 {7: }{8: 3│}{103:>!}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 375 {7: }{8: │}{7: }{8: }aaaaaaa | 376 {7: }{8: 2│}{103:>!}{102:>>}{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 377 {7: }{8: │}{7: }{8: }aaaaaaa | 378 {7: }{8: 1│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 379 {7: }{8: │}{7: }{8: }aaaaaaa | 380 {7:+}{15: 0│}{7: }{15: }{100:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 381 {7: }{8: 1│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 382 {7: }{8: │}{7: }{8: }aaaaaaa | 383 {7: }{8: 2│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 384 {7: }{8: │}{7: }{8: }aaaaaaa | 385 | 386 ]]) 387 -- Up to 9 signs in a line 388 command('set signcolumn=auto:9 foldcolumn=auto') 389 command('sign place 5 line=6 name=piet1 buffer=1') 390 command('sign place 6 line=6 name=piet2 buffer=1') 391 command('sign place 7 line=6 name=piet1 buffer=1') 392 command('sign place 8 line=6 name=piet2 buffer=1') 393 command('sign place 9 line=6 name=piet1 buffer=1') 394 command('sign place 10 line=6 name=piet2 buffer=1') 395 command('sign place 11 line=6 name=piet1 buffer=1') 396 screen:expect([[ 397 {7: }{8: 4│}{102:>>}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 398 {7: }{8: │}{7: }{8: }aaaaaaaaaaaaaaaaaaaaa | 399 {7: }{8: 3│}{103:>!}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 400 {7: }{8: │}{7: }{8: }aaaaaaaaaaaaaaaaaaaaa | 401 {7: }{8: 2│}{102:>>}{103:>!}{102:>>}{103:>!}{102:>>}{103:>!}{102:>>}{103:>!}{102:>>}{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 402 {7: }{8: │}{7: }{8: }aaaaaaaaaaaaaaaaaaaaa | 403 {7: }{8: 1│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 404 {7: }{8: │}{7: }{8: }aaaaaaaaaaaaaaaaaaaaa | 405 {7:+}{15: 0│}{7: }{15: }{100:^+-- 1 line: aaaaaaaaaaaaaaaa}| 406 {7: }{8: 1│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 407 {7: }{8: │}{7: }{8: }aaaaaaaaaaaaaaaaaaaaa | 408 {7: }{8: 2│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 409 {7: }{8: │}{7: }{8: }aaaaaaaaaaaaaaaaaaaaa | 410 | 411 ]]) 412 -- Also test fold and sign column when 'cpoptions' includes "n" 413 command('set cpoptions+=n') 414 feed('Hgjg0') 415 screen:expect([[ 416 {7: }{15: 0│}{102:>>}{7: }{15: }{19:aaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 417 {7: }{19:^aaaaaaaaaaaaaaaaaaaaa }| 418 {7: }{8: 3│}{103:>!}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 419 {7: }aaaaaaaaaaaaaaaaaaaaa | 420 {7: }{8: 2│}{102:>>}{103:>!}{102:>>}{103:>!}{102:>>}{103:>!}{102:>>}{103:>!}{102:>>}{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 421 {7: }aaaaaaaaaaaaaaaaaaaaa | 422 {7: }{8: 1│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 423 {7: }aaaaaaaaaaaaaaaaaaaaa | 424 {7:+}{8: 4│}{7: }{8: }{13:+-- 1 line: aaaaaaaaaaaaaaaa}| 425 {7: }{8: 1│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 426 {7: }aaaaaaaaaaaaaaaaaaaaa | 427 {7: }{8: 2│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 428 {7: }aaaaaaaaaaaaaaaaaaaaa | 429 | 430 ]]) 431 command('set breakindent') 432 command('sign unplace 2') 433 feed('J2gjg0') 434 screen:expect([[ 435 {7: }{15: 0│}{102:>>}{7: }{15: }{19:aaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 436 {7: } {19:aaaaaaaaaaaaaaaaaaaaa aaaaaaa}| 437 {7: } {19:aaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 438 {7: } {19:^aaaaaaaaaaaaaa }| 439 {7: }{8: 1│}{102:>>}{103:>!}{102:>>}{103:>!}{102:>>}{103:>!}{102:>>}{103:>!}{102:>>}{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 440 {7: } aaaaaaaaaaaaaaaaaaaaa | 441 {7: }{8: 2│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 442 {7: } aaaaaaaaaaaaaaaaaaaaa | 443 {7:+}{8: 3│}{7: }{8: }{13:+-- 1 line: aaaaaaaaaaaaaaaa}| 444 {7: }{8: 4│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 445 {7: } aaaaaaaaaaaaaaaaaaaaa | 446 {7: }{8: 5│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 447 {7: } aaaaaaaaaaaaaaaaaaaaa | 448 | 449 ]]) 450 command('set nobreakindent') 451 feed('$g0') 452 screen:expect([[ 453 {7: }{15: 0│}{102:>>}{7: }{15: }{19:aaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 454 {7: }{19:aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaa}| 455 {7: }{19:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 456 {7: }{19:^aaaa }| 457 {7: }{8: 1│}{102:>>}{103:>!}{102:>>}{103:>!}{102:>>}{103:>!}{102:>>}{103:>!}{102:>>}{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 458 {7: }aaaaaaaaaaaaaaaaaaaaa | 459 {7: }{8: 2│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 460 {7: }aaaaaaaaaaaaaaaaaaaaa | 461 {7:+}{8: 3│}{7: }{8: }{13:+-- 1 line: aaaaaaaaaaaaaaaa}| 462 {7: }{8: 4│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 463 {7: }aaaaaaaaaaaaaaaaaaaaa | 464 {7: }{8: 5│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 465 {7: }aaaaaaaaaaaaaaaaaaaaa | 466 | 467 ]]) 468 command('silent undo') 469 feed('8gg') 470 command('set cpoptions-=n') 471 -- Status column is re-evaluated for virt_lines, buffer line, and wrapped line 472 exec_lua([[ 473 vim.api.nvim_buf_set_extmark(0, ns, 5, 0, { 474 virt_lines_above = true, virt_lines = {{{"virt_line above", ""}}} }) 475 vim.api.nvim_buf_set_extmark(0, ns, 4, 0, { virt_lines = {{{"virt_line", ""}}} }) 476 ]]) 477 command('set foldcolumn=0 signcolumn=number stc=%l') 478 screen:expect([[ 479 {102:>>}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 480 {8: 5}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 481 {8: }virt_line | 482 {8: }virt_line above | 483 {102:>>}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 484 {8: 7}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 485 {15: 8}{100:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 486 {8: 9}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 487 {8:10}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 488 {8:11}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 489 {8:12}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 490 {8:13}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 491 {8:14}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 492 | 493 ]]) 494 command( 495 [[set stc=%{v:virtnum<0?'virtual':(!v:virtnum?'buffer':'wrapped')}%=%{'\ '.v:virtnum.'\ '.v:lnum}]] 496 ) 497 screen:expect([[ 498 {8:buffer 0 4}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 499 {8:wrapped 1 4}aaaaaaaa | 500 {8:buffer 0 5}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 501 {8:wrapped 1 5}aaaaaaaa | 502 {8:virtual-2 5}virt_line | 503 {8:virtual-1 6}virt_line above | 504 {8:buffer 0 6}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 505 {8:wrapped 1 6}aaaaaaaa | 506 {8:buffer 0 7}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 507 {8:wrapped 1 7}aaaaaaaa | 508 {15:buffer 0 8}{100:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 509 {8:buffer 0 9}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 510 {8:wrapped 1 9}aaaaaaaa | 511 | 512 ]]) 513 -- Also correct v:lnum with a partial redraw 514 exec_lua('vim.api.nvim_buf_set_extmark(0, ns, 4, 0, { virt_lines = {{{"virt_line", ""}}} })') 515 screen:expect([[ 516 {8:buffer 0 4}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 517 {8:wrapped 1 4}aaaaaaaa | 518 {8:buffer 0 5}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 519 {8:wrapped 1 5}aaaaaaaa | 520 {8:virtual-3 5}virt_line | 521 {8:virtual-2 5}virt_line | 522 {8:virtual-1 6}virt_line above | 523 {8:buffer 0 6}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 524 {8:wrapped 1 6}aaaaaaaa | 525 {8:buffer 0 7}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 526 {8:wrapped 1 7}aaaaaaaa | 527 {15:buffer 0 8}{100:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 528 {8:buffer 0 9}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa{1:@@@}| 529 | 530 ]]) 531 -- Also test virt_lines at the end of buffer 532 exec_lua('vim.api.nvim_buf_set_extmark(0, ns, 15, 0, { virt_lines = {{{"END", ""}}} })') 533 feed('GkJzz') 534 screen:expect([[ 535 {8:buffer 0 12}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 536 {8:wrapped 1 12}aaaaaaaaa | 537 {8:buffer 0 13}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 538 {8:wrapped 1 13}aaaaaaaaa | 539 {8:buffer 0 14}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 540 {8:wrapped 1 14}aaaaaaaaa | 541 {15:buffer 0 15}{19:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 542 {15:wrapped 1 15}{19:aaaaaaaaa^ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 543 {15:wrapped 2 15}{19:aaaaaaaaaaaaaaaaaaa }| 544 {8:virtual-1 15}END | 545 {1:~ }|*3 546 | 547 ]]) 548 -- Also test virt_lines when 'cpoptions' includes "n" 549 exec_lua([[ 550 vim.opt.cpoptions:append("n") 551 vim.api.nvim_buf_set_extmark(0, ns, 14, 0, { virt_lines = {{{"virt_line1", ""}}} }) 552 vim.api.nvim_buf_set_extmark(0, ns, 14, 0, { virt_lines = {{{"virt_line2", ""}}} }) 553 ]]) 554 screen:expect([[ 555 {8:buffer 0 12}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 556 aaaaaaaaa | 557 {8:buffer 0 13}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 558 aaaaaaaaa | 559 {8:buffer 0 14}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 560 aaaaaaaaa | 561 {15:buffer 0 15}{19:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 562 {19:aaaaaaaaa^ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| 563 {19:aaaaaaa }| 564 {8:virtual-3 15}virt_line1 | 565 {8:virtual-2 15}virt_line2 | 566 {8:virtual-1 15}END | 567 {1:~ }| 568 | 569 ]]) 570 -- Also test "col_rows" code path for 'relativenumber' cursor movement 571 command([[ 572 set cpoptions-=n nocursorline relativenumber 573 set stc=%{v:virtnum<0?'virtual':(!v:virtnum?'buffer':'wrapped')}%=%{'\ '.v:virtnum.'\ '.v:lnum.'\ '.v:relnum} 574 ]]) 575 screen:expect([[ 576 {8:buffer 0 12 3}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 577 {8:wrapped 1 12 3}aaaaaaaaaaa | 578 {8:buffer 0 13 2}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 579 {8:wrapped 1 13 2}aaaaaaaaaaa | 580 {8:buffer 0 14 1}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 581 {8:wrapped 1 14 1}aaaaaaaaaaa | 582 {8:buffer 0 15 0}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 583 {8:wrapped 1 15 0}aaaaaaaaaaa^ aaaaaaaaaaaaaaaaaaaaaaaaaaa| 584 {8:wrapped 2 15 0}aaaaaaaaaaaaaaaaaaaaaaa | 585 {8:virtual-3 15 0}virt_line1 | 586 {8:virtual-2 15 0}virt_line2 | 587 {8:virtual-1 15 0}END | 588 {1:~ }| 589 | 590 ]]) 591 feed('kk') 592 screen:expect([[ 593 {8:buffer 0 12 1}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 594 {8:wrapped 1 12 1}aaaaaaaaaaa | 595 {8:buffer 0 13 0}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 596 {8:wrapped 1 13 0}aaaaaaaaaa^a | 597 {8:buffer 0 14 1}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 598 {8:wrapped 1 14 1}aaaaaaaaaaa | 599 {8:buffer 0 15 2}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 600 {8:wrapped 1 15 2}aaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaa| 601 {8:wrapped 2 15 2}aaaaaaaaaaaaaaaaaaaaaaa | 602 {8:virtual-3 15 2}virt_line1 | 603 {8:virtual-2 15 2}virt_line2 | 604 {8:virtual-1 15 2}END | 605 {1:~ }| 606 | 607 ]]) 608 end) 609 610 it('does not corrupt the screen with minwid sign item', function() 611 screen:try_resize(screen._width, 3) 612 command([[set stc=%6s\ %l]]) 613 exec_lua('vim.api.nvim_buf_set_extmark(0, ns, 7, 0, {sign_text = "𒀀"})') 614 screen:expect([[ 615 {8: }{7:𒀀 }{8: 8}^aaaaa | 616 {8: }{7: }{8: 9}aaaaa | 617 | 618 ]]) 619 end) 620 621 for _, model in ipairs({ 'extend', 'popup', 'popup_setpos' }) do 622 describe('with mousemodel=' .. model, function() 623 before_each(function() 624 command('set mousemodel=' .. model) 625 exec([[ 626 function! MyClickFunc(minwid, clicks, button, mods) 627 let g:testvar = printf("%d %d %s %d", a:minwid, a:clicks, a:button, getmousepos().line) 628 if a:mods !=# ' ' 629 let g:testvar ..= '(' .. a:mods .. ')' 630 endif 631 endfunction 632 let g:testvar = '' 633 ]]) 634 end) 635 636 it('clicks work with mousemodel=' .. model, function() 637 api.nvim_set_option_value('statuscolumn', '%0@MyClickFunc@%=%l%T', {}) 638 api.nvim_input_mouse('left', 'press', '', 0, 0, 0) 639 eq('0 1 l 4', eval('g:testvar')) 640 api.nvim_input_mouse('left', 'press', '', 0, 0, 0) 641 eq('0 2 l 4', eval('g:testvar')) 642 api.nvim_input_mouse('left', 'press', '', 0, 0, 0) 643 eq('0 3 l 4', eval('g:testvar')) 644 api.nvim_input_mouse('left', 'press', '', 0, 0, 0) 645 eq('0 4 l 4', eval('g:testvar')) 646 api.nvim_input_mouse('right', 'press', '', 0, 3, 0) 647 eq('0 1 r 7', eval('g:testvar')) 648 api.nvim_input_mouse('right', 'press', '', 0, 3, 0) 649 eq('0 2 r 7', eval('g:testvar')) 650 api.nvim_input_mouse('right', 'press', '', 0, 3, 0) 651 eq('0 3 r 7', eval('g:testvar')) 652 api.nvim_input_mouse('right', 'press', '', 0, 3, 0) 653 eq('0 4 r 7', eval('g:testvar')) 654 655 command('rightbelow vsplit') 656 api.nvim_input_mouse('left', 'press', '', 0, 0, 27) 657 eq('0 1 l 4', eval('g:testvar')) 658 api.nvim_input_mouse('right', 'press', '', 0, 3, 27) 659 eq('0 1 r 7', eval('g:testvar')) 660 command('setlocal rightleft') 661 api.nvim_input_mouse('left', 'press', '', 0, 0, 52) 662 eq('0 1 l 4', eval('g:testvar')) 663 api.nvim_input_mouse('right', 'press', '', 0, 3, 52) 664 eq('0 1 r 7', eval('g:testvar')) 665 command('wincmd H') 666 api.nvim_input_mouse('left', 'press', '', 0, 0, 25) 667 eq('0 1 l 4', eval('g:testvar')) 668 api.nvim_input_mouse('right', 'press', '', 0, 3, 25) 669 eq('0 1 r 7', eval('g:testvar')) 670 command('close') 671 672 command('set laststatus=2 winbar=%f') 673 command('let g:testvar = ""') 674 -- Check that winbar click doesn't register as statuscolumn click 675 api.nvim_input_mouse('right', 'press', '', 0, 0, 0) 676 eq('', eval('g:testvar')) 677 -- Check that statusline click doesn't register as statuscolumn click 678 api.nvim_input_mouse('right', 'press', '', 0, 12, 0) 679 eq('', eval('g:testvar')) 680 -- Check that rightclick still opens popupmenu if there is no clickdef 681 if model == 'popup' then 682 api.nvim_set_option_value('statuscolumn', '%0@MyClickFunc@%=%l%TNoClick', {}) 683 api.nvim_input_mouse('right', 'press', '', 0, 1, 0) 684 screen:expect([[ 685 {5:[No Name] }| 686 {8: 4NoClick}^aaaaa | 687 {8: 5NoClick}aaaaa | 688 {8: 6NoClick}aaaaa | 689 {8: 7NoClick}aaaaa | 690 {8: 8NoClick}aaaaa | 691 {8: 9NoClick}aaaaa | 692 {8:10NoClick}aaaaa | 693 {8:11NoClick}aaaaa | 694 {8:12NoClick}aaaaa | 695 {8:13NoClick}aaaaa | 696 {8:14NoClick}aaaaa | 697 {3:[No Name] [+] }| 698 | 699 ]]) 700 api.nvim_input_mouse('right', 'press', '', 0, 1, 3) 701 screen:expect([[ 702 {5:[No Name] }| 703 {8: 4NoClick}^aaaaa | 704 {8: 5}{4: Inspect } | 705 {8: 6}{4: } | 706 {8: 7}{4: Paste } | 707 {8: 8}{4: Select All } | 708 {8: 9}{4: } | 709 {8:10}{4: How-to disable mouse } | 710 {8:11NoClick}aaaaa | 711 {8:12NoClick}aaaaa | 712 {8:13NoClick}aaaaa | 713 {8:14NoClick}aaaaa | 714 {3:[No Name] [+] }| 715 | 716 ]]) 717 end 718 end) 719 720 it('clicks and highlights work with control characters', function() 721 api.nvim_set_option_value('statuscolumn', '\t%#NonText#\1%0@MyClickFunc@\t\1%T\t%##\1', {}) 722 screen:expect([[ 723 {8:^I}{1:^A^I^A^I}{8:^A}aaaaa |*4 724 {8:^I}{1:^A^I^A^I}{8:^A}^aaaaa | 725 {8:^I}{1:^A^I^A^I}{8:^A}aaaaa |*8 726 | 727 ]]) 728 api.nvim_input_mouse('right', 'press', '', 0, 4, 3) 729 feed('<Esc>') -- Close popupmenu 730 eq('', eval('g:testvar')) 731 api.nvim_input_mouse('left', 'press', '', 0, 5, 8) 732 eq('', eval('g:testvar')) 733 api.nvim_input_mouse('right', 'press', '', 0, 6, 4) 734 -- Wait for the synchronous call of `textDocument/documentLink` 735 t.retry(nil, 1500, function() 736 eq('0 1 r 10', eval('g:testvar')) 737 end) 738 api.nvim_input_mouse('left', 'press', '', 0, 7, 7) 739 eq('0 1 l 11', eval('g:testvar')) 740 end) 741 742 it('popupmenu callback does not drag mouse on close', function() 743 screen:try_resize(screen._width, 2) 744 api.nvim_set_option_value('statuscolumn', '%0@MyClickFunc@%l%T', {}) 745 exec([[ 746 function! MyClickFunc(minwid, clicks, button, mods) 747 let g:testvar = printf("%d %d %s %d", a:minwid, a:clicks, a:button, getmousepos().line) 748 menu PopupStc.Echo <cmd>echo g:testvar<CR> 749 popup PopupStc 750 endfunction 751 ]]) 752 -- clicking an item does not drag mouse 753 api.nvim_input_mouse('left', 'press', '', 0, 0, 0) 754 screen:expect([[ 755 {8: 8}^aaaaa | 756 {4: Echo } | 757 ]]) 758 api.nvim_input_mouse('left', 'press', '', 0, 1, 5) 759 api.nvim_input_mouse('left', 'release', '', 0, 1, 5) 760 screen:expect([[ 761 {8: 8}^aaaaa | 762 0 1 l 8 | 763 ]]) 764 command('echo') 765 -- clicking outside to close the menu does not drag mouse 766 api.nvim_input_mouse('left', 'press', '', 0, 0, 0) 767 screen:expect([[ 768 {8: 8}^aaaaa | 769 {4: Echo } | 770 ]]) 771 api.nvim_input_mouse('left', 'press', '', 0, 0, 10) 772 api.nvim_input_mouse('left', 'release', '', 0, 0, 10) 773 screen:expect([[ 774 {8: 8}^aaaaa | 775 | 776 ]]) 777 end) 778 779 it('foldcolumn item can be clicked', function() 780 api.nvim_set_option_value('statuscolumn', '|%C|', {}) 781 api.nvim_set_option_value('foldcolumn', '2', {}) 782 api.nvim_set_option_value('mousetime', 0, {}) 783 feed('ggzfjzfjzo') 784 local s1 = [[ 785 {8:|}{7:-+}{8:|}{13:^+--- 2 lines: aaaaa·····························}| 786 {8:|}{7:│ }{8:|}aaaaa | 787 {8:|}{7: }{8:|}aaaaa |*11 788 | 789 ]] 790 screen:expect(s1) 791 api.nvim_input_mouse('left', 'press', '', 0, 0, 2) 792 screen:expect([[ 793 {8:|}{7:--}{8:|}^aaaaa | 794 {8:|}{7:││}{8:|}aaaaa | 795 {8:|}{7:│ }{8:|}aaaaa | 796 {8:|}{7: }{8:|}aaaaa |*10 797 | 798 ]]) 799 api.nvim_input_mouse('left', 'press', '', 0, 0, 1) 800 screen:expect(s1) 801 api.nvim_input_mouse('left', 'press', '', 0, 0, 1) 802 screen:expect([[ 803 {8:|}{7:+ }{8:|}{13:^+-- 3 lines: aaaaa······························}| 804 {8:|}{7: }{8:|}aaaaa |*12 805 | 806 ]]) 807 end) 808 end) 809 end 810 811 it('click labels do not leak memory #21878', function() 812 exec([[ 813 set laststatus=2 814 setlocal statuscolumn=%0@MyClickFunc@abcd%T 815 4vsplit 816 setlocal statusline=abcd 817 redrawstatus 818 setlocal statusline= 819 only 820 redraw 821 ]]) 822 end) 823 824 it('click labels do not crash when initial width is 0 #24428', function() 825 exec([[ 826 set nonumber 827 bwipe! 828 setlocal statuscolumn=abcd 829 redraw 830 setlocal statuscolumn=%0@MyClickFunc@abcd%T 831 redraw 832 ]]) 833 assert_alive() 834 end) 835 836 it('works with foldcolumn', function() 837 -- Fits maximum multibyte foldcolumn #21759 838 command([[set stc=%C%=%l\ fdc=9 fillchars=foldsep:𒀀]]) 839 for _ = 0, 8 do 840 command('norm zfjzo') 841 end 842 -- 'statuscolumn' is not drawn for `virt_lines_leftcol` lines 843 exec_lua([[ 844 vim.api.nvim_buf_set_extmark(0, ns, 6, 0, { 845 virt_lines_leftcol = true, virt_lines = {{{"virt", ""}}} }) 846 vim.api.nvim_buf_set_extmark(0, ns, 7, 0, { 847 virt_lines_leftcol = true, virt_lines = {{{"virt", ""}}} }) 848 ]]) 849 screen:expect([[ 850 {7: }{8: 4 }aaaaa | 851 {7: }{8: 5 }aaaaa | 852 {7: }{8: 6 }aaaaa | 853 {7: }{8: 7 }aaaaa | 854 virt | 855 {7:---------}{8: 8 }^aaaaa | 856 virt | 857 {7:𒀀𒀀𒀀𒀀𒀀𒀀𒀀𒀀𒀀}{8: 9 }aaaaa | 858 {7: }{8:10 }aaaaa | 859 {7: }{8:11 }aaaaa | 860 {7: }{8:12 }aaaaa | 861 {7: }{8:13 }aaaaa | 862 {7: }{8:14 }aaaaa | 863 | 864 ]]) 865 command('set stc=') -- also for the default fold column 866 screen:expect_unchanged() 867 -- 'statuscolumn' is not too wide with custom (bogus) fold column 868 command([[set stc=%{foldlevel(v:lnum)>0?repeat('-',foldlevel(v:lnum)):''}%=%l\ ]]) 869 feed('Gd10Ggg<C-l>') 870 screen:expect([[ 871 {8: 1 }^aaaaa | 872 {8: 2 }aaaaa | 873 {8: 3 }aaaaa | 874 {8: 4 }aaaaa | 875 {8: 5 }aaaaa | 876 {8: 6 }aaaaa | 877 {8: 7 }aaaaa | 878 virt | 879 {8:---------8 }aaaaa | 880 virt | 881 {8:---------9 }aaaaa | 882 {1:~ }|*2 883 | 884 ]]) 885 end) 886 887 it('works with cmdwin', function() 888 feed(':set stc=%l<CR>q:k$') 889 screen:expect([[ 890 {8: 7}aaaaa | 891 {8: 8}aaaaa | 892 {8: 9}aaaaa | 893 {8:10}aaaaa | 894 {2:[No Name] [+] }| 895 {1::}{8:1}set stc=%^l | 896 {1::}{8:2} | 897 {1:~ }|*5 898 {3:[Command Line] }| 899 : | 900 ]]) 901 end) 902 903 it("has correct width when toggling '(relative)number'", function() 904 screen:try_resize(screen._width, 6) 905 command('call setline(1, repeat(["aaaaa"], 100))') 906 command('set relativenumber') 907 command([[set stc=%{!&nu&&!&rnu?'':&rnu?v:relnum?v:relnum:&nu?v:lnum:'0':v:lnum}]]) 908 screen:expect([[ 909 {8:1 }aaaaa | 910 {8:8 }^aaaaa | 911 {8:1 }aaaaa | 912 {8:2 }aaaaa | 913 {8:3 }aaaaa | 914 | 915 ]]) 916 -- width correctly estimated with "w_nrwidth_line_count" when setting 'stc' 917 command([[set stc=%{!&nu&&!&rnu?'':&rnu?v:relnum?v:relnum:&nu?v:lnum:'0':v:lnum}]]) 918 screen:expect_unchanged() 919 -- zero width when disabling 'number' 920 command('set norelativenumber nonumber') 921 screen:expect([[ 922 aaaaa | 923 ^aaaaa | 924 aaaaa |*3 925 | 926 ]]) 927 -- width correctly estimated with "w_nrwidth_line_count" when setting 'nu' 928 command('set number') 929 screen:expect([[ 930 {8:7 }aaaaa | 931 {8:8 }^aaaaa | 932 {8:9 }aaaaa | 933 {8:10 }aaaaa | 934 {8:11 }aaaaa | 935 | 936 ]]) 937 end) 938 939 it('has correct width with custom sign column when (un)placing signs', function() 940 screen:try_resize(screen._width, 3) 941 exec_lua([[ 942 vim.cmd.norm('gg') 943 vim.o.signcolumn = 'no' 944 vim.fn.sign_define('sign', { text = 'ss' }) 945 _G.StatusCol = function() 946 local s = vim.fn.sign_getplaced(1)[1].signs 947 local es = vim.api.nvim_buf_get_extmarks(0, ns, 0, -1, {type = "sign"}) 948 local sign = '' 949 local signs = #s + #es 950 if signs > 0 then 951 sign = (vim.v.lnum == 2 and 'ss' or ' '):rep(signs) 952 end 953 return vim.v.lnum .. '%=' .. sign 954 end 955 vim.o.number = true 956 vim.o.numberwidth = 2 957 vim.o.statuscolumn = "%!v:lua.StatusCol()" 958 ]]) 959 command('sign place 1 line=2 name=sign') 960 screen:expect([[ 961 {8:1 }^aaaaa | 962 {8:2 ss}aaaaa | 963 | 964 ]]) 965 command('sign place 2 line=2 name=sign') 966 screen:expect([[ 967 {8:1 }^aaaaa | 968 {8:2 ssss}aaaaa | 969 | 970 ]]) 971 command('sign unplace 2') 972 screen:expect([[ 973 {8:1 }^aaaaa | 974 {8:2 ss}aaaaa | 975 | 976 ]]) 977 command('sign unplace 1') 978 screen:expect([[ 979 {8:1 }^aaaaa | 980 {8:2 }aaaaa | 981 | 982 ]]) 983 -- Also for extmark signs 984 exec_lua('id1 = vim.api.nvim_buf_set_extmark(0, ns, 1, 0, {sign_text = "ss"})') 985 screen:expect([[ 986 {8:1 }^aaaaa | 987 {8:2 ss}aaaaa | 988 | 989 ]]) 990 exec_lua('id2 = vim.api.nvim_buf_set_extmark(0, ns, 1, 0, {sign_text = "ss"})') 991 screen:expect([[ 992 {8:1 }^aaaaa | 993 {8:2 ssss}aaaaa | 994 | 995 ]]) 996 exec_lua('vim.api.nvim_buf_del_extmark(0, ns, id1)') 997 screen:expect([[ 998 {8:1 }^aaaaa | 999 {8:2 ss}aaaaa | 1000 | 1001 ]]) 1002 exec_lua('vim.api.nvim_buf_del_extmark(0, ns, id2)') 1003 screen:expect([[ 1004 {8:1 }^aaaaa | 1005 {8:2 }aaaaa | 1006 | 1007 ]]) 1008 -- In all windows 1009 command('wincmd v | set ls=0') 1010 command('sign place 1 line=2 name=sign') 1011 screen:expect([[ 1012 {8:1 }^aaaaa │{8:1 }aaaaa | 1013 {8:2 ss}aaaaa │{8:2 ss}aaaaa | 1014 | 1015 ]]) 1016 end) 1017 1018 it('is only evaluated twice, once to estimate and once to draw', function() 1019 command([[ 1020 let g:stcnr = 0 1021 func! Stc() 1022 let g:stcnr += 1 1023 return '12345' 1024 endfunc 1025 set stc=%!Stc() 1026 norm ggdG 1027 ]]) 1028 eq(2, eval('g:stcnr')) 1029 end) 1030 1031 it('does not wrap multibyte characters at the end of a line', function() 1032 screen:try_resize(33, 4) 1033 command([[set spell stc=%l\ ]]) 1034 command('call setline(8, "This is a line that contains ᶏ multibyte character.")') 1035 screen:expect([[ 1036 {8: 8 }^This is a line that contains {104:ᶏ}| 1037 {8: } {104:multibyte} character. | 1038 {8: 9 }{104:aaaaa} | 1039 | 1040 ]]) 1041 end) 1042 1043 it('line increase properly redraws buffer text with relativenumber #27709', function() 1044 screen:try_resize(33, 4) 1045 command([[set rnu nuw=3 stc=%{v:lnum}\ ]]) 1046 command('call setline(1, range(1, 99))') 1047 feed('Gyyp') 1048 screen:expect([[ 1049 {8:98 }98 | 1050 {8:99 }99 | 1051 {8:100 }^99 | 1052 | 1053 ]]) 1054 end) 1055 1056 it('forces a rebuild with nvim__redraw', function() 1057 screen:try_resize(40, 4) 1058 -- Current window 1059 command([[ 1060 let g:insert = v:false 1061 set nonu stc=%{g:insert?'insert':''} 1062 vsplit 1063 au InsertEnter * let g:insert = v:true | call nvim__redraw(#{statuscolumn:1, win:0}) 1064 au InsertLeave * let g:insert = v:false | call nvim__redraw(#{statuscolumn:1, win:0}) 1065 ]]) 1066 feed('i') 1067 screen:expect([[ 1068 {8:insert}^aaaaa │aaaaa | 1069 {8:insert}aaaaa │aaaaa | 1070 {3:[No Name] [+] }{2:[No Name] [+] }| 1071 {5:-- INSERT --} | 1072 ]]) 1073 feed('<esc>') 1074 screen:expect([[ 1075 ^aaaaa │aaaaa | 1076 aaaaa │aaaaa | 1077 {3:[No Name] [+] }{2:[No Name] [+] }| 1078 | 1079 ]]) 1080 -- All windows 1081 command([[ 1082 au! InsertEnter * let g:insert = v:true | call nvim__redraw(#{statuscolumn:1}) 1083 au! InsertLeave * let g:insert = v:false | call nvim__redraw(#{statuscolumn:1}) 1084 ]]) 1085 feed('i') 1086 screen:expect([[ 1087 {8:insert}^aaaaa │{8:insert}aaaaa | 1088 {8:insert}aaaaa │{8:insert}aaaaa | 1089 {3:[No Name] [+] }{2:[No Name] [+] }| 1090 {5:-- INSERT --} | 1091 ]]) 1092 feed('<esc>') 1093 screen:expect([[ 1094 ^aaaaa │aaaaa | 1095 aaaaa │aaaaa | 1096 {3:[No Name] [+] }{2:[No Name] [+] }| 1097 | 1098 ]]) 1099 end) 1100 1101 it('applies numhl highlight to virtual lines', function() 1102 exec_lua([[ 1103 vim.o.statuscolumn = '%=%{%v:virtnum==0?"%l":v:virtnum>0?"↳":"•"%}│' 1104 vim.o.cursorline = true 1105 vim.api.nvim_set_hl(0, 'CursorLineNr', { underline = true }) 1106 1107 vim.api.nvim_buf_set_extmark(0, ns, 0, 0, { number_hl_group = 'DiagnosticError' }) 1108 1109 local opts_1 = { number_hl_group = 'DiagnosticWarn', virt_lines = { { { 'Hello' } }, { { 'Hello' } } }, virt_lines_above = true } 1110 vim.api.nvim_buf_set_extmark(0, ns, 1, 0, opts_1) 1111 opts_1.virt_lines_above = nil 1112 vim.api.nvim_buf_set_extmark(0, ns, 1, 0, opts_1) 1113 1114 local opts_2 = { number_hl_group = 'DiagnosticInfo', virt_lines = { { { 'World' } }, { { 'World' } } }, virt_lines_above = true } 1115 vim.api.nvim_buf_set_extmark(0, ns, 2, 0, opts_2) 1116 opts_2.virt_lines_above = nil 1117 vim.api.nvim_buf_set_extmark(0, ns, 2, 0, opts_2) 1118 vim.cmd.norm('gg') 1119 ]]) 1120 screen:expect([[ 1121 {105: 1│}{21:^aaaaa }| 1122 {106: •│}Hello |*2 1123 {106: 2│}aaaaa | 1124 {106: •│}Hello |*2 1125 {107: •│}World |*2 1126 {107: 3│}aaaaa | 1127 {107: •│}World |*2 1128 {8: 4│}aaaaa | 1129 {8: 5│}aaaaa | 1130 | 1131 ]]) 1132 end) 1133 end)