From b00b169bf5bee7a4a3c812ba81236027766e7ebe Mon Sep 17 00:00:00 2001 From: Barrett Ruth <62671086+barrettruth@users.noreply.github.com> Date: Tue, 3 Mar 2026 13:42:44 -0500 Subject: [PATCH] feat(compiler): debounce compilation in toggle mode (#8) 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 | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/lua/preview/compiler.lua b/lua/preview/compiler.lua index 50ab0ba..6e3f5cf 100644 --- a/lua/preview/compiler.lua +++ b/lua/preview/compiler.lua @@ -15,6 +15,10 @@ local opened = {} ---@type table local last_output = {} +local debounce_timers = {} + +local DEBOUNCE_MS = 500 + ---@param val string[]|fun(ctx: preview.Context): string[] ---@param ctx preview.Context ---@return string[] @@ -179,8 +183,19 @@ 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, }) @@ -206,6 +221,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 @@ -275,6 +295,7 @@ M._test = { watching = watching, opened = opened, last_output = last_output, + debounce_timers = debounce_timers, } return M