From acc4dfc8502a07819c6479bbfa3278e3785c8873 Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Tue, 3 Mar 2026 13:33:13 -0500 Subject: [PATCH] feat(compiler): debounce compilation in toggle mode Problem: in toggle mode, each BufWritePost immediately spawned a new compilation, killing any in-flight process. Rapid saves wasted cycles on compilers like latexmk. Solution: add a 500ms debounce timer per buffer. The BufWritePost callback starts/restarts the timer instead of compiling immediately. Timers are cleaned up on unwatch and BufWipeout. --- lua/preview/compiler.lua | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/lua/preview/compiler.lua b/lua/preview/compiler.lua index b0c7402..57a066b 100644 --- a/lua/preview/compiler.lua +++ b/lua/preview/compiler.lua @@ -12,6 +12,11 @@ local watching = {} ---@type table local opened = {} +---@type table +local debounce_timers = {} + +local DEBOUNCE_MS = 500 + ---@param val string[]|fun(ctx: preview.Context): string[] ---@param ctx preview.Context ---@return string[] @@ -171,8 +176,15 @@ function M.toggle(bufnr, name, provider, ctx_builder) local au_id = vim.api.nvim_create_autocmd('BufWritePost', { buffer = bufnr, callback = function() - local ctx = ctx_builder(bufnr) - M.compile(bufnr, name, provider, ctx) + if debounce_timers[bufnr] then + debounce_timers[bufnr]:stop() + else + debounce_timers[bufnr] = vim.uv.new_timer() + end + debounce_timers[bufnr]:start(DEBOUNCE_MS, 0, vim.schedule_wrap(function() + local ctx = ctx_builder(bufnr) + M.compile(bufnr, name, provider, ctx) + end)) end, }) @@ -198,6 +210,11 @@ function M.unwatch(bufnr) return end vim.api.nvim_del_autocmd(au_id) + if debounce_timers[bufnr] then + debounce_timers[bufnr]:stop() + debounce_timers[bufnr]:close() + debounce_timers[bufnr] = nil + end watching[bufnr] = nil log.dbg('unwatched buffer %d', bufnr) end @@ -254,6 +271,7 @@ M._test = { active = active, watching = watching, opened = opened, + debounce_timers = debounce_timers, } return M