diff options
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 |
