diff --git a/CHANGELOG.md b/CHANGELOG.md index e7e55c3..99d5f76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.1.2] - 2026-04-12 + +### Fixed + +- `BufWritePre` formatters (e.g. conform.nvim format-on-save) now run on + autosave. The trigger autocmd now uses `nested = true`, so the `:write` + invoked from inside the `InsertLeave` / `TextChanged` / `FocusLost` + handler fires nested autocmds (see `:help autocmd-nested`). + +### Changed + +- Skip saves for unmodified, unnamed, or special (`buftype`) buffers instead + of always attempting a write. +- Drop `:wall` — autosave only writes the buffer the event fired on. +- Use `silent` (not `silent!`) so write errors surface instead of being + swallowed. + ## [0.1.1] - 2026-04-09 ### Fixed @@ -21,5 +38,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Configurable trigger events - Zero-config auto-loading via `plugin/` directory +[0.1.2]: https://github.com/swaits/tiny-autosave.nvim/releases/tag/v0.1.2 [0.1.1]: https://github.com/swaits/tiny-autosave.nvim/releases/tag/v0.1.1 [0.1.0]: https://github.com/swaits/tiny-autosave.nvim/releases/tag/v0.1.0 diff --git a/lua/tiny-autosave/init.lua b/lua/tiny-autosave/init.lua index 353ffa2..f5acd83 100644 --- a/lua/tiny-autosave/init.lua +++ b/lua/tiny-autosave/init.lua @@ -9,13 +9,22 @@ function M.setup(opts) vim.api.nvim_create_autocmd(events, { group = vim.api.nvim_create_augroup("tiny-autosave", { clear = true }), - callback = function() - local name = vim.api.nvim_buf_get_name(0) - if name ~= "" and vim.fn.filereadable(name) == 0 then + nested = true, + callback = function(args) + local buf = args.buf + if vim.bo[buf].buftype ~= "" or not vim.bo[buf].modified then + return + end + local name = vim.api.nvim_buf_get_name(buf) + if name == "" then + return + end + if vim.fn.filereadable(name) == 0 then vim.fn.mkdir(vim.fn.fnamemodify(name, ":p:h"), "p") end - vim.cmd("silent! write") - vim.cmd("silent! wall") + vim.api.nvim_buf_call(buf, function() + vim.cmd("silent keepalt keepjumps write") + end) end, }) end diff --git a/tests/test_init.lua b/tests/test_init.lua index a37dfec..779a6da 100644 --- a/tests/test_init.lua +++ b/tests/test_init.lua @@ -21,4 +21,53 @@ T["setup"]["respects custom events"] = function() eq(#groups, 1) end +T["save"] = MiniTest.new_set() + +T["save"]["fires BufWritePre once and applies formatter changes"] = function() + require("tiny-autosave").setup() + local tmp = vim.fn.tempname() .. ".txt" + vim.cmd("edit " .. tmp) + local buf = vim.api.nvim_get_current_buf() + local pre_count = 0 + vim.api.nvim_create_autocmd("BufWritePre", { + buffer = buf, + callback = function() + pre_count = pre_count + 1 + vim.api.nvim_buf_set_lines(buf, 0, -1, false, { "formatted" }) + end, + }) + vim.api.nvim_buf_set_lines(buf, 0, -1, false, { "original", "", "", "" }) + vim.api.nvim_exec_autocmds("InsertLeave", { buffer = buf }) + eq(pre_count, 1) + eq(vim.fn.readfile(tmp), { "formatted" }) + os.remove(tmp) +end + +T["save"]["skips unnamed buffers"] = function() + require("tiny-autosave").setup() + vim.cmd("enew") + local buf = vim.api.nvim_get_current_buf() + vim.api.nvim_buf_set_lines(buf, 0, -1, false, { "scratch" }) + local ok = pcall(vim.api.nvim_exec_autocmds, "InsertLeave", {}) + eq(ok, true) +end + +T["save"]["skips unmodified buffers"] = function() + require("tiny-autosave").setup() + local tmp = vim.fn.tempname() .. ".txt" + vim.fn.writefile({ "hello" }, tmp) + vim.cmd("edit " .. tmp) + local buf = vim.api.nvim_get_current_buf() + local pre_count = 0 + vim.api.nvim_create_autocmd("BufWritePre", { + buffer = buf, + callback = function() + pre_count = pre_count + 1 + end, + }) + vim.api.nvim_exec_autocmds("InsertLeave", { buffer = buf }) + eq(pre_count, 0) + os.remove(tmp) +end + return T