feat(multicursor): MC HAMMER #41587

Other (squashed) commits:

fix(tui): emit ui_send output atomically with the frame

Problem:
tui_ui_send() writes directly to the TTY, bypassing the output buffer.
Sequences sent via nvim_ui_send() (e.g. kitty multiple-cursors, or
visual-dot-repeat) always arrive in a separate TTY write from the frame
they were computed for. This manifests as "tearing", or e.g. in the case
of multicursor the terminal renders text with stale cursor overlays.

Solution:
- tui_ui_send(): while a frame is being assembled (pending invalid
  regions or buffered output), buffer instead of writing directly.
  - Out-of-frame sends (tty queries, clear-on-disable) still write
    immediately.
- mcursor.lua: emit the terminal-cursor update at the end of the redraw
  cycle (`on_end`, when screen positions are final) instead of
  vim.schedule().
This commit is contained in:
Justin M. Keyes
2026-09-01 11:17:22 -04:00
committed by GitHub
parent 9ebf9b1017
commit 9a29622b54
63 changed files with 5093 additions and 347 deletions

View File

@@ -119,6 +119,12 @@ function vim.api.nvim__inspect_cell(grid, row, col) end
--- reach, so this function can be used to force a cache clear in a test.
function vim.api.nvim__invalidate_glyph_cache() end
--- WARNING: This feature is experimental/unstable.
---
--- Returns true if a multicursor cascade is in-progress.
--- @return boolean
function vim.api.nvim__mcursor_cascading() end
--- WARNING: This feature is experimental/unstable.
---
--- Get the properties for namespace
@@ -1674,6 +1680,13 @@ function vim.api.nvim_list_wins() end
--- @return any
function vim.api.nvim_load_context(dict) end
--- Adds a multicursor in the given buffer.
---
--- @param buf integer Buffer handle, or 0 for current buffer
--- @param pos [integer, integer] (row, col) (1,0)-indexed cursor position (byte offset)
--- @return integer # Total number of extra cursors.
function vim.api.nvim_mcursor(buf, pos) end
--- @deprecated
--- @param msg string
--- @param log_level integer