Compare commits

...

4 Commits

Author SHA1 Message Date
glepnir
2bbe25219d
Merge 5bb11844b3 into 160cbd0ef4 2024-12-18 21:39:48 +01:00
luukvbaal
160cbd0ef4
test(cursor_spec): global highlight definitions (#31613) 2024-12-18 19:06:16 +00:00
Gregory Anders
3db3947b0e
fix(terminal): restore cursor from 'guicursor' on TermLeave (#31620)
Fixes: https://github.com/neovim/neovim/issues/31612
2024-12-18 11:41:05 -06:00
glepnir
5bb11844b3 fix(diagnostic): support function type of float in open_float()
Problem: the float field of vim.diagnostic.config can be a function type
but function was ignored in open_float function.

Solution: check global_diagnostic_options.float type before use for funciton type
2024-12-14 18:05:46 +08:00
4 changed files with 113 additions and 59 deletions

View File

@ -1824,10 +1824,13 @@ function M.open_float(opts, ...)
-- Resolve options with user settings from vim.diagnostic.config
-- Unlike the other decoration functions (e.g. set_virtual_text, set_signs, etc.) `open_float`
-- does not have a dedicated table for configuration options; instead, the options are mixed in
-- with its `opts` table which also includes "keyword" parameters. So we create a dedicated
-- options table that inherits missing keys from the global configuration before resolving.
local t = global_diagnostic_options.float
local float_opts = vim.tbl_extend('keep', opts, type(t) == 'table' and t or {})
-- with its `opts` table. We create a dedicated options table (`float_opts`) that inherits
-- missing keys from the global configuration (`global_diagnostic_options.float`), which can
-- be a table or a function.
local o = global_diagnostic_options
local t = type(o.float) == 'table' and o.float
or (type(o.float) == 'function' and o.float(0, bufnr) or {})
local float_opts = vim.tbl_extend('keep', opts, t)
opts = get_resolved_options({ float = float_opts }, nil, bufnr).float
end

View File

@ -641,9 +641,6 @@ bool terminal_enter(void)
curwin->w_p_so = 0;
curwin->w_p_siso = 0;
// Save the existing cursor entry since it may be modified by the application
cursorentry_T save_cursorentry = shape_table[SHAPE_IDX_TERM];
// Update the cursor shape table and flush changes to the UI
s->term->pending.cursor = true;
refresh_cursor(s->term);
@ -674,8 +671,8 @@ bool terminal_enter(void)
RedrawingDisabled = s->save_rd;
apply_autocmds(EVENT_TERMLEAVE, NULL, NULL, false, curbuf);
shape_table[SHAPE_IDX_TERM] = save_cursorentry;
ui_mode_info_set();
// Restore the terminal cursor to what is set in 'guicursor'
(void)parse_shape_opt(SHAPE_CURSOR);
if (save_curwin == curwin->handle) { // Else: window was closed.
curwin->w_p_cul = save_w_p_cul;

View File

@ -1750,6 +1750,19 @@ describe('vim.diagnostic', function()
return _G.count_extmarks(_G.diagnostic_bufnr, _G.diagnostic_ns)
end)
)
--`float` option defined as a function.
eq(
true,
exec_lua(function()
vim.diagnostic.config({
float = function(_, _)
return { border = 'rounded' }
end,
})
return type(vim.diagnostic.config().float) == 'function'
end)
)
end)
it('can use functions for config values', function()
@ -2501,6 +2514,37 @@ describe('vim.diagnostic', function()
)
end)
it('', function()
eq(
{ { 'Diagnostics:', '1. syntax error' }, '', '' },
exec_lua(function()
local diagnostics = {
_G.make_error('syntax error', 0, 1, 0, 3),
}
vim.api.nvim_win_set_buf(0, _G.diagnostic_bufnr)
vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, diagnostics)
vim.diagnostic.config({
float = function(_, bufnr)
return { border = bufnr == _G.diagnostic_bufnr and 'rounded' or 'single' }
end,
})
local float_bufnr, winnr = vim.diagnostic.open_float()
local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
local border1 = vim.api.nvim_win_get_config(winnr).border
vim.api.nvim_win_close(winnr, true)
local other_bufnr = vim.api.nvim_create_buf(true, true)
vim.api.nvim_win_set_buf(0, other_bufnr)
vim.diagnostic.set(_G.diagnostic_ns, other_bufnr, diagnostics)
local _, winnr1 = vim.diagnostic.open_float()
local border2 = vim.api.nvim_win_get_config(winnr1).border
vim.api.nvim_win_close(winnr1, true)
return { lines, border1[1], border2[1] }
end)
)
end)
it('can show diagnostics from the whole buffer', function()
eq(
{ '1. Syntax error', '2. Some warning' },

View File

@ -15,9 +15,20 @@ local skip = t.skip
describe(':terminal cursor', function()
local screen
local terminal_mode_idx ---@type number
before_each(function()
clear()
screen = tt.setup_screen()
if terminal_mode_idx == nil then
for i, v in ipairs(screen._mode_info) do
if v.name == 'terminal' then
terminal_mode_idx = i
end
end
assert(terminal_mode_idx)
end
end)
it('moves the screen cursor when focused', function()
@ -143,13 +154,6 @@ describe(':terminal cursor', function()
it('can be modified by application #3681', function()
skip(is_os('win'), '#31587')
local idx ---@type number
for i, v in ipairs(screen._mode_info) do
if v.name == 'terminal' then
idx = i
end
end
assert(idx)
local states = {
[1] = { blink = true, shape = 'block' },
@ -171,13 +175,13 @@ describe(':terminal cursor', function()
]],
condition = function()
if v.blink then
eq(500, screen._mode_info[idx].blinkon)
eq(500, screen._mode_info[idx].blinkoff)
eq(500, screen._mode_info[terminal_mode_idx].blinkon)
eq(500, screen._mode_info[terminal_mode_idx].blinkoff)
else
eq(0, screen._mode_info[idx].blinkon)
eq(0, screen._mode_info[idx].blinkoff)
eq(0, screen._mode_info[terminal_mode_idx].blinkon)
eq(0, screen._mode_info[terminal_mode_idx].blinkoff)
end
eq(v.shape, screen._mode_info[idx].cursor_shape)
eq(v.shape, screen._mode_info[terminal_mode_idx].cursor_shape)
end,
})
end
@ -191,20 +195,13 @@ describe(':terminal cursor', function()
]])
-- Cursor returns to default on TermLeave
eq(500, screen._mode_info[idx].blinkon)
eq(500, screen._mode_info[idx].blinkoff)
eq('block', screen._mode_info[idx].cursor_shape)
eq(500, screen._mode_info[terminal_mode_idx].blinkon)
eq(500, screen._mode_info[terminal_mode_idx].blinkoff)
eq('block', screen._mode_info[terminal_mode_idx].cursor_shape)
end)
it('can be modified per terminal', function()
skip(is_os('win'), '#31587')
local idx ---@type number
for i, v in ipairs(screen._mode_info) do
if v.name == 'terminal' then
idx = i
end
end
assert(idx)
-- Set cursor to vertical bar with blink
tt.feed_csi('5 q')
@ -216,9 +213,9 @@ describe(':terminal cursor', function()
{3:-- TERMINAL --} |
]],
condition = function()
eq(500, screen._mode_info[idx].blinkon)
eq(500, screen._mode_info[idx].blinkoff)
eq('vertical', screen._mode_info[idx].cursor_shape)
eq(500, screen._mode_info[terminal_mode_idx].blinkon)
eq(500, screen._mode_info[terminal_mode_idx].blinkoff)
eq('vertical', screen._mode_info[terminal_mode_idx].cursor_shape)
end,
})
@ -231,9 +228,9 @@ describe(':terminal cursor', function()
{3:-- TERMINAL --} |
]],
condition = function()
eq(500, screen._mode_info[idx].blinkon)
eq(500, screen._mode_info[idx].blinkoff)
eq('vertical', screen._mode_info[idx].cursor_shape)
eq(500, screen._mode_info[terminal_mode_idx].blinkon)
eq(500, screen._mode_info[terminal_mode_idx].blinkoff)
eq('vertical', screen._mode_info[terminal_mode_idx].cursor_shape)
end,
})
@ -256,9 +253,9 @@ describe(':terminal cursor', function()
]],
condition = function()
-- New terminal, cursor resets to defaults
eq(500, screen._mode_info[idx].blinkon)
eq(500, screen._mode_info[idx].blinkoff)
eq('block', screen._mode_info[idx].cursor_shape)
eq(500, screen._mode_info[terminal_mode_idx].blinkon)
eq(500, screen._mode_info[terminal_mode_idx].blinkoff)
eq('block', screen._mode_info[terminal_mode_idx].cursor_shape)
end,
})
@ -275,9 +272,9 @@ describe(':terminal cursor', function()
{3:-- TERMINAL --} |
]],
condition = function()
eq(0, screen._mode_info[idx].blinkon)
eq(0, screen._mode_info[idx].blinkoff)
eq('horizontal', screen._mode_info[idx].cursor_shape)
eq(0, screen._mode_info[terminal_mode_idx].blinkon)
eq(0, screen._mode_info[terminal_mode_idx].blinkoff)
eq('horizontal', screen._mode_info[terminal_mode_idx].cursor_shape)
end,
})
@ -294,9 +291,9 @@ describe(':terminal cursor', function()
{3:-- TERMINAL --} |
]],
condition = function()
eq(500, screen._mode_info[idx].blinkon)
eq(500, screen._mode_info[idx].blinkoff)
eq('vertical', screen._mode_info[idx].cursor_shape)
eq(500, screen._mode_info[terminal_mode_idx].blinkon)
eq(500, screen._mode_info[terminal_mode_idx].blinkoff)
eq('vertical', screen._mode_info[terminal_mode_idx].cursor_shape)
end,
})
end)
@ -326,6 +323,32 @@ describe(':terminal cursor', function()
{3:-- TERMINAL --} |
]])
end)
it('preserves guicursor value on TermLeave #31612', function()
eq(3, screen._mode_info[terminal_mode_idx].hl_id)
-- Change 'guicursor' while terminal mode is active
command('set guicursor+=t:Error')
local error_hl_id = call('hlID', 'Error')
screen:expect({
condition = function()
eq(error_hl_id, screen._mode_info[terminal_mode_idx].hl_id)
end,
})
-- Exit terminal mode
feed([[<C-\><C-N>]])
screen:expect([[
tty ready |
^ |
|*5
]])
eq(error_hl_id, screen._mode_info[terminal_mode_idx].hl_id)
end)
end)
describe('buffer cursor position is correct in terminal without number column', function()
@ -350,12 +373,6 @@ describe('buffer cursor position is correct in terminal without number column',
}, {
cols = 70,
})
screen:set_default_attr_ids({
[1] = { foreground = 253, background = 11 },
[2] = { reverse = true },
[3] = { bold = true },
[4] = { background = 11 },
})
-- Also check for real cursor position, as it is used for stuff like input methods
screen._handle_busy_start = function() end
screen._handle_busy_stop = function() end
@ -667,13 +684,6 @@ describe('buffer cursor position is correct in terminal with number column', fun
}, {
cols = 70,
})
screen:set_default_attr_ids({
[1] = { foreground = 253, background = 11 },
[2] = { reverse = true },
[3] = { bold = true },
[4] = { background = 11 },
[7] = { foreground = 130 },
})
-- Also check for real cursor position, as it is used for stuff like input methods
screen._handle_busy_start = function() end
screen._handle_busy_stop = function() end