From 29bac037b3a35b2adf15c847ae38cf8b9d0a8c5f Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Tue, 13 Oct 2026 18:27:45 -0400 Subject: [PATCH] feat(plugins): add close_win and save_close_buf helpers and update mappings for conditional save/close behavior --- lua/plugins/astrocore.lua | 56 +++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/lua/plugins/astrocore.lua b/lua/plugins/astrocore.lua index 54ef8ac..8732000 100644 --- a/lua/plugins/astrocore.lua +++ b/lua/plugins/astrocore.lua @@ -6,6 +6,21 @@ local ignore_patterns = require "config.ignore_patterns" local file_filter = ignore_patterns.create_picker_filter() +-- : close the window; only quit (saving all) when it's the last one +local function close_win() + local ok, err = pcall(vim.cmd.close) + if ok then return end + -- E444: last window; E5601: only floating windows would remain + if not tostring(err):find "E444" and not tostring(err):find "E5601" then error(err, 0) end + vim.cmd "wqa" +end + +-- : save the current buffer only if it has unsaved changes, then close it +local function save_close_buf() + if vim.bo.buftype == "" then vim.cmd "update" end + require("snacks").bufdelete() +end + -- e: two-stage find-by-extension. Stage 1 scans the repo with fd -- (respects .gitignore) and shows every file extension ranked by count; -- stage 2 opens fff prefilled with a `*. ` glob constraint so the @@ -231,18 +246,11 @@ return { mappings = { n = { - -- overrides AstroNvim's default = force quit (:q!) - [""] = { "wqa", desc = "Save all buffers and quit Neovim" }, + [""] = { close_win, desc = "Close window (quit if last)" }, [""] = { "suspend", desc = "Suspend nvim (return with 'fg')" }, ["ZZ"] = { "wqa", desc = "Save all buffers and quit Neovim" }, [""] = { "wqa", desc = "Save all buffers and quit Neovim" }, - [""] = { - function() - vim.cmd "wa" - require("snacks").bufdelete() - end, - desc = "Save and close buffer", - }, + [""] = { save_close_buf, desc = "Save (if modified) and close buffer" }, ["F"] = { "za", desc = "Toggle fold under cursor" }, -- v6: vim.diagnostic.goto_next/goto_prev deprecated in 0.11, use jump() ["J"] = { @@ -296,14 +304,17 @@ return { desc = "Find in line", }, ["o"] = { function() require("snacks").gitbrowse() end, desc = "Open Repo on Web" }, - [""] = { "w", desc = "Save buffer" }, - [""] = { + [""] = { function() - vim.cmd "w" - require("snacks").bufdelete() + if vim.bo.modified and vim.bo.buftype == "" then + vim.cmd "write" + else + require("snacks").picker.buffers() + end end, - desc = "Save and close buffer", + desc = "Save if modified, else find buffers", }, + [""] = { "w", desc = "Save buffer" }, [""] = { "tabnext", desc = "Next Tab" }, [""] = { function() require("snacks").picker.gh_issue() end, @@ -490,10 +501,9 @@ return { [""] = { function() vim.cmd "stopinsert" - vim.cmd "wa" - require("snacks").bufdelete() + save_close_buf() end, - desc = "Save, close buffer, and return to normal mode", + desc = "Save (if modified), close buffer, and return to normal mode", }, [""] = { function() @@ -505,13 +515,7 @@ return { }, }, v = { - [""] = { - function() - vim.cmd "w" - require("snacks").bufdelete() - end, - desc = "Save and close buffer", - }, + [""] = { save_close_buf, desc = "Save (if modified) and close buffer" }, [""] = { function() vim.cmd "w" @@ -568,9 +572,9 @@ return { [""] = { function() vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes([[]], true, false, true), "n", false) - vim.cmd "close" + close_win() end, - desc = "Exit terminal and close window", + desc = "Exit terminal and close window (quit if last)", }, }, },