mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	fix(diagnostic): virtual_lines diagnostic columns (#32703)
When multiple diagnostics appear on a single line, the virtual lines for all diagnostics except the first were rendered with progressively fewer columns.
This commit is contained in:
		| @@ -1757,8 +1757,7 @@ local function render_virtual_lines(namespace, bufnr, diagnostics) | ||||
|         string.rep( | ||||
|           ' ', | ||||
|           -- +1 because indexing starts at 0 in one API but at 1 in the other. | ||||
|           -- -1 for non-first lines, since the previous column was already drawn. | ||||
|           distance_between_cols(bufnr, diag.lnum, prev_col + 1, diag.col) - 1 | ||||
|           distance_between_cols(bufnr, diag.lnum, prev_col + 1, diag.col) | ||||
|         ), | ||||
|       }) | ||||
|     else | ||||
|   | ||||
| @@ -2231,6 +2231,110 @@ describe('vim.diagnostic', function() | ||||
|       eq('Another error there!', result[2][4].virt_lines[1][3][1]) | ||||
|     end) | ||||
|  | ||||
|     it('highlights multiple diagnostics in a single line by default', function() | ||||
|       local result = exec_lua(function() | ||||
|         vim.api.nvim_buf_set_lines( | ||||
|           _G.diagnostic_bufnr, | ||||
|           0, | ||||
|           -1, | ||||
|           false, | ||||
|           { 'def foo(x: int, /, y: str, *, z: float) -> None: ...' } | ||||
|         ) | ||||
|  | ||||
|         vim.diagnostic.config({ virtual_lines = true }) | ||||
|  | ||||
|         vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, { | ||||
|           _G.make_error('Error here!', 0, 8, 0, 9, 'foo_server'), | ||||
|           _G.make_error('Another error there!', 0, 19, 0, 20, 'foo_server'), | ||||
|           _G.make_error('And another one!', 0, 30, 0, 31, 'foo_server'), | ||||
|         }) | ||||
|  | ||||
|         local extmarks = _G.get_virt_lines_extmarks(_G.diagnostic_ns) | ||||
|         return extmarks | ||||
|       end) | ||||
|  | ||||
|       --[[ | ||||
|       |def foo(x: int, /, y: str, *, z: float) -> None: ... | ||||
|       |        │          │          └──── And another one! | ||||
|       |        │          └──── Another error there! | ||||
|       |        └──── Error here! | ||||
|       |        ^ col=8 | ||||
|       |                   ^ col=19 | ||||
|       |                              ^ col=30 | ||||
|  | ||||
|       11 cols between each diagnostic after the first one (10 spaces + |) | ||||
|       ]] | ||||
|  | ||||
|       eq(1, #result) | ||||
|       local virt_lines = result[1][4].virt_lines | ||||
|       eq(8, virt_lines[1][1][1]:len()) -- first space | ||||
|       eq(10, virt_lines[1][3][1]:len()) -- second space | ||||
|       eq(10, virt_lines[1][5][1]:len()) -- third space | ||||
|       eq('And another one!', virt_lines[1][7][1]) | ||||
|       eq(8, virt_lines[2][1][1]:len()) -- first space | ||||
|       eq(10, virt_lines[2][3][1]:len()) -- second space | ||||
|       eq('Another error there!', virt_lines[2][5][1]) | ||||
|       eq(8, virt_lines[3][1][1]:len()) -- first space | ||||
|       eq('Error here!', virt_lines[3][3][1]) | ||||
|     end) | ||||
|  | ||||
|     it('highlights overlapping diagnostics on a single line', function() | ||||
|       local result = exec_lua(function() | ||||
|         vim.diagnostic.config({ virtual_lines = true }) | ||||
|  | ||||
|         vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, { | ||||
|           _G.make_error('Error here!', 0, 10, 0, 11, 'foo_server'), | ||||
|           _G.make_error('Another error here!', 0, 10, 0, 11, 'foo_server'), | ||||
|         }) | ||||
|  | ||||
|         local extmarks = _G.get_virt_lines_extmarks(_G.diagnostic_ns) | ||||
|         return extmarks | ||||
|       end) | ||||
|  | ||||
|       --[[ | ||||
|       |1234567890x | ||||
|       |          ├──── Another error here! | ||||
|       |          └──── Error here! | ||||
|       ]] | ||||
|  | ||||
|       eq(1, #result) | ||||
|       local virt_lines = result[1][4].virt_lines | ||||
|       eq(10, virt_lines[1][1][1]:len()) -- first space | ||||
|       eq('├──── ', virt_lines[1][2][1]) | ||||
|       eq('Another error here!', virt_lines[1][3][1]) | ||||
|       eq(10, virt_lines[2][1][1]:len()) -- second space | ||||
|       eq('└──── ', virt_lines[2][2][1]) | ||||
|       eq('Error here!', virt_lines[2][3][1]) | ||||
|     end) | ||||
|  | ||||
|     it('handles multi-line diagnostic message', function() | ||||
|       local result = exec_lua(function() | ||||
|         vim.diagnostic.config({ virtual_lines = true }) | ||||
|  | ||||
|         vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, { | ||||
|           _G.make_error('Error here!\ngot another line', 0, 10, 0, 11, 'foo_server'), | ||||
|         }) | ||||
|  | ||||
|         local extmarks = _G.get_virt_lines_extmarks(_G.diagnostic_ns) | ||||
|         return extmarks | ||||
|       end) | ||||
|  | ||||
|       --[[ | ||||
|       |1234567890x | ||||
|       |          └──── Error here! | ||||
|       |                got another line | ||||
|       ]] | ||||
|  | ||||
|       eq(1, #result) | ||||
|       local virt_lines = result[1][4].virt_lines | ||||
|       eq(10, virt_lines[1][1][1]:len()) -- first space | ||||
|       eq('└──── ', virt_lines[1][2][1]) | ||||
|       eq('Error here!', virt_lines[1][3][1]) | ||||
|       eq(10, virt_lines[2][1][1]:len()) -- second line space | ||||
|       eq(6, virt_lines[2][2][1]:len()) -- extra padding | ||||
|       eq('got another line', virt_lines[2][3][1]) | ||||
|     end) | ||||
|  | ||||
|     it('can highlight diagnostics only in the current line', function() | ||||
|       local result = exec_lua(function() | ||||
|         vim.api.nvim_win_set_cursor(0, { 1, 0 }) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 James Trew
					James Trew