diff options
-rw-r--r-- | lua/conform/init.lua | 35 | ||||
-rw-r--r-- | lua/conform/runner.lua | 8 |
2 files changed, 42 insertions, 1 deletions
diff --git a/lua/conform/init.lua b/lua/conform/init.lua index 5f8610a..271e33d 100644 --- a/lua/conform/init.lua +++ b/lua/conform/init.lua @@ -106,6 +106,8 @@ M.setup = function(opts) if type(opts.format_after_save) == "boolean" then opts.format_after_save = {} end + local exit_timeout = 1000 + local num_running_format_jobs = 0 vim.api.nvim_create_autocmd("BufWritePost", { pattern = "*", group = aug, @@ -118,12 +120,15 @@ M.setup = function(opts) format_args, callback = format_args(args.buf) end if format_args then + exit_timeout = format_args.timeout_ms or exit_timeout + num_running_format_jobs = num_running_format_jobs + 1 M.format( vim.tbl_deep_extend("force", format_args, { buf = args.buf, async = true, }), function(err) + num_running_format_jobs = num_running_format_jobs - 1 if not err and vim.api.nvim_buf_is_valid(args.buf) then vim.api.nvim_buf_call(args.buf, function() vim.b[args.buf].conform_applying_formatting = true @@ -139,6 +144,36 @@ M.setup = function(opts) end end, }) + + vim.api.nvim_create_autocmd("BufWinLeave", { + pattern = "*", + group = aug, + callback = function(args) + -- We store this because when vim is exiting it will set changedtick = -1 for visible + -- buffers right after firing BufWinLeave + vim.b[args.buf].last_changedtick = vim.api.nvim_buf_get_changedtick(args.buf) + end, + }) + + vim.api.nvim_create_autocmd("VimLeavePre", { + pattern = "*", + group = aug, + callback = function() + if num_running_format_jobs == 0 then + return + end + local uv = vim.uv or vim.loop + local start = uv.hrtime() / 1e6 + vim.wait(exit_timeout, function() + return num_running_format_jobs == 0 + end, 10) + local elapsed = uv.hrtime() / 1e6 - start + if elapsed > 200 then + local log = require("conform.log") + log.warn("Delayed Neovim exit by %dms to wait for formatting to complete", elapsed) + end + end, + }) end vim.api.nvim_create_user_command("ConformInfo", function() diff --git a/lua/conform/runner.lua b/lua/conform/runner.lua index e162b38..33429e9 100644 --- a/lua/conform/runner.lua +++ b/lua/conform/runner.lua @@ -457,8 +457,14 @@ M.format_async = function(bufnr, formatters, range, callback) local function run_next_formatter() local formatter = formatters[idx] if not formatter then + local new_changedtick = vim.b[bufnr].changedtick + -- changedtick gets set to -1 when vim is exiting. We have an autocmd that should store it in + -- last_changedtick before it is set to -1. + if new_changedtick == -1 then + new_changedtick = vim.b[bufnr].last_changedtick or -1 + end -- discard formatting if buffer has changed - if not vim.api.nvim_buf_is_valid(bufnr) or vim.b[bufnr].changedtick ~= changedtick then + if not vim.api.nvim_buf_is_valid(bufnr) or changedtick ~= new_changedtick then callback({ code = M.ERROR_CODE.CONCURRENT_MODIFICATION, message = string.format( |