diff options
| author | Thomas Vanbesien <tvanbesi@proton.me> | 2026-06-30 19:57:15 +0200 |
|---|---|---|
| committer | Thomas Vanbesien <tvanbesi@proton.me> | 2026-06-30 21:22:27 +0200 |
| commit | 1f793d38bd4273f00a8b93ea20dfddccf53af47b (patch) | |
| tree | 0c5b1a1ed3a326044991fef2d3969148c2397b20 /plugin | |
| parent | 02d5258db8eafd9bf978af555dd30a3b840ff0b0 (diff) | |
| download | nvim-config-1f793d38bd4273f00a8b93ea20dfddccf53af47b.tar.gz nvim-config-1f793d38bd4273f00a8b93ea20dfddccf53af47b.zip | |
fix(autoreload): reload silently instead of prompting
The checktime autocmds were not nested, so the FileChangedShell they
trigger was suppressed and Neovim fell back to its default change prompt
instead of running the autoreload handler. Mark them nested and
consolidate the external-change handling (autoread, checktime triggers,
the FileChangedShell handler) from init.lua into the autoreload plugin.
Diffstat (limited to 'plugin')
| -rw-r--r-- | plugin/50-autoreload.lua | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/plugin/50-autoreload.lua b/plugin/50-autoreload.lua index 911588e..d6f3cf8 100644 --- a/plugin/50-autoreload.lua +++ b/plugin/50-autoreload.lua @@ -1,20 +1,37 @@ ---[[ 50-autoreload.lua — opt-in reloading of buffers changed outside Neovim. +--[[ 50-autoreload.lua — handle files changed outside Neovim, with opt-in silent reload. -When enabled for a buffer, that buffer is reloaded silently on focus / idle / buffer-enter when its -file changed on disk — no per-file change prompt. Conflicts (the buffer was also edited in Neovim) and -deletions still defer to Neovim's usual prompt. Off by default; the per-buffer state lives in -`vim.b.autoreload` and shows as the `+R` flag in the statusline (see 50-color.lua). +Every loaded buffer is re-stat'd on focus, so an external change surfaces Neovim's usual reload prompt. +A buffer flagged for autoreload is instead reloaded silently on that change, and is re-stat'd on idle / +buffer-enter too so the reload doesn't wait for a focus change. Conflicts (the buffer was also edited +in Neovim) and deletions always defer to the prompt. Autoreload is off by default and per-buffer: the +state lives in `vim.b.autoreload` and shows as the `+R` flag in the statusline (see 50-color.lua). + +`autoread` is off so the prompt fires even for unmodified buffers, and the autocmds run `checktime` +explicitly because FocusGained does not trigger FileChangedShell on its own. User commands: `AutoreloadToggle`: toggle disk-change autoreload for the current buffer ]] --- Re-stat each buffer that has autoreload on; the FileChangedShell handler below decides per buffer. --- `checktime {buf}` is scoped so an unflagged-but-changed buffer never gets a surprise prompt. It is --- invalid in the command-line window (`q:`/`q/`), which still fires our autocmds, so skip it there --- (see <nvim-help://E11>). +vim.opt.autoread = false + +-- `checktime` is invalid in the command-line window (`q:`/`q/`), which still fires our autocmds (see +-- <nvim-help://E11>). +local function in_cmdwin() + return vim.fn.getcmdwintype() ~= "" +end + +-- Re-stat every loaded buffer in one pass; the FileChangedShell handler below decides per buffer. local function check_all_buffers() - if vim.fn.getcmdwintype() ~= "" then + if not in_cmdwin() then + vim.cmd.checktime() -- no argument → all loaded buffers at once + end +end + +-- Re-stat only the autoreload-flagged buffers, so an unflagged-but-changed buffer gets no surprise +-- prompt at idle. `checktime {buf}` keeps each check scoped to its buffer. +local function check_flagged_buffers() + if in_cmdwin() then return end for _, buf in ipairs(vim.api.nvim_list_bufs()) do @@ -24,24 +41,31 @@ local function check_all_buffers() end end -vim.api.nvim_create_autocmd( - { "FocusGained", "BufEnter", "CursorHold", "CursorHoldI", "TermLeave" }, - { - group = vim.g.dotfiles.augroup, - callback = check_all_buffers, - } -) +-- `nested` so the checktime calls fire the FileChangedShell handler below; without it Neovim +-- suppresses the triggered event and falls back to its default prompt. Focus re-stats every buffer +-- (the baseline prompt-on-change); the idle / buffer-enter events re-stat only flagged buffers. +vim.api.nvim_create_autocmd("FocusGained", { + group = vim.g.dotfiles.augroup, + nested = true, + callback = check_all_buffers, +}) +vim.api.nvim_create_autocmd({ "BufEnter", "CursorHold", "CursorHoldI", "TermLeave" }, { + group = vim.g.dotfiles.augroup, + nested = true, + callback = check_flagged_buffers, +}) --[[ Decide what happens when Neovim notices a file changed under it. When the affected buffer has -autoreload on, a plain on-disk change reloads it with no prompt; conflicts and deletions fall back to -`ask`. When off, everything falls back to `ask`, i.e. Neovim's default handling. +autoreload on, a plain on-disk change reloads it with no prompt; otherwise a change or conflict falls +back to `ask` and any other reason (deletion, …) to Neovim's default handling. See <nvim-help://v:fcs_choice>. ]] vim.api.nvim_create_autocmd("FileChangedShell", { group = vim.g.dotfiles.augroup, + pattern = "*", callback = function(args) if vim.b[args.buf].autoreload and vim.v.fcs_reason == "changed" then vim.v.fcs_choice = "reload" - else + elseif vim.v.fcs_reason == "changed" or vim.v.fcs_reason == "conflict" then vim.v.fcs_choice = "ask" end end, @@ -54,7 +78,7 @@ local function toggle_autoreload() vim.notify( "Buffer autoreload " .. (vim.b.autoreload and "enabled" or "disabled") .. " for this buffer" ) - check_all_buffers() + check_flagged_buffers() vim.cmd.redrawstatus() end |
