From 54ef0c3c99f505098252bbb9e37a4b022b0d5ec8 Mon Sep 17 00:00:00 2001 From: Barrett Ruth <62671086+barrettruth@users.noreply.github.com> Date: Wed, 4 Mar 2026 00:17:10 -0500 Subject: [PATCH 1/2] fix(compiler): guard active entry before clearing in process callback (#22) * fix(compiler): guard active entry before clearing in process callback Problem: when M.compile() is called while a previous process is still running, the old process's vim.schedule_wrap callback unconditionally sets active[bufnr] = nil, wiping the new process from the tracking table. status() incorrectly returns idle and stop() becomes a no-op against the still-running process. Solution: capture obj as an upvalue in each callback and only clear active[bufnr] if it still points to the same process object. * fix(compiler): hoist obj declaration before vim.system closure Problem: lua-language-server flagged obj as an undefined global in both vim.schedule_wrap callbacks because local obj = vim.system(...) puts the variable out of scope inside the closure at declaration time. At runtime the guard active[bufnr].obj == obj evaluated obj as nil, so the clear was always skipped and the process remained tracked indefinitely. Solution: split into local obj / obj = vim.system(...) so the upvalue is in scope when the closure is defined. --- lua/preview/compiler.lua | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lua/preview/compiler.lua b/lua/preview/compiler.lua index 6f9b312..ee55604 100644 --- a/lua/preview/compiler.lua +++ b/lua/preview/compiler.lua @@ -91,14 +91,17 @@ function M.compile(bufnr, name, provider, ctx) table.concat(reload_cmd, ' ') ) - local obj = vim.system( + local obj + obj = vim.system( reload_cmd, { cwd = cwd, env = provider.env, }, vim.schedule_wrap(function(result) - active[bufnr] = nil + if active[bufnr] and active[bufnr].obj == obj then + active[bufnr] = nil + end if not vim.api.nvim_buf_is_valid(bufnr) then return end @@ -180,14 +183,17 @@ function M.compile(bufnr, name, provider, ctx) log.dbg('compiling buffer %d with provider "%s": %s', bufnr, name, table.concat(cmd, ' ')) - local obj = vim.system( + local obj + obj = vim.system( cmd, { cwd = cwd, env = provider.env, }, vim.schedule_wrap(function(result) - active[bufnr] = nil + if active[bufnr] and active[bufnr].obj == obj then + active[bufnr] = nil + end if not vim.api.nvim_buf_is_valid(bufnr) then return end From c12891f7ea97e79ec2fb8a12bcc035ee3c994bb6 Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Wed, 4 Mar 2026 00:20:10 -0500 Subject: [PATCH 2/2] style(compiler): reformat long condition for stylua --- lua/preview/compiler.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lua/preview/compiler.lua b/lua/preview/compiler.lua index 29ffcaf..8555881 100644 --- a/lua/preview/compiler.lua +++ b/lua/preview/compiler.lua @@ -147,7 +147,12 @@ function M.compile(bufnr, name, provider, ctx) end) ) - if provider.open and not opened[bufnr] and output_file ~= '' and vim.uv.fs_stat(output_file) then + if + provider.open + and not opened[bufnr] + and output_file ~= '' + and vim.uv.fs_stat(output_file) + then if provider.open == true then vim.ui.open(output_file) elseif type(provider.open) == 'table' then