summaryrefslogtreecommitdiffstats
path: root/plugin
diff options
context:
space:
mode:
Diffstat (limited to 'plugin')
-rw-r--r--plugin/50-autoreload.lua66
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