diff options
author | Toby Vincent <tobyv13@gmail.com> | 2022-07-14 10:38:29 -0500 |
---|---|---|
committer | Toby Vincent <tobyv13@gmail.com> | 2022-07-14 10:38:29 -0500 |
commit | 431e8bd814fd0385f3fb272d888fa649475ae39d (patch) | |
tree | eb21e2471b99382d825e127f19389b1dd54aae46 | |
parent | a3c640de64882b4ce3cc7564336351dab427a94c (diff) |
feat(nvim): implement minimal bdelete wrapper and pre/post autocmds
-rw-r--r-- | nvim/.config/nvim/lua/tobyvin/autocommands.lua | 34 | ||||
-rw-r--r-- | nvim/.config/nvim/lua/tobyvin/mappings.lua | 2 | ||||
-rw-r--r-- | nvim/.config/nvim/lua/tobyvin/utils.lua | 42 | ||||
-rw-r--r-- | nvim/.config/nvim/lua/tobyvin/utils/bdelete.lua | 95 |
4 files changed, 71 insertions, 102 deletions
diff --git a/nvim/.config/nvim/lua/tobyvin/autocommands.lua b/nvim/.config/nvim/lua/tobyvin/autocommands.lua index 17c109b..b626c91 100644 --- a/nvim/.config/nvim/lua/tobyvin/autocommands.lua +++ b/nvim/.config/nvim/lua/tobyvin/autocommands.lua @@ -1,6 +1,40 @@ local M = {} M.setup = function() + local augroup_user = vim.api.nvim_create_augroup("Default", { clear = true }) + + vim.api.nvim_create_autocmd("User", { + group = augroup_user, + pattern = "BDeletePre", + callback = function(opts) + local windows = vim.tbl_filter(function(win) + return vim.api.nvim_win_get_buf(win) == opts.bufnr + end, vim.api.nvim_list_wins()) + + local buffers = vim.tbl_filter(function(buf) + return vim.api.nvim_buf_is_valid(buf) and vim.bo[buf].buflisted + end, vim.api.nvim_list_bufs()) + + if buffers ~= nil and #buffers > 1 then + local next_buffer = vim.fn.winbufnr(vim.fn.winnr("#")) + + if not next_buffer then + for i, v in ipairs(buffers) do + if v == opts.bufnr then + next_buffer = buffers[i % #buffers + 1] + break + end + end + end + + for _, win in ipairs(windows) do + vim.api.nvim_win_set_buf(win, next_buffer) + end + end + end, + desc = "BDeletePre", + }) + local augroup_default = vim.api.nvim_create_augroup("Default", { clear = true }) vim.api.nvim_create_autocmd("TextYankPost", { diff --git a/nvim/.config/nvim/lua/tobyvin/mappings.lua b/nvim/.config/nvim/lua/tobyvin/mappings.lua index 151fa52..8e916d3 100644 --- a/nvim/.config/nvim/lua/tobyvin/mappings.lua +++ b/nvim/.config/nvim/lua/tobyvin/mappings.lua @@ -23,7 +23,7 @@ M.close = function() end M.close_force = function() - utils.bdelete(true) + utils.bdelete({ force = true }) -- vim.cmd("bdelete!") end diff --git a/nvim/.config/nvim/lua/tobyvin/utils.lua b/nvim/.config/nvim/lua/tobyvin/utils.lua index 97a7504..b65d1cb 100644 --- a/nvim/.config/nvim/lua/tobyvin/utils.lua +++ b/nvim/.config/nvim/lua/tobyvin/utils.lua @@ -1,10 +1,40 @@ -local bdelete = require("tobyvin.utils.bdelete") -bdelete.setup() +local M = {} + +--- Wrapper for bdelete/bwipeout to add a write/discard modified selection and fire autocmd event +---@param opts ?BdeleteOpts +---@return nil +M.bdelete = function(opts) + ---@class BdeleteOpts + ---@field bufnr number Number of the buffer to target + ---@field force boolean Discard modified buffer + ---@field wipeout boolean Wipeout buffer + opts = opts or {} + + if opts.bufnr == nil or opts.bufnr == 0 then + opts.bufnr = vim.api.nvim_get_current_buf() + end -local M = { - bdelete = bdelete.bdelete, - bwipeout = bdelete.bwipeout, -} + if not opts.force and vim.bo[opts.bufnr].modified then + vim.ui.select({ "write", "discard", "abort" }, { + prompt = string.format("No write since last change for buffer %d:", opts.bufnr), + }, function(n) + if n == 1 then + vim.cmd("write") + elseif n == 2 then + opts.force = true + end + end) + end + + local cmd = opts.wipeout and "wipeout" or "bdelete" .. opts.force and "!" or "" + + vim.api.nvim_exec_autocmds("User", { pattern = "BDeletePre", data = opts }) + + if vim.api.nvim_buf_is_valid(opts.bufnr) then + vim.cmd(string.format("%s %d", cmd, opts.bufnr)) + vim.api.nvim_exec_autocmds("User", { pattern = "BDeletePost", data = opts }) + end +end M.spinner_frames = { "⣷", "⣯", "⣟", "⡿", "⢿", "⣻", "⣽", "⣾" } diff --git a/nvim/.config/nvim/lua/tobyvin/utils/bdelete.lua b/nvim/.config/nvim/lua/tobyvin/utils/bdelete.lua deleted file mode 100644 index 84cd6d8..0000000 --- a/nvim/.config/nvim/lua/tobyvin/utils/bdelete.lua +++ /dev/null @@ -1,95 +0,0 @@ -local M = {} - --- Common kill function for bdelete and bwipeout -M._bdelete = function(wipeout, bufnr, force) - -- If buffer is modified and force isn't true, print error and abort - - if type(bufnr) == "boolean" and force == nil then - force = bufnr - bufnr = nil - end - - if bufnr == 0 or bufnr == nil then - bufnr = vim.api.nvim_get_current_buf() - end - - local base_cmd = "bdelete" - - if wipeout then - base_cmd = "bwipeout" - end - - local cmd - if not force and vim.bo[bufnr].modified then - vim.ui.select({ "write", "discard" }, { - prompt = string.format("No write since last change for buffer %d:", bufnr), - }, function(n) - if n == 1 then - vim.cmd("write") - cmd = base_cmd - elseif n == 2 then - cmd = base_cmd .. "!" - else - vim.notify("[bdelete] Aborting...") - end - end) - end - - if not cmd then - return - end - - -- Get list of windows IDs with the buffer to close - local windows = vim.tbl_filter(function(win) - return vim.api.nvim_win_get_buf(win) == bufnr - end, vim.api.nvim_list_wins()) - - -- Get list of valid and listed buffers - local buffers = vim.tbl_filter(function(buf) - return vim.api.nvim_buf_is_valid(buf) and vim.bo[buf].buflisted - end, vim.api.nvim_list_bufs()) - - -- If there is only one buffer (which has to be the current one), Neovim will automatically - -- create a new buffer on :bd. - -- For more than one buffer, pick the next buffer (wrapping around if necessary) - if buffers ~= nil and #buffers > 1 then - local next_buffer = vim.fn.winbufnr(vim.fn.winnr("#")) - - if not next_buffer then - for i, v in ipairs(buffers) do - if v == bufnr then - next_buffer = buffers[i % #buffers + 1] - break - end - end - end - - for _, win in ipairs(windows) do - vim.api.nvim_win_set_buf(win, next_buffer) - end - end - - -- Check if buffer still exists, to ensure the target buffer wasn't killed - -- due to options like bufhidden=wipe. - if vim.api.nvim_buf_is_valid(bufnr) then - -- Execute the BDeletePre and BDeletePost autocommands before and after deleting the buffer - vim.api.nvim_exec_autocmds("User", { pattern = "BDeletePre" }) - vim.cmd(string.format("%s %d", cmd, bufnr)) - vim.api.nvim_exec_autocmds("User", { pattern = "BDeletePost" }) - end -end - -M.bdelete = function(...) - M._bdelete(false, ...) -end - -M.bwipeout = function(...) - M._bdelete(true, ...) -end - -M.setup = function() - vim.api.nvim_create_user_command("Bdelete", M.bdelete, { nargs = "?", bang = true, desc = "Bdelete" }) - vim.api.nvim_create_user_command("Bwipeout", M.bwipeout, { nargs = "?", bang = true, desc = "Bwipeout" }) -end - -return M |