mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-05 03:08:13 +00:00
feat(explorer): show symlink target
This commit is contained in:
parent
7ad3b42d7b
commit
dfa79e0443
5 changed files with 27 additions and 17 deletions
|
@ -151,7 +151,7 @@ function M.next(cwd, path, up)
|
|||
local next ---@type snacks.picker.explorer.Node?
|
||||
local found = false
|
||||
Tree:walk(root, function(node)
|
||||
local want = node.type ~= "directory" and node.status and not node.ignored
|
||||
local want = not node.dir and node.status and not node.ignored
|
||||
if node.path == path then
|
||||
found = true
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
---@field status? string
|
||||
---@field ignored? boolean
|
||||
---@field type "file"|"directory"|"link"|"fifo"|"socket"|"char"|"block"|"unknown"
|
||||
---@field dir? boolean
|
||||
---@field open? boolean wether the node should be expanded (only for directories)
|
||||
---@field expanded? boolean wether the node is expanded (only for directories)
|
||||
---@field parent? snacks.picker.explorer.Node
|
||||
|
@ -34,7 +35,7 @@ Tree.__index = Tree
|
|||
|
||||
function Tree.new()
|
||||
local self = setmetatable({}, Tree)
|
||||
self.root = { name = "", children = {}, type = "directory", path = "" }
|
||||
self.root = { name = "", children = {}, dir = true, type = "directory", path = "" }
|
||||
self.nodes = {}
|
||||
return self
|
||||
end
|
||||
|
@ -75,6 +76,7 @@ function Tree:child(node, name, type)
|
|||
parent = node,
|
||||
children = {},
|
||||
type = type,
|
||||
dir = type == "directory" or (type == "link" and vim.fn.isdirectory(path) == 1),
|
||||
hidden = name:sub(1, 1) == ".",
|
||||
}
|
||||
self.nodes[path] = node.children[name]
|
||||
|
@ -121,18 +123,17 @@ function Tree:expand(node)
|
|||
return
|
||||
end
|
||||
local found = {} ---@type table<string, boolean>
|
||||
assert(node.type == "directory", "Can only expand directories")
|
||||
assert(node.dir, "Can only expand directories")
|
||||
local fs = uv.fs_scandir(node.path)
|
||||
while fs do
|
||||
local name, t = uv.fs_scandir_next(fs)
|
||||
if not name then
|
||||
break
|
||||
end
|
||||
if t == "link" and vim.fn.isdirectory(node.path .. "/" .. name) == 1 then
|
||||
t = "directory"
|
||||
end
|
||||
found[name] = true
|
||||
self:child(node, name, t).type = t
|
||||
local child = self:child(node, name, t)
|
||||
child.type = t
|
||||
child.dir = t == "directory" or (t == "link" and vim.fn.isdirectory(child.path) == 1)
|
||||
end
|
||||
for name in pairs(node.children) do
|
||||
if not found[name] then
|
||||
|
@ -172,17 +173,15 @@ function Tree:walk(node, fn, opts)
|
|||
end
|
||||
local children = vim.tbl_values(node.children) ---@type snacks.picker.explorer.Node[]
|
||||
table.sort(children, function(a, b)
|
||||
local a_dir = a.type == "directory"
|
||||
local b_dir = b.type == "directory"
|
||||
if a_dir ~= b_dir then
|
||||
return a_dir
|
||||
if a.dir ~= b.dir then
|
||||
return a.dir
|
||||
end
|
||||
return a.name < b.name
|
||||
end)
|
||||
for c, child in ipairs(children) do
|
||||
child.last = c == #children
|
||||
abort = false
|
||||
if child.type == "directory" and (child.open or (opts and opts.all)) then
|
||||
if child.dir and (child.open or (opts and opts.all)) then
|
||||
abort = self:walk(child, fn, opts)
|
||||
else
|
||||
abort = fn(child)
|
||||
|
@ -210,7 +209,7 @@ function Tree:get(cwd, cb, opts)
|
|||
return false
|
||||
end
|
||||
end
|
||||
if n.type == "directory" and n.open and not n.expanded and opts.expand ~= false then
|
||||
if n.dir and n.open and not n.expanded and opts.expand ~= false then
|
||||
self:expand(n)
|
||||
end
|
||||
cb(n)
|
||||
|
@ -223,7 +222,7 @@ function Tree:is_dirty(cwd, opts)
|
|||
opts = opts or {}
|
||||
local dirty = false
|
||||
self:get(cwd, function(n)
|
||||
if n.type == "directory" and n.open and not n.expanded then
|
||||
if n.dir and n.open and not n.expanded then
|
||||
dirty = true
|
||||
end
|
||||
end, { hidden = opts.hidden, ignored = opts.ignored, expand = false })
|
||||
|
|
|
@ -10,6 +10,7 @@ Snacks.util.set_hl({
|
|||
Label = "SnacksPickerSpecial",
|
||||
Totals = "NonText",
|
||||
File = "", -- basename of a file path
|
||||
Link = "Comment",
|
||||
Directory = "Directory", -- basename of a directory path
|
||||
PathIgnored = "NonText", -- any ignored file or directory
|
||||
PathHidden = "NonText", -- any hidden file or directory
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
---@field [string] snacks.picker.format
|
||||
local M = {}
|
||||
|
||||
local uv = vim.uv or vim.loop
|
||||
|
||||
function M.severity(item, picker)
|
||||
local ret = {} ---@type snacks.picker.Highlight[]
|
||||
local severity = item.severity
|
||||
|
@ -95,6 +97,14 @@ function M.filename(item, picker)
|
|||
end
|
||||
end
|
||||
ret[#ret + 1] = { " " }
|
||||
if item.type == "link" then
|
||||
local real = uv.fs_realpath(item.file) or uv.fs_readlink(item.file)
|
||||
if real then
|
||||
ret[#ret + 1] = { "-> ", "SnacksPickerDelim" }
|
||||
ret[#ret + 1] = { Snacks.picker.util.truncpath(real, 20), "SnacksPickerLink" }
|
||||
ret[#ret + 1] = { " " }
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
|
|
|
@ -211,13 +211,13 @@ function M.explorer(opts, ctx)
|
|||
Tree:get(ctx.filter.cwd, function(node)
|
||||
local item = {
|
||||
file = node.path,
|
||||
dir = node.type == "directory",
|
||||
dir = node.dir,
|
||||
open = node.open,
|
||||
text = node.path,
|
||||
parent = node.parent and items[node.parent.path] or nil,
|
||||
hidden = node.hidden,
|
||||
ignored = node.ignored,
|
||||
status = (node.type ~= "directory" or not node.open or opts.git_status_open) and node.status or nil,
|
||||
status = (not node.dir or not node.open or opts.git_status_open) and node.status or nil,
|
||||
last = node.last,
|
||||
type = node.type,
|
||||
}
|
||||
|
@ -298,7 +298,7 @@ function M.search(opts, ctx)
|
|||
end
|
||||
local node = Tree:find(item.file)
|
||||
if node then
|
||||
item.status = (node.type ~= "directory" or opts.git_status_open) and node.status or nil
|
||||
item.status = (not node.dir or opts.git_status_open) and node.status or nil
|
||||
end
|
||||
|
||||
if opts.tree then
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue