diff --git a/README.md b/README.md index 1329737..5ff468f 100644 --- a/README.md +++ b/README.md @@ -103,33 +103,65 @@ EOF defer_save = { "InsertLeave", "TextChanged" }, -- vim events that trigger a deferred save (saves after `debounce_delay`) cancel_defered_save = { "InsertEnter" }, -- vim events that cancel a pending deferred save }, - -- function that determines whether to save the current buffer or not + -- function that takes the buffer handle and determines whether to save the current buffer or not -- return true: if buffer is ok to be saved -- return false: if it's not ok to be saved - condition = function(buf) - local fn = vim.fn - local utils = require("auto-save.utils.data") - - if - fn.getbufvar(buf, "&modifiable") == 1 and - utils.not_in(fn.getbufvar(buf, "&filetype"), {}) then - return true -- met condition(s), can save - end - return false -- can't save - end, + -- if set to `nil` then no specific condition is applied + condition = nil, write_all_buffers = false, -- write all buffers when the current one meets `condition` debounce_delay = 1000, -- delay after which a pending save is executed callbacks = { -- functions to be executed at different intervals enabling = nil, -- ran when enabling auto-save disabling = nil, -- ran when disabling auto-save - before_asserting_save = nil, -- ran before checking `condition` before_saving = nil, -- ran before doing the actual save after_saving = nil -- ran after doing the actual save } } ``` -Additionally you may want to set up a key mapping to toggle auto-save: +#### Condition +The condition field of the configuration allows the user to exclude **auto-save** from saving specific buffers. + +Here is an example using a helper function from `auto-save.utils.data` that disables auto-save for specified file types: +```lua +{ + condition = function(buf) + local fn = vim.fn + local utils = require("auto-save.utils.data") + + -- don't save for `sql` file types + if utils.not_in(fn.getbufvar(buf, "&filetype"), {'sql'}) then + return true + end + return false + end +} +``` + +You may also exclude `special-buffers` see (`:h buftype` and `:h special-buffers`): +```lua +{ + condition = function(buf) + local fn = vim.fn + + -- don't save for special-buffers + if fn.getbufvar(buf, "&buftype") ~= '' then + return false + end + return true + end +} +``` + +Buffers that are `nomodifiable` are not saved by default. + +### 🪴 Usage + +Besides running auto-save at startup (if you have `enabled = true` in your config), you may as well: + +- `ASToggle`: toggle auto-save + +You may want to set up a key mapping for toggling: ```lua vim.api.nvim_set_keymap("n", "n", ":ASToggle", {}) @@ -148,11 +180,6 @@ or as part of the `lazy.nvim` plugin spec: ``` -### 🪴 Usage - -Besides running auto-save at startup (if you have `enabled = true` in your config), you may as well: - -- `ASToggle`: toggle auto-save ### 🤝 Contributing diff --git a/lua/auto-save/config.lua b/lua/auto-save/config.lua index 94af8fe..6f9ff6e 100644 --- a/lua/auto-save/config.lua +++ b/lua/auto-save/config.lua @@ -11,27 +11,19 @@ Config = { }, trigger_events = { -- See :h events immediate_save = { "BufLeave", "FocusLost" }, -- vim events that trigger an immediate save - defer_save = { "InsertLeave", "TextChanged" }, -- vim events that trigger a deferred save (saves after `debounce_delay`) - cancel_defered_save = { "InsertEnter" }, -- vim events that cancel a pending deferred save + defer_save = { "InsertLeave", "TextChanged" }, -- vim events that trigger a deferred save (saves after `debounce_delay`) + cancel_defered_save = { "InsertEnter" }, -- vim events that cancel a pending deferred save }, - -- function that determines whether to save the current buffer or not + -- function that takes the buffer handle and determines whether to save the current buffer or not -- return true: if buffer is ok to be saved -- return false: if it's not ok to be saved - condition = function(buf) - local fn = vim.fn - local utils = require("auto-save.utils.data") - - if fn.getbufvar(buf, "&modifiable") == 1 and utils.not_in(fn.getbufvar(buf, "&filetype"), {}) then - return true -- met condition(s), can save - end - return false -- can't save - end, + -- if set to `nil` then no specific condition is applied + condition = nil, write_all_buffers = false, -- write all buffers when the current one meets `condition` debounce_delay = 1000, -- delay after which a pending save is executed callbacks = { -- functions to be executed at different intervals enabling = nil, -- ran when enabling auto-save disabling = nil, -- ran when disabling auto-save - before_asserting_save = nil, -- ran before checking `condition` before_saving = nil, -- ran before doing the actual save after_saving = nil, -- ran after doing the actual save }, diff --git a/lua/auto-save/init.lua b/lua/auto-save/init.lua index 2475dc6..e825751 100644 --- a/lua/auto-save/init.lua +++ b/lua/auto-save/init.lua @@ -52,13 +52,22 @@ local function echo_execution_message() end end -local function save(buf) - callback("before_asserting_save") - - if cnf.opts.condition(buf) == false then - return +--- Determines if the given buffer is modifiable and if the condition from the config yields true for it +--- @param buf number +--- @return boolean +local function should_be_saved(buf) + if fn.getbufvar(buf, "&modifiable") ~= 1 then + return false end + if cnf.opts.condition ~= nil then + return cnf.opts.condition(buf) + end + + return true +end + +local function save(buf) if not api.nvim_buf_get_option(buf, "modified") then return end @@ -86,19 +95,13 @@ local function save(buf) end end -function M.immediate_save(buf) - buf = buf or api.nvim_get_current_buf() - cancel_timer(buf) - save(buf) +local function immediate_save(buf) + cancel_timer(buf) + save(buf) end - local save_func = nil local function defer_save(buf) - -- why is this needed? auto_save_abort is never set to true anyways? - -- TODO: remove? - g.auto_save_abort = false - -- is it really needed to cache this function -- TODO: remove? if save_func == nil then @@ -109,25 +112,31 @@ end function M.on() api.nvim_create_autocmd(cnf.opts.trigger_events.immediate_save, { - callback = function (opts) - M.immediate_save(opts.buf) + callback = function(opts) + if should_be_saved(opts.buf) then + immediate_save(opts.buf) + end end, group = "AutoSave", - desc = "Immediately save a buffer" + desc = "Immediately save a buffer", }) api.nvim_create_autocmd(cnf.opts.trigger_events.defer_save, { callback = function(opts) - defer_save(opts.buf) + if should_be_saved(opts.buf) then + defer_save(opts.buf) + end end, group = "AutoSave", - desc = "Save a buffer after the `debounce_delay`" + desc = "Save a buffer after the `debounce_delay`", }) api.nvim_create_autocmd(cnf.opts.trigger_events.cancel_defered_save, { - callback = function (opts) - cancel_timer(opts.buf) + callback = function(opts) + if should_be_saved(opts.buf) then + cancel_timer(opts.buf) + end end, group = "AutoSave", - desc = "Cancel a pending save timer for a buffer" + desc = "Cancel a pending save timer for a buffer", }) api.nvim_create_autocmd({ "VimEnter", "ColorScheme", "UIEnter" }, {