mirror of
https://github.com/folke/snacks.nvim
synced 2025-12-23 08:47:57 +00:00
feat(bufdelete): added wipe option. Closes #38
This commit is contained in:
parent
9b9777ec3b
commit
5914cb1010
3 changed files with 96 additions and 69 deletions
|
|
@ -3,7 +3,7 @@
|
|||
==============================================================================
|
||||
Table of Contents *snacks-bufdelete-table-of-contents*
|
||||
|
||||
1. Config |snacks-bufdelete-config|
|
||||
1. Types |snacks-bufdelete-types|
|
||||
2. Module |snacks-bufdelete-module|
|
||||
- Snacks.bufdelete() |snacks-bufdelete-module-snacks.bufdelete()|
|
||||
- Snacks.bufdelete.all() |snacks-bufdelete-module-snacks.bufdelete.all()|
|
||||
|
|
@ -16,15 +16,14 @@ discard.
|
|||
|
||||
|
||||
==============================================================================
|
||||
1. Config *snacks-bufdelete-config*
|
||||
1. Types *snacks-bufdelete-types*
|
||||
|
||||
>lua
|
||||
---@class snacks.bufdelete.Opts
|
||||
---@field buf? number Buffer to delete. If not provided, the current buffer is deleted
|
||||
---@field buf? number Buffer to delete. Defaults to the current buffer
|
||||
---@field force? boolean Delete the buffer even if it is modified
|
||||
---@field filter? fun(buf: number): boolean Filter buffers to delete
|
||||
---@field wipe? boolean Wipe the buffer instead of deleting it (see `:h :bwipeout`)
|
||||
{}
|
||||
<
|
||||
|
||||
|
||||
|
|
@ -35,7 +34,7 @@ discard.
|
|||
SNACKS.BUFDELETE() *snacks-bufdelete-module-snacks.bufdelete()*
|
||||
|
||||
>lua
|
||||
---@type fun(buf?: number)
|
||||
---@type fun(buf?: number|snacks.bufdelete.Opts)
|
||||
Snacks.bufdelete()
|
||||
<
|
||||
|
||||
|
|
@ -45,7 +44,8 @@ SNACKS.BUFDELETE.ALL() *snacks-bufdelete-module-snacks.bufdelete.all()*
|
|||
Delete all buffers
|
||||
|
||||
>lua
|
||||
Snacks.bufdelete.all()
|
||||
---@param opts? snacks.bufdelete.Opts
|
||||
Snacks.bufdelete.all(opts)
|
||||
<
|
||||
|
||||
|
||||
|
|
@ -56,8 +56,8 @@ buffer `buf` if it is a number - or every buffer for which `buf` returns true
|
|||
if it is a function
|
||||
|
||||
>lua
|
||||
---@param buf? number | fun(buf: number): boolean
|
||||
Snacks.bufdelete.delete(buf)
|
||||
---@param opts? number|snacks.bufdelete.Opts
|
||||
Snacks.bufdelete.delete(opts)
|
||||
<
|
||||
|
||||
|
||||
|
|
@ -66,7 +66,8 @@ SNACKS.BUFDELETE.OTHER() *snacks-bufdelete-module-snacks.bufdelete.other()*
|
|||
Delete all buffers except the current one
|
||||
|
||||
>lua
|
||||
Snacks.bufdelete.other()
|
||||
---@param opts? snacks.bufdelete.Opts
|
||||
Snacks.bufdelete.other(opts)
|
||||
<
|
||||
|
||||
Generated by panvimdoc <https://github.com/kdheepak/panvimdoc>
|
||||
|
|
|
|||
|
|
@ -7,12 +7,22 @@ a prompt will be shown to save or discard.
|
|||
|
||||
<!-- docgen -->
|
||||
|
||||
## 📚 Types
|
||||
|
||||
```lua
|
||||
---@class snacks.bufdelete.Opts
|
||||
---@field buf? number Buffer to delete. Defaults to the current buffer
|
||||
---@field force? boolean Delete the buffer even if it is modified
|
||||
---@field filter? fun(buf: number): boolean Filter buffers to delete
|
||||
---@field wipe? boolean Wipe the buffer instead of deleting it (see `:h :bwipeout`)
|
||||
```
|
||||
|
||||
## 📦 Module
|
||||
|
||||
### `Snacks.bufdelete()`
|
||||
|
||||
```lua
|
||||
---@type fun(buf?: number)
|
||||
---@type fun(buf?: number|snacks.bufdelete.Opts)
|
||||
Snacks.bufdelete()
|
||||
```
|
||||
|
||||
|
|
@ -21,7 +31,8 @@ Snacks.bufdelete()
|
|||
Delete all buffers
|
||||
|
||||
```lua
|
||||
Snacks.bufdelete.all()
|
||||
---@param opts? snacks.bufdelete.Opts
|
||||
Snacks.bufdelete.all(opts)
|
||||
```
|
||||
|
||||
### `Snacks.bufdelete.delete()`
|
||||
|
|
@ -32,8 +43,8 @@ Delete a buffer:
|
|||
- or every buffer for which `buf` returns true if it is a function
|
||||
|
||||
```lua
|
||||
---@param buf? number | fun(buf: number): boolean
|
||||
Snacks.bufdelete.delete(buf)
|
||||
---@param opts? number|snacks.bufdelete.Opts
|
||||
Snacks.bufdelete.delete(opts)
|
||||
```
|
||||
|
||||
### `Snacks.bufdelete.other()`
|
||||
|
|
@ -41,5 +52,6 @@ Snacks.bufdelete.delete(buf)
|
|||
Delete all buffers except the current one
|
||||
|
||||
```lua
|
||||
Snacks.bufdelete.other()
|
||||
---@param opts? snacks.bufdelete.Opts
|
||||
Snacks.bufdelete.other(opts)
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,84 +1,98 @@
|
|||
---@class snacks.bufdelete
|
||||
---@overload fun(buf?: number)
|
||||
---@overload fun(buf?: number|snacks.bufdelete.Opts)
|
||||
local M = setmetatable({}, {
|
||||
__call = function(t, ...)
|
||||
return t.delete(...)
|
||||
end,
|
||||
})
|
||||
|
||||
---@class snacks.bufdelete.Opts
|
||||
---@field buf? number Buffer to delete. Defaults to the current buffer
|
||||
---@field force? boolean Delete the buffer even if it is modified
|
||||
---@field filter? fun(buf: number): boolean Filter buffers to delete
|
||||
---@field wipe? boolean Wipe the buffer instead of deleting it (see `:h :bwipeout`)
|
||||
|
||||
--- Delete a buffer:
|
||||
--- - either the current buffer if `buf` is not provided
|
||||
--- - or the buffer `buf` if it is a number
|
||||
--- - or every buffer for which `buf` returns true if it is a function
|
||||
---@param buf? number | fun(buf: number): boolean
|
||||
function M.delete(buf)
|
||||
if type(buf) == "function" then
|
||||
for _, b in ipairs(vim.api.nvim_list_bufs()) do
|
||||
if vim.bo[b].buflisted and buf(b) then
|
||||
M.delete(b)
|
||||
---@param opts? number|snacks.bufdelete.Opts
|
||||
function M.delete(opts)
|
||||
opts = opts or {}
|
||||
opts = type(opts) == "number" and { buf = opts } or opts
|
||||
opts = type(opts) == "function" and { filter = opts } or opts
|
||||
---@cast opts snacks.bufdelete.Opts
|
||||
|
||||
if type(opts.filter) == "function" then
|
||||
for _, b in ipairs(vim.tbl_filter(opts.filter, vim.api.nvim_list_bufs())) do
|
||||
if vim.bo[b].buflisted then
|
||||
M.delete(vim.tbl_extend("force", {}, opts, { buf = b, filter = false }))
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
buf = buf or 0
|
||||
local buf = opts.buf or 0
|
||||
buf = buf == 0 and vim.api.nvim_get_current_buf() or buf
|
||||
|
||||
-- Ensure we always run in the target buffer
|
||||
if buf ~= vim.api.nvim_get_current_buf() then
|
||||
return vim.api.nvim_buf_call(buf, M.delete)
|
||||
end
|
||||
|
||||
if vim.bo.modified then
|
||||
local choice = vim.fn.confirm(("Save changes to %q?"):format(vim.fn.bufname()), "&Yes\n&No\n&Cancel")
|
||||
if choice == 0 or choice == 3 then -- 0 for <Esc>/<C-c> and 3 for Cancel
|
||||
return
|
||||
vim.api.nvim_buf_call(buf, function()
|
||||
if vim.bo.modified and not opts.force then
|
||||
local choice = vim.fn.confirm(("Save changes to %q?"):format(vim.fn.bufname()), "&Yes\n&No\n&Cancel")
|
||||
if choice == 0 or choice == 3 then -- 0 for <Esc>/<C-c> and 3 for Cancel
|
||||
return
|
||||
end
|
||||
if choice == 1 then -- Yes
|
||||
vim.cmd.write()
|
||||
end
|
||||
end
|
||||
if choice == 1 then -- Yes
|
||||
vim.cmd.write()
|
||||
|
||||
for _, win in ipairs(vim.fn.win_findbuf(buf)) do
|
||||
vim.api.nvim_win_call(win, function()
|
||||
if not vim.api.nvim_win_is_valid(win) or vim.api.nvim_win_get_buf(win) ~= buf then
|
||||
return
|
||||
end
|
||||
-- Try using alternate buffer
|
||||
local alt = vim.fn.bufnr("#")
|
||||
if alt ~= buf and vim.fn.buflisted(alt) == 1 then
|
||||
vim.api.nvim_win_set_buf(win, alt)
|
||||
return
|
||||
end
|
||||
|
||||
-- Try using previous buffer
|
||||
local has_previous = pcall(vim.cmd, "bprevious")
|
||||
if has_previous and buf ~= vim.api.nvim_win_get_buf(win) then
|
||||
return
|
||||
end
|
||||
|
||||
-- Create new listed buffer
|
||||
local new_buf = vim.api.nvim_create_buf(true, false)
|
||||
vim.api.nvim_win_set_buf(win, new_buf)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
for _, win in ipairs(vim.fn.win_findbuf(buf)) do
|
||||
vim.api.nvim_win_call(win, function()
|
||||
if not vim.api.nvim_win_is_valid(win) or vim.api.nvim_win_get_buf(win) ~= buf then
|
||||
return
|
||||
end
|
||||
-- Try using alternate buffer
|
||||
local alt = vim.fn.bufnr("#")
|
||||
if alt ~= buf and vim.fn.buflisted(alt) == 1 then
|
||||
vim.api.nvim_win_set_buf(win, alt)
|
||||
return
|
||||
end
|
||||
|
||||
-- Try using previous buffer
|
||||
local has_previous = pcall(vim.cmd, "bprevious")
|
||||
if has_previous and buf ~= vim.api.nvim_win_get_buf(win) then
|
||||
return
|
||||
end
|
||||
|
||||
-- Create new listed buffer
|
||||
local new_buf = vim.api.nvim_create_buf(true, false)
|
||||
vim.api.nvim_win_set_buf(win, new_buf)
|
||||
end)
|
||||
end
|
||||
if vim.api.nvim_buf_is_valid(buf) then
|
||||
pcall(vim.cmd, "bdelete! " .. buf)
|
||||
end
|
||||
if vim.api.nvim_buf_is_valid(buf) then
|
||||
pcall(vim.cmd, opts.wipe and "bwipeout! " or "bdelete! " .. buf)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--- Delete all buffers
|
||||
function M.all()
|
||||
return M.delete(function()
|
||||
return true
|
||||
end)
|
||||
---@param opts? snacks.bufdelete.Opts
|
||||
function M.all(opts)
|
||||
return M.delete(vim.tbl_extend("force", {}, opts or {}, {
|
||||
filter = function()
|
||||
return true
|
||||
end,
|
||||
}))
|
||||
end
|
||||
|
||||
--- Delete all buffers except the current one
|
||||
function M.other()
|
||||
return M.delete(function(b)
|
||||
return b ~= vim.api.nvim_get_current_buf()
|
||||
end)
|
||||
---@param opts? snacks.bufdelete.Opts
|
||||
function M.other(opts)
|
||||
return M.delete(vim.tbl_extend("force", {}, opts or {}, {
|
||||
filter = function(b)
|
||||
return b ~= vim.api.nvim_get_current_buf()
|
||||
end,
|
||||
}))
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue