mirror of
https://github.com/folke/snacks.nvim
synced 2025-12-23 08:47:57 +00:00
feat(picker.scratch): add scratch picker with grep, new and delete keybinds (#1019)
## Description The scratch module uses `vim.ui.select` which misses the nice things about the picker. This implementation adds scratch picker with ability to create, grep and delete scratch buffers. Couldn't figure out how to prettify the scratch buffer's name so any help would be appreciated. ## Related Issue(s) <!-- If this PR fixes any issues, please link to the issue here. - Fixes #<issue_number> --> ## Screenshots <!-- Add screenshots of the changes if applicable. --> --------- Co-authored-by: Folke Lemaitre <folke.lemaitre@gmail.com>
This commit is contained in:
parent
4e1070867a
commit
ca0f8b2c09
6 changed files with 94 additions and 35 deletions
|
|
@ -300,6 +300,19 @@ function M.finder(finder)
|
|||
return M.field(finder) or nop
|
||||
end
|
||||
|
||||
---@param picker snacks.Picker
|
||||
---@param action string
|
||||
function M.action(picker, action)
|
||||
local ret = (picker.opts.actions or {})[action] or require("snacks.picker.actions")[action]
|
||||
if ret then
|
||||
return ret
|
||||
end
|
||||
local source = action:match("^(.-)_")
|
||||
if source then -- source specific action
|
||||
return (M.field(("%s_actions"):format(source)) or {})[action]
|
||||
end
|
||||
end
|
||||
|
||||
--- Resolves a module field
|
||||
---@param spec string
|
||||
function M.field(spec)
|
||||
|
|
|
|||
|
|
@ -807,6 +807,21 @@ M.registers = {
|
|||
-- Special picker that resumes the last picker
|
||||
M.resume = {}
|
||||
|
||||
-- Open or create scratch buffers
|
||||
M.scratch = {
|
||||
finder = "scratch",
|
||||
format = "scratch_format",
|
||||
confirm = "scratch_open",
|
||||
win = {
|
||||
input = {
|
||||
keys = {
|
||||
["<c-x>"] = { "scratch_delete", mode = { "n", "i" } },
|
||||
["<c-n>"] = { "scratch_new", mode = { "n", "i" } },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
-- Neovim search history
|
||||
---@type snacks.picker.history.Config
|
||||
M.search_history = {
|
||||
|
|
|
|||
|
|
@ -81,16 +81,8 @@ function M.resolve(action, picker, name, stack)
|
|||
end
|
||||
end
|
||||
stack[#stack + 1] = action
|
||||
return M.resolve(
|
||||
(picker.opts.actions or {})[action]
|
||||
or require("snacks.picker.actions")[action]
|
||||
or require("snacks.explorer.actions").actions[action],
|
||||
picker,
|
||||
action,
|
||||
stack
|
||||
)
|
||||
return M.resolve(Snacks.picker.config.action(picker, action), picker, action, stack)
|
||||
elseif type(action) == "table" and svim.islist(action) then
|
||||
---@type snacks.picker.Action[]
|
||||
local actions = vim.tbl_map(function(a)
|
||||
return M.resolve(a, picker, nil, stack)
|
||||
end, action)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ local Tree = require("snacks.explorer.tree")
|
|||
|
||||
local M = {}
|
||||
|
||||
M.actions = Actions.actions
|
||||
|
||||
---@type table<snacks.Picker, snacks.picker.explorer.State>
|
||||
M._state = setmetatable({}, { __mode = "k" })
|
||||
local uv = vim.uv or vim.loop
|
||||
|
|
|
|||
62
lua/snacks/picker/source/scratch.lua
Normal file
62
lua/snacks/picker/source/scratch.lua
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
local M = {}
|
||||
|
||||
---@class snacks.scratch.actions
|
||||
---@field [string] snacks.picker.Action.spec
|
||||
M.actions = {
|
||||
scratch_open = function(picker, item)
|
||||
picker:close()
|
||||
if not item then
|
||||
return
|
||||
end
|
||||
Snacks.scratch.open({ icon = item.item.icon, file = item.item.file, name = item.item.name, ft = item.item.ft })
|
||||
end,
|
||||
scratch_delete = function(picker, item)
|
||||
local current = item.file
|
||||
os.remove(current)
|
||||
picker.list:set_selected()
|
||||
picker.list:set_target()
|
||||
picker:find()
|
||||
end,
|
||||
scratch_new = function(picker)
|
||||
picker:close()
|
||||
Snacks.scratch.open()
|
||||
end,
|
||||
}
|
||||
|
||||
---@param opts snacks.picker.proc.Config
|
||||
---@type snacks.picker.finder
|
||||
function M.scratch(opts)
|
||||
local list = Snacks.scratch.list()
|
||||
local items = {} ---@type snacks.picker.finder.Item[]
|
||||
for _, item in ipairs(list) do
|
||||
items[#items + 1] = {
|
||||
file = item.file,
|
||||
item = item,
|
||||
title = item.name,
|
||||
text = Snacks.picker.util.text(item, { "name", "branch", "ft" }),
|
||||
branch = item.branch and ("branch:%s"):format(item.branch) or "",
|
||||
}
|
||||
end
|
||||
return items
|
||||
end
|
||||
|
||||
---@type snacks.picker.format
|
||||
function M.format(item, picker)
|
||||
local file = item.item
|
||||
local ret = {} ---@type snacks.picker.Highlight[]
|
||||
local a = Snacks.picker.util.align
|
||||
local icon, icon_hl = file.icon, nil
|
||||
if not icon then
|
||||
icon, icon_hl = Snacks.util.icon(file.ft, "filetype")
|
||||
end
|
||||
ret[#ret + 1] = { a(icon, 3), icon_hl }
|
||||
ret[#ret + 1] = { a(file.name, 20, { truncate = true }) }
|
||||
ret[#ret + 1] = { " " }
|
||||
ret[#ret + 1] = { a(item.branch, 20, { truncate = true }), "Number" }
|
||||
ret[#ret + 1] = { " " }
|
||||
---@diagnostic disable-next-line: missing-fields
|
||||
vim.list_extend(ret, Snacks.picker.format.filename({ text = "", dir = true, file = file.cwd }, picker))
|
||||
return ret
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
@ -119,32 +119,7 @@ end
|
|||
|
||||
--- Select a scratch buffer from a list of scratch buffers.
|
||||
function M.select()
|
||||
local widths = { 0, 0, 0, 0 }
|
||||
local items = M.list()
|
||||
for _, item in ipairs(items) do
|
||||
item.icon = item.icon or Snacks.util.icon(item.ft, "filetype")
|
||||
item.branch = item.branch and ("branch:%s"):format(item.branch) or ""
|
||||
item.cwd = item.cwd and vim.fn.fnamemodify(item.cwd, ":p:~") or ""
|
||||
widths[1] = math.max(widths[1], vim.api.nvim_strwidth(item.cwd))
|
||||
widths[2] = math.max(widths[2], vim.api.nvim_strwidth(item.icon))
|
||||
widths[3] = math.max(widths[3], vim.api.nvim_strwidth(item.name))
|
||||
widths[4] = math.max(widths[4], vim.api.nvim_strwidth(item.branch))
|
||||
end
|
||||
vim.ui.select(items, {
|
||||
prompt = "Select Scratch Buffer",
|
||||
---@param item snacks.scratch.File
|
||||
format_item = function(item)
|
||||
local parts = { item.cwd, item.icon, item.name, item.branch }
|
||||
for i, part in ipairs(parts) do
|
||||
parts[i] = part .. string.rep(" ", widths[i] - vim.api.nvim_strwidth(part))
|
||||
end
|
||||
return table.concat(parts, " ")
|
||||
end,
|
||||
}, function(selected)
|
||||
if selected then
|
||||
M.open({ icon = selected.icon, file = selected.file, name = selected.name, ft = selected.ft })
|
||||
end
|
||||
end)
|
||||
return Snacks.picker.scratch()
|
||||
end
|
||||
|
||||
--- Open a scratch buffer with the given options.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue