mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-04 10:49:08 +00:00
feat(picker): reworked toggles (flags). they're now configurable. Closes #770
This commit is contained in:
parent
847509e12c
commit
e16a6a4413
7 changed files with 53 additions and 37 deletions
|
@ -448,12 +448,6 @@ function M.focus_preview(picker)
|
|||
picker.preview.win:focus()
|
||||
end
|
||||
|
||||
function M.toggle_ignored(picker)
|
||||
local opts = picker.opts --[[@as snacks.picker.files.Config]]
|
||||
opts.ignored = not opts.ignored
|
||||
picker:find()
|
||||
end
|
||||
|
||||
function M.item_action(picker, item, action)
|
||||
if item.action then
|
||||
picker:norm(function()
|
||||
|
@ -463,19 +457,6 @@ function M.item_action(picker, item, action)
|
|||
end
|
||||
end
|
||||
|
||||
function M.toggle_hidden(picker)
|
||||
local opts = picker.opts --[[@as snacks.picker.files.Config]]
|
||||
opts.hidden = not opts.hidden
|
||||
picker.list:set_target()
|
||||
picker:find()
|
||||
end
|
||||
|
||||
function M.toggle_follow(picker)
|
||||
local opts = picker.opts --[[@as snacks.picker.files.Config]]
|
||||
opts.follow = not opts.follow
|
||||
picker:find()
|
||||
end
|
||||
|
||||
function M.list_top(picker)
|
||||
picker.list:move(1, true)
|
||||
end
|
||||
|
|
|
@ -8,6 +8,7 @@ local M = {}
|
|||
---@alias snacks.picker.sort fun(a:snacks.picker.Item, b:snacks.picker.Item):boolean
|
||||
---@alias snacks.picker.transform fun(item:snacks.picker.finder.Item, ctx:snacks.picker.finder.ctx):(boolean|snacks.picker.finder.Item|nil)
|
||||
---@alias snacks.picker.Pos {[1]:number, [2]:number}
|
||||
---@alias snacks.picker.toggle {icon?:string, enabled?:boolean, value?:boolean}
|
||||
|
||||
--- Generic filter used by finders to pre-filter items
|
||||
---@class snacks.picker.filter.Config
|
||||
|
@ -166,6 +167,14 @@ local defaults = {
|
|||
tagstack = false, -- save the current position in the tagstack
|
||||
reuse_win = false, -- reuse an existing window if the buffer is already open
|
||||
},
|
||||
---@type table<string, string|false|snacks.picker.toggle>
|
||||
toggles = {
|
||||
follow = "f",
|
||||
hidden = "h",
|
||||
ignored = "i",
|
||||
modified = "m",
|
||||
regex = { icon = "R", value = false },
|
||||
},
|
||||
win = {
|
||||
-- input window
|
||||
input = {
|
||||
|
@ -244,6 +253,8 @@ local defaults = {
|
|||
["<ScrollWheelDown>"] = "list_scroll_wheel_down",
|
||||
["<ScrollWheelUp>"] = "list_scroll_wheel_up",
|
||||
["<c-a>"] = "select_all",
|
||||
["<a-m>"] = { "toggle_maximize" },
|
||||
["<a-p>"] = { "toggle_preview" },
|
||||
["<c-f>"] = "preview_scroll_down",
|
||||
["<c-b>"] = "preview_scroll_up",
|
||||
["<c-l>"] = "preview_scroll_right",
|
||||
|
@ -256,6 +267,9 @@ local defaults = {
|
|||
["<c-p>"] = "list_up",
|
||||
["<a-w>"] = "cycle_win",
|
||||
["<Esc>"] = "close",
|
||||
["<a-i>"] = "toggle_ignored",
|
||||
["<a-h>"] = "toggle_hidden",
|
||||
["<a-f>"] = "toggle_follow",
|
||||
},
|
||||
wo = {
|
||||
conceallevel = 2,
|
||||
|
|
|
@ -12,10 +12,7 @@ Snacks.util.set_hl({
|
|||
File = "", -- basename of a file path
|
||||
Directory = "Directory", -- basename of a directory path
|
||||
Dir = "NonText", -- dirname of a path
|
||||
Flag = "DiagnosticVirtualTextInfo",
|
||||
FlagHidden = "SnacksPickerFlag",
|
||||
FlagIgnored = "SnacksPickerFlag",
|
||||
FlagFollow = "SnacksPickerFlag",
|
||||
Toggle = "DiagnosticVirtualTextInfo",
|
||||
Dimmed = "Conceal",
|
||||
Row = "String",
|
||||
Col = "LineNr",
|
||||
|
|
|
@ -87,6 +87,21 @@ function M.get(opts)
|
|||
opts = t.config(opts) or opts
|
||||
end
|
||||
end
|
||||
|
||||
-- add hl groups and actions for toggles
|
||||
opts.actions = opts.actions or {}
|
||||
for name in pairs(opts.toggles) do
|
||||
local hl = table.concat(vim.tbl_map(function(a)
|
||||
return a:sub(1, 1):upper() .. a:sub(2)
|
||||
end, vim.split(name, "_")))
|
||||
Snacks.util.set_hl({ [hl] = "SnacksPickerToggle" }, { default = true, prefix = "SnacksPickerToggle" })
|
||||
opts.actions["toggle_" .. name] = function(picker)
|
||||
picker.opts[name] = not picker.opts[name]
|
||||
picker.list:set_target()
|
||||
picker:find()
|
||||
end
|
||||
end
|
||||
|
||||
M.multi(opts)
|
||||
return opts
|
||||
end
|
||||
|
|
|
@ -16,6 +16,7 @@ M.autocmds = {
|
|||
---@field unloaded? boolean show loaded buffers
|
||||
---@field current? boolean show current buffer
|
||||
---@field nofile? boolean show `buftype=nofile` buffers
|
||||
---@field modified? boolean show only modified buffers
|
||||
---@field sort_lastused? boolean sort by last used
|
||||
---@field filter? snacks.picker.filter.Config
|
||||
M.buffers = {
|
||||
|
@ -232,6 +233,7 @@ M.git_diff = {
|
|||
---@field rtp? boolean search in runtimepath
|
||||
M.grep = {
|
||||
finder = "grep",
|
||||
regex = true,
|
||||
format = "file",
|
||||
live = true, -- live grep by default
|
||||
supports_live = true,
|
||||
|
|
|
@ -355,19 +355,25 @@ function M:update_titles()
|
|||
live = self.opts.live and self.opts.icons.ui.live or "",
|
||||
preview = vim.trim(self.preview.title or ""),
|
||||
}
|
||||
local opts = self.opts --[[@as snacks.picker.files.Config]]
|
||||
local flags = {} ---@type snacks.picker.Text[]
|
||||
if opts.follow then
|
||||
flags[#flags + 1] = { " " .. self.opts.icons.ui.follow .. " ", "SnacksPickerFlagFollow" }
|
||||
flags[#flags + 1] = { " ", "FloatTitle" }
|
||||
end
|
||||
if opts.hidden then
|
||||
flags[#flags + 1] = { " " .. self.opts.icons.ui.hidden .. " ", "SnacksPickerFlagHidden" }
|
||||
flags[#flags + 1] = { " ", "FloatTitle" }
|
||||
end
|
||||
if opts.ignored then
|
||||
flags[#flags + 1] = { " " .. self.opts.icons.ui.ignored .. " ", "SnacksPickerFlagIgnored" }
|
||||
flags[#flags + 1] = { " ", "FloatTitle" }
|
||||
local toggles = {} ---@type snacks.picker.Text[]
|
||||
for name, toggle in pairs(self.opts.toggles) do
|
||||
if toggle then
|
||||
toggle = type(toggle) == "string" and { icon = toggle } or toggle
|
||||
toggle = toggle == true and { icon = name:sub(1, 1) } or toggle
|
||||
toggle = toggle == false and { enabled = false } or toggle
|
||||
local want = toggle.value
|
||||
if toggle.value == nil then
|
||||
want = true
|
||||
end
|
||||
---@cast toggle snacks.picker.toggle
|
||||
if toggle.enabled ~= false and self.opts[name] == want then
|
||||
local hl = table.concat(vim.tbl_map(function(a)
|
||||
return a:sub(1, 1):upper() .. a:sub(2)
|
||||
end, vim.split(name, "_")))
|
||||
toggles[#toggles + 1] = { " " .. toggle.icon .. " ", "SnacksPickerToggle" .. hl }
|
||||
toggles[#toggles + 1] = { " ", "FloatTitle" }
|
||||
end
|
||||
end
|
||||
end
|
||||
local wins = { self.layout.root }
|
||||
vim.list_extend(wins, vim.tbl_values(self.layout.wins))
|
||||
|
@ -380,7 +386,7 @@ function M:update_titles()
|
|||
local title = Snacks.picker.util.tpl(tpl, data)
|
||||
if title:find("{flags}", 1, true) then
|
||||
title = title:gsub("{flags}", "")
|
||||
vim.list_extend(ret, flags)
|
||||
vim.list_extend(ret, toggles)
|
||||
end
|
||||
title = vim.trim(title):gsub("%s+", " ")
|
||||
if title ~= "" then
|
||||
|
|
|
@ -21,6 +21,7 @@ function M.buffers(opts, ctx)
|
|||
and (opts.unloaded or vim.api.nvim_buf_is_loaded(buf))
|
||||
and (opts.current or buf ~= current_buf)
|
||||
and (opts.nofile or vim.bo[buf].buftype ~= "nofile")
|
||||
and (not opts.modified or vim.bo[buf].modified)
|
||||
if keep then
|
||||
local name = vim.api.nvim_buf_get_name(buf)
|
||||
if name == "" then
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue