local U = {} U.map = function(mode, lhs, rhs, opts) local options = { noremap = true, silent = true } if opts then options = vim.tbl_extend("force", options, opts) end vim.api.nvim_set_keymap(mode, lhs, rhs, options) end U.close_buffer = function(force) -- Yanked from NvChad, thanks to them. This saves -- a lot of pain -- This is a modification of a NeoVim plugin from -- Author: ojroques - Olivier Roques -- Src: https://github.com/ojroques/nvim-bufdel -- Options local opts = { next = "cycle", -- how to retrieve the next buffer quit = false, -- exit when last buffer is deleted --TODO make this a chadrc flag/option } -- ---------------- -- Helper functions -- ---------------- -- Switch to buffer 'buf' on each window from list 'windows' local function switch_buffer(windows, buf) local cur_win = vim.fn.winnr() for _, winid in ipairs(windows) do vim.cmd(string.format("%d wincmd w", vim.fn.win_id2win(winid))) vim.cmd(string.format("buffer %d", buf)) end vim.cmd(string.format("%d wincmd w", cur_win)) -- return to original window end -- Select the first buffer with a number greater than given buffer local function get_next_buf(buf) local next = vim.fn.bufnr("#") if opts.next == "alternate" and vim.fn.buflisted(next) == 1 then return next end for i = 0, vim.fn.bufnr("$") - 1 do next = (buf + i) % vim.fn.bufnr("$") + 1 -- will loop back to 1 if vim.fn.buflisted(next) == 1 then return next end end end -- ---------------- -- End helper functions -- ---------------- local buf = vim.fn.bufnr() if vim.fn.buflisted(buf) == 0 then -- exit if buffer number is invalid vim.cmd("close") return end if #vim.fn.getbufinfo({ buflisted = 1 }) < 2 then if opts.quit then -- exit when there is only one buffer left if force then vim.cmd("qall!") else vim.cmd("confirm qall") end return end local chad_term, _ = pcall(function() return vim.api.nvim_buf_get_var(buf, "term_type") end) if chad_term then -- Must be a window type vim.cmd(string.format("setlocal nobl", buf)) vim.cmd("enew") return end -- don't exit and create a new empty buffer vim.cmd("enew") vim.cmd("bp") end local next_buf = get_next_buf(buf) local windows = vim.fn.getbufinfo(buf)[1].windows -- force deletion of terminal buffers to avoid the prompt if force or vim.fn.getbufvar(buf, "&buftype") == "terminal" then local chad_term, type = pcall(function() return vim.api.nvim_buf_get_var(buf, "term_type") end) -- TODO this scope is error prone, make resilient if chad_term then if type == "wind" then -- hide from bufferline vim.cmd(string.format("%d bufdo setlocal nobl", buf)) -- swtich to another buff -- TODO switch to next bufffer, this works too vim.cmd("BufferLineCycleNext") else local cur_win = vim.fn.winnr() -- we can close this window vim.cmd(string.format("%d wincmd c", cur_win)) return end else switch_buffer(windows, next_buf) vim.cmd(string.format("bd! %d", buf)) end else switch_buffer(windows, next_buf) vim.cmd(string.format("silent! confirm bd %d", buf)) end -- revert buffer switches if user has canceled deletion if vim.fn.buflisted(buf) == 1 then switch_buffer(windows, buf) end end return U