From da2997e10f341610d7aa4dd9d93c40fa89fe463f Mon Sep 17 00:00:00 2001 From: Jay Shitre Date: Sat, 6 Jun 2026 09:47:08 +0530 Subject: [PATCH] fix: force UI flush after RPC-created diff on Windows conhost (cmd.exe) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When Neovim runs in the legacy Windows console (cmd.exe / conhost), a diff opened via the hook's `nvim --remote-expr` call did not paint until the next event — the user's next edit. neo-tree updated meanwhile (it forces its own redraw), producing the "marking shows but diff doesn't" symptom. The deferred `redraw!` is simply not flushed by conhost from an idle --remote-expr. Extract the post-tab repaint into force_redraw() and, on Windows only, follow the `redraw!` with nvim__redraw({ flush = true }) (pushes the grid to the UI) plus an feedkeys nudge (wakes the input loop so conhost delivers it). Both pcall'd (__redraw is 0.10+ / semi-private); the whole block is behind has('win32'), so every other platform keeps byte-identical prior behaviour. Pre-existing behaviour, not a regression from the hook-entry consolidation (#77): the redraw timer predates Windows support and the RPC call path was unchanged. Verified manually in a cmd terminal — the diff now appears on the first edit. Co-Authored-By: Claude Opus 4.8 --- lua/code-preview/diff.lua | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/lua/code-preview/diff.lua b/lua/code-preview/diff.lua index 79a6ccb..db14932 100644 --- a/lua/code-preview/diff.lua +++ b/lua/code-preview/diff.lua @@ -95,6 +95,31 @@ local function read_file_lines(path) return lines end +-- Force the terminal to repaint after an RPC-driven tab/window change. +-- +-- show_diff runs inside a `nvim --remote-expr` call from the hook shim, so the +-- new diff tab exists in Neovim's state immediately but the TUI isn't repainted +-- until the event loop next wakes. A deferred `redraw!` covers most hosts. +-- +-- The Windows legacy console (cmd.exe / conhost) is the exception: it does NOT +-- flush a timer-driven `redraw!` issued from an idle --remote-expr, so the diff +-- only paints on the next event (the user's next edit) — neo-tree, which forces +-- its own redraw, updates meanwhile, producing the "marking shows but diff +-- doesn't" symptom. nvim__redraw({flush=true}) pushes the grid to the UI on the +-- spot, and the feedkeys nudge wakes the input loop so conhost delivers +-- it. Both are pcall'd: __redraw is 0.10+ and semi-private. The win32 guard keeps +-- every other platform on the exact prior behaviour. +local function force_redraw() + vim.fn.timer_start(10, function() + vim.cmd("redraw!") + if vim.fn.has("win32") == 1 then + pcall(vim.api.nvim__redraw, { flush = true }) + pcall(vim.api.nvim_feedkeys, + vim.api.nvim_replace_termcodes("", true, false, true), "n", false) + end + end) +end + --- Count how many active diffs are currently open. local function active_count() local n = 0 @@ -412,8 +437,8 @@ function M.show_diff(original_path, proposed_path, real_file_path, abs_file_path if cfg.diff.layout == "inline" then local result = show_inline_diff(original_path, proposed_path, real_file_path, cfg) active_diffs[file_key] = result - -- Force terminal redraw via timer so RPC-triggered tab creation is visible - vim.fn.timer_start(10, function() vim.cmd("redraw!") end) + -- Force terminal redraw so RPC-triggered tab creation is visible (see force_redraw). + force_redraw() return end @@ -498,7 +523,7 @@ function M.show_diff(original_path, proposed_path, real_file_path, abs_file_path vim.cmd("normal! ]c") - vim.fn.timer_start(10, function() vim.cmd("redraw!") end) + force_redraw() end --- Close the diff for a specific file and clean up its resources.