aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Anders <greg@gpanders.com>2024-12-18 11:41:05 -0600
committerGitHub <noreply@github.com>2024-12-18 11:41:05 -0600
commit3db3947b0ed256d498b09eef95c4969e28387e66 (patch)
tree572c9e6f9508a4255353506e81998e0b17343e5a
parent7121983c45d92349a6532f32dcde9f425e30781e (diff)
downloadrneovim-3db3947b0ed256d498b09eef95c4969e28387e66.tar.gz
rneovim-3db3947b0ed256d498b09eef95c4969e28387e66.tar.bz2
rneovim-3db3947b0ed256d498b09eef95c4969e28387e66.zip
fix(terminal): restore cursor from 'guicursor' on TermLeave (#31620)
Fixes: https://github.com/neovim/neovim/issues/31612
-rw-r--r--src/nvim/terminal.c7
-rw-r--r--test/functional/terminal/cursor_spec.lua97
2 files changed, 62 insertions, 42 deletions
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index fa08f3d6ca..969c539f97 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -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;
diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua
index d4d08fb24c..657468c03e 100644
--- a/test/functional/terminal/cursor_spec.lua
+++ b/test/functional/terminal/cursor_spec.lua
@@ -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()