fix(multicursor): 'guicursor' uses Normal shape in Visual mode #41669

Problem:
'guicursor' is not respected when extra cursors exist.

Per-cursor selection toggles Visual off, and the sandbox restores it
only after restore_current_state(), whose ui_cursor_shape() caches the
Normal shape.

Solution:
Restore Visual before restore_current_state().
This commit is contained in:
Justin M. Keyes
2026-09-03 13:22:50 -04:00
committed by GitHub
parent 3808c00fc8
commit da4355ab8f
2 changed files with 6 additions and 4 deletions

View File

@@ -307,10 +307,10 @@ static void mc_sandbox_leave(McSandbox *sb)
ctx_free(&sb->regs);
restore_redobuff(&sb->redo);
restore_search_patterns();
restore_current_state(&sb->sst);
// Visual before the cursor restore: check_cursor() below must see the restored mode (a
// blockwise 'virtualedit' selection would otherwise lose the cursor's coladd).
// Visual first: restore_current_state() updates the cursor shape, and check_cursor() below keeps
// a blockwise 'virtualedit' selection's coladd.
Visual = sb->visual;
restore_current_state(&sb->sst);
buf_T *buf = handle_get_buffer(sb->bufnr);
bool topline_valid = false;
if (buf != NULL) {

View File

@@ -1512,7 +1512,7 @@ describe('multicursor', function()
eq('n', api.nvim_get_mode().mode)
end)
it('shows per-cursor visual selection', function()
it('shows per-cursor selection', function()
local screen = Screen.new(30, 6)
cursors({ 'longword x', 'ab y', 'medium z' })
-- Each cursor shows its own selection ("iw" = that cursor's word), previewed live.
@@ -1524,6 +1524,7 @@ describe('multicursor', function()
{1:~ }|*2
{5:-- VISUAL --} |
]])
eq('visual', screen.mode) -- The UI mode ('guicursor'). #41631
feed('e')
screen:expect([[
{17:longword x} |
@@ -1540,6 +1541,7 @@ describe('multicursor', function()
{1:~ }|*2
|
]])
eq('normal', screen.mode)
end)
it('shows linewise/blockwise selections', function()