mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-06 11:48:23 +00:00
feat(explorer): add hl groups for ignored / hidden files. Closes #887
This commit is contained in:
parent
ef040d0ba5
commit
85e1b343b0
5 changed files with 50 additions and 12 deletions
|
@ -11,6 +11,8 @@ Snacks.util.set_hl({
|
||||||
Totals = "NonText",
|
Totals = "NonText",
|
||||||
File = "", -- basename of a file path
|
File = "", -- basename of a file path
|
||||||
Directory = "Directory", -- basename of a directory path
|
Directory = "Directory", -- basename of a directory path
|
||||||
|
PathIgnored = "NonText", -- any ignored file or directory
|
||||||
|
PathHidden = "NonText", -- any hidden file or directory
|
||||||
Dir = "NonText", -- dirname of a path
|
Dir = "NonText", -- dirname of a path
|
||||||
Toggle = "DiagnosticVirtualTextInfo",
|
Toggle = "DiagnosticVirtualTextInfo",
|
||||||
Dimmed = "Conceal",
|
Dimmed = "Conceal",
|
||||||
|
|
|
@ -252,6 +252,8 @@ M.git_stash = {
|
||||||
confirm = "git_stash_apply",
|
confirm = "git_stash_apply",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@class snacks.picker.git.status.Config: snacks.picker.Config
|
||||||
|
---@field ignored? boolean show ignored files
|
||||||
M.git_status = {
|
M.git_status = {
|
||||||
finder = "git_status",
|
finder = "git_status",
|
||||||
format = "git_status",
|
format = "git_status",
|
||||||
|
|
|
@ -51,6 +51,21 @@ function M.filename(item, picker)
|
||||||
end
|
end
|
||||||
|
|
||||||
local base_hl = item.dir and "SnacksPickerDirectory" or "SnacksPickerFile"
|
local base_hl = item.dir and "SnacksPickerDirectory" or "SnacksPickerFile"
|
||||||
|
local function is(prop)
|
||||||
|
local it = item
|
||||||
|
while it do
|
||||||
|
if it[prop] then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
it = it.parent
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if is("ignored") then
|
||||||
|
base_hl = "SnacksPickerPathIgnored"
|
||||||
|
elseif is("hidden") then
|
||||||
|
base_hl = "SnacksPickerPathHidden"
|
||||||
|
end
|
||||||
local dir_hl = "SnacksPickerDir"
|
local dir_hl = "SnacksPickerDir"
|
||||||
|
|
||||||
if picker.opts.formatters.file.filename_only then
|
if picker.opts.formatters.file.filename_only then
|
||||||
|
|
|
@ -146,6 +146,7 @@ local git_tree_status = {} ---@type table<string, string>
|
||||||
---@field git_status {file: string, status: string, sort?:string}[]
|
---@field git_status {file: string, status: string, sort?:string}[]
|
||||||
---@field expanded table<string, boolean>
|
---@field expanded table<string, boolean>
|
||||||
---@field cache table<string, snacks.picker.explorer.Item[]>
|
---@field cache table<string, snacks.picker.explorer.Item[]>
|
||||||
|
---@field cache_opts? snacks.picker.explorer.Config|{}
|
||||||
local State = {}
|
local State = {}
|
||||||
State.__index = State
|
State.__index = State
|
||||||
---@param picker snacks.Picker
|
---@param picker snacks.Picker
|
||||||
|
@ -213,19 +214,21 @@ function State:update_git_status()
|
||||||
-- Update tree status
|
-- Update tree status
|
||||||
git_tree_status = {}
|
git_tree_status = {}
|
||||||
|
|
||||||
---@param p string
|
---@param path string
|
||||||
---@param s string
|
---@param status string
|
||||||
---@param is_dir? boolean
|
local function add_git_status(path, status)
|
||||||
local function add_git_status(p, s, is_dir)
|
git_tree_status[path] = git_tree_status[path] and Git.merge_status(git_tree_status[path], status) or status
|
||||||
git_tree_status[p] = git_tree_status[p] and Git.merge_status(git_tree_status[p], s) or s
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Add git status to files and parents
|
-- Add git status to files and parents
|
||||||
for _, s in ipairs(self.git_status) do
|
for _, s in ipairs(self.git_status) do
|
||||||
add_git_status(s.file, s.status)
|
local path = s.file:gsub("/$", "")
|
||||||
add_git_status(self.cwd, s.status, true)
|
add_git_status(path, s.status)
|
||||||
for dir in Snacks.picker.util.parents(s.file, self.cwd) do
|
if s.status:sub(1, 1) ~= "!" then -- don't propagate ignored status
|
||||||
add_git_status(dir, s.status, true)
|
add_git_status(self.cwd, s.status)
|
||||||
|
for dir in Snacks.picker.util.parents(path, self.cwd) do
|
||||||
|
add_git_status(dir, s.status)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -642,7 +645,9 @@ function M.explorer(opts, ctx)
|
||||||
local tick = state.tick
|
local tick = state.tick
|
||||||
opts.notify = false
|
opts.notify = false
|
||||||
local expanded = {} ---@type table<string, boolean>
|
local expanded = {} ---@type table<string, boolean>
|
||||||
local use_cache = not state.all
|
local cache_opts = { hidden = opts.hidden, ignored = opts.ignored }
|
||||||
|
|
||||||
|
local use_cache = not state.all and vim.deep_equal(state.cache_opts, cache_opts)
|
||||||
for _, dir in ipairs(opts.dirs or {}) do
|
for _, dir in ipairs(opts.dirs or {}) do
|
||||||
expanded[dir] = true
|
expanded[dir] = true
|
||||||
use_cache = use_cache and state.cache[dir] ~= nil
|
use_cache = use_cache and state.cache[dir] ~= nil
|
||||||
|
@ -650,6 +655,7 @@ function M.explorer(opts, ctx)
|
||||||
|
|
||||||
if not use_cache then
|
if not use_cache then
|
||||||
state.cache = {}
|
state.cache = {}
|
||||||
|
state.cache_opts = cache_opts
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param path string
|
---@param path string
|
||||||
|
@ -659,7 +665,14 @@ function M.explorer(opts, ctx)
|
||||||
|
|
||||||
---@param item snacks.picker.explorer.Item
|
---@param item snacks.picker.explorer.Item
|
||||||
local function add_git_status(item)
|
local function add_git_status(item)
|
||||||
item.status = (opts.git_status_open or not item.open) and git_tree_status[item.file or ""] or nil
|
item.status = git_tree_status[item.file or ""] or nil
|
||||||
|
local ignored = item.status and item.status:sub(1, 1) == "!"
|
||||||
|
if item.open and not opts.git_status_open and not ignored then
|
||||||
|
item.status = nil
|
||||||
|
end
|
||||||
|
if item.status and ignored then
|
||||||
|
item.ignored = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---@type snacks.picker.explorer.Item
|
---@type snacks.picker.explorer.Item
|
||||||
|
@ -721,6 +734,9 @@ function M.explorer(opts, ctx)
|
||||||
else
|
else
|
||||||
item.sort = parent.sort .. "#" .. basename .. " "
|
item.sort = parent.sort .. "#" .. basename .. " "
|
||||||
end
|
end
|
||||||
|
if basename:sub(1, 1) == "." then
|
||||||
|
item.hidden = true
|
||||||
|
end
|
||||||
add_git_status(item)
|
add_git_status(item)
|
||||||
|
|
||||||
if opts.tree then
|
if opts.tree then
|
||||||
|
|
|
@ -98,7 +98,7 @@ function M.log(opts, ctx)
|
||||||
}, ctx)
|
}, ctx)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param opts snacks.picker.Config
|
---@param opts snacks.picker.git.status.Config
|
||||||
---@type snacks.picker.finder
|
---@type snacks.picker.finder
|
||||||
function M.status(opts, ctx)
|
function M.status(opts, ctx)
|
||||||
local args = {
|
local args = {
|
||||||
|
@ -107,6 +107,9 @@ function M.status(opts, ctx)
|
||||||
"-uall",
|
"-uall",
|
||||||
"--porcelain=v1",
|
"--porcelain=v1",
|
||||||
}
|
}
|
||||||
|
if opts.ignored then
|
||||||
|
table.insert(args, "--ignored=matching")
|
||||||
|
end
|
||||||
|
|
||||||
local cwd = vim.fs.normalize(opts and opts.cwd or uv.cwd() or ".") or nil
|
local cwd = vim.fs.normalize(opts and opts.cwd or uv.cwd() or ".") or nil
|
||||||
cwd = Snacks.git.get_root(cwd)
|
cwd = Snacks.git.get_root(cwd)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue