Line data Source code
1 : -- lua/yoda/commands/buffer.lua
2 : -- Buffer management commands
3 : --
4 : -- Provides :Bd / :BD — smart buffer delete that preserves window layout.
5 : -- Regular :bdelete closes the window when the buffer is the last one visible;
6 : -- :Bd instead switches each window showing the buffer to an alternate buffer
7 : -- first, so the window layout survives. Falls back to :bdelete for
8 : -- non-normal buffer types (e.g. terminals, quickfix) where the simple
9 : -- behaviour is fine.
10 :
11 1 : local M = {}
12 :
13 1 : function M.setup()
14 22 : vim.api.nvim_create_user_command("Bd", function(opts)
15 : local buf = vim.api.nvim_get_current_buf()
16 : local window_protection = require("yoda-window.protection")
17 :
18 : if vim.bo[buf].buftype ~= "" then
19 : vim.cmd("bdelete" .. (opts.bang and "!" or ""))
20 : return
21 : end
22 :
23 : local windows_with_buf = vim.fn.win_findbuf(buf)
24 :
25 : local normal_buffers = {}
26 : for _, b in ipairs(vim.api.nvim_list_bufs()) do
27 : if vim.api.nvim_buf_is_valid(b) and b ~= buf and vim.bo[b].buflisted and vim.bo[b].buftype == "" then
28 : table.insert(normal_buffers, b)
29 : end
30 : end
31 :
32 : if #normal_buffers > 0 then
33 : local alt = vim.fn.bufnr("#")
34 : local target_buf
35 :
36 : if alt ~= -1 and alt ~= buf and vim.api.nvim_buf_is_valid(alt) and vim.bo[alt].buftype == "" then
37 : target_buf = alt
38 : else
39 : target_buf = normal_buffers[1]
40 : end
41 :
42 : for _, win in ipairs(windows_with_buf) do
43 : if vim.api.nvim_win_is_valid(win) then
44 : if window_protection.is_buffer_switch_allowed(win, target_buf) then
45 : pcall(vim.api.nvim_win_set_buf, win, target_buf)
46 : end
47 : end
48 : end
49 : end
50 :
51 : local delete_cmd = "bdelete" .. (opts.bang and "!" or "") .. " " .. buf
52 :
53 : local ok_delete, err = pcall(vim.cmd, delete_cmd)
54 : if not ok_delete then
55 : require("yoda-adapters.notification").notify("Buffer delete failed: " .. tostring(err), "error")
56 : end
57 11 : end, { bang = true, desc = "Smart buffer delete that preserves window layout" })
58 :
59 22 : vim.api.nvim_create_user_command("BD", function(opts)
60 : vim.cmd("Bd" .. (opts.bang and "!" or ""))
61 11 : end, { bang = true, desc = "Alias for Bd" })
62 :
63 22 : vim.cmd([[
64 : cnoreabbrev <expr> bd getcmdtype() == ':' && getcmdline() == 'bd' ? 'Bd' : 'bd'
65 : cnoreabbrev <expr> bdelete getcmdtype() == ':' && getcmdline() == 'bdelete' ? 'Bd' : 'bdelete'
66 11 : ]])
67 12 : end
68 :
69 1 : return M
|