diff --git a/README.md b/README.md index 8b1d0d3..141bea7 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,8 @@ require("sos").setup { -- open an older version of a file in another application/Neovim instance, -- although in that case you're probably better off disabling autosaving -- altogether (or keep it enabled but utilize a VCS to get the version you - -- need - that is, if you commit frequently enough). + -- need - that is, if you commit frequently enough). This option also enables + -- saving on suspend. save_on_focuslost = true, -- Predicate fn which receives a buf number and should return true if it diff --git a/lua/sos/_test/util.lua b/lua/sos/_test/util.lua index cf4ac70..cb4eb87 100644 --- a/lua/sos/_test/util.lua +++ b/lua/sos/_test/util.lua @@ -307,6 +307,17 @@ function M.start_nvim(opts) vim.fn.jobstop(jobid) end + function self:exec_lua(f, args) + if type(f) == "string" then + return self:req("nvim_exec_lua", f, args or {}) + end + return self:req( + "nvim_exec_lua", + ("return assert(loadstring(%q))(...)"):format(string.dump(f)), + args or {} + ) + end + setmetatable(self, { __index = function(_, key) return M[key] diff --git a/lua/sos/autocmds.lua b/lua/sos/autocmds.lua index dd47ba1..db424d1 100644 --- a/lua/sos/autocmds.lua +++ b/lua/sos/autocmds.lua @@ -60,6 +60,17 @@ function M.refresh(cfg) group = augroup, pattern = "*", desc = "Save all buffers when Neovim loses focus", + nested = true, + callback = function(_info) + cfg.on_timer() + end, + }) + + api.nvim_create_autocmd("VimSuspend", { + group = augroup, + pattern = "*", + desc = "Save all buffers when Neovim is suspended", + nested = true, callback = function(_info) cfg.on_timer() end, diff --git a/lua/sos/config.lua b/lua/sos/config.lua index 06317a6..98a1edc 100644 --- a/lua/sos/config.lua +++ b/lua/sos/config.lua @@ -4,7 +4,7 @@ ---@field autowrite boolean | "all" | nil # Set and manage Vim's 'autowrite' option. ---@field save_on_cmd "all" | "some" | table | false | nil # Save all buffers before executing a command on cmdline ---@field save_on_bufleave boolean | nil # Save current buffer on `BufLeave` (see `:h BufLeave`) ----@field save_on_focuslost boolean | nil # Save all bufs when Neovim loses focus. +---@field save_on_focuslost boolean | nil # Save all bufs when Neovim loses focus or is suspended. ---@field should_observe_buf nil | fun(buf: integer): boolean # Return true to observe/attach to buf. ---@field on_timer function # The function to call when the timer fires. local defaults = { diff --git a/tests/suspend_spec.lua b/tests/suspend_spec.lua index 63b81e4..7ee5b11 100644 --- a/tests/suspend_spec.lua +++ b/tests/suspend_spec.lua @@ -246,4 +246,31 @@ describe("sos.nvim", function() nvim:set_current_tabpage(tab) -- trigger sos to check file times (which triggers autoread) assert.are.same({ "new new new" }, nvim:buf_get_lines(0, 0, -1, true)) end) + + it("should save all bufs on suspend", function() + util.with_nvim({ + xargs = { + "-u", + "tests/min_init.lua", + }, + }, function(nvim) + local tmp_a = util.tmpfile() + local tmp_b = util.tmpfile() + nvim:set_option("awa", false) + nvim:set_option("aw", false) + nvim:set_option("hidden", true) + nvim:silent_edit(tmp_a) + nvim:buf_set_lines(0, 0, -1, true, { "changes" }) + nvim:silent_edit(tmp_b) + nvim:buf_set_lines(0, 0, -1, true, { "changes" }) + nvim:exec_lua(function() + return require("sos").setup { enabled = true, timeout = 9e6 } + end) + sleep(200) + nvim:suspend() + sleep(200) + assert.is.True(util.file_exists(tmp_a)) + assert.is.True(util.file_exists(tmp_b)) + end) + end) end)