Last active
June 19, 2024 13:36
-
-
Save iamgideonidoko/814ea1d0f535bf8aba2b2084b773c564 to your computer and use it in GitHub Desktop.
Smartly close Neovim buffer without closings the window it's in.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| local function get_loaded_buffers() | |
| local result = {} | |
| local buffers = vim.api.nvim_list_bufs() | |
| for _, buf in ipairs(buffers) do | |
| if vim.api.nvim_buf_is_loaded(buf) then | |
| table.insert(result, buf) | |
| end | |
| end | |
| return result | |
| end | |
| -- Delete a buffer without closing splits | |
| -- Switch a loaded alt buffer | |
| local function smart_close_buffer(force) | |
| local bufnr = vim.api.nvim_get_current_buf() | |
| if not force and vim.api.nvim_buf_get_option(bufnr, "modified") then | |
| return vim.api.nvim_err_writeln("Buffer is modified. Force required.") | |
| end | |
| -- Alternate bufnr | |
| ---@diagnostic disable: param-type-mismatch | |
| local alt_bufnr = vim.fn.bufnr("#") | |
| local alt_bufnr_active = alt_bufnr ~= -1 and vim.fn.bufloaded(alt_bufnr) == 1 | |
| -- Next bufnr | |
| local loaded_buffers = get_loaded_buffers() | |
| local next_bufnr = nil | |
| local found_current = false | |
| for _, buf in ipairs(loaded_buffers) do | |
| if found_current then | |
| next_bufnr = buf | |
| break | |
| end | |
| if buf == bufnr then | |
| found_current = true | |
| end | |
| end | |
| if #loaded_buffers > 1 and not next_bufnr then | |
| -- The next loaded buffer is likely the first | |
| for _, buf in ipairs(loaded_buffers) do | |
| next_bufnr = buf | |
| break | |
| end | |
| end | |
| -- Loop through all windows that is displaying the current buffer | |
| for _, win in ipairs(vim.fn.win_findbuf(bufnr)) do | |
| if alt_bufnr_active then | |
| vim.api.nvim_win_set_buf(win, alt_bufnr) | |
| elseif next_bufnr then | |
| vim.api.nvim_win_set_buf(win, next_bufnr) | |
| else | |
| -- Set window buffer to a new empty buffer | |
| vim.api.nvim_win_set_buf(win, vim.api.nvim_create_buf(false, true)) | |
| end | |
| end | |
| -- Finally, delete the original buffer | |
| vim.api.nvim_buf_delete(bufnr, { force = force }) | |
| end | |
| vim.keymap.set("n", "<leader>x", smart_close_buffer, { desc = "Close current buffer" }) | |
| vim.keymap.set("n", "<leader>X", function() | |
| smart_close_buffer(true) | |
| end, { desc = "Force close current buffer" }) | |
| -- vim: ts=2 sts=2 sw=2 et |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment