mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 14:51:03 +00:00
163 lines
3.7 KiB
Lua
163 lines
3.7 KiB
Lua
Entity = {
|
|
_inc = 1000,
|
|
_children = {
|
|
{ "padding", id = 1, order = 1000 },
|
|
{ "icon", id = 2, order = 2000 },
|
|
{ "prefix", id = 3, order = 3000 },
|
|
{ "highlights", id = 4, order = 4000 },
|
|
{ "found", id = 5, order = 5000 },
|
|
{ "symlink", id = 6, order = 6000 },
|
|
},
|
|
}
|
|
|
|
function Entity:new(file) return setmetatable({ _file = file }, { __index = self }) end
|
|
|
|
function Entity:padding()
|
|
if not self._file.is_hovered then
|
|
return " "
|
|
end
|
|
|
|
local style = self:style_rev()
|
|
if style then
|
|
return ui.Span(th.indicator.padding.open):style(style)
|
|
else
|
|
return " "
|
|
end
|
|
end
|
|
|
|
function Entity:icon()
|
|
local icon = th.icon:match(self._file, { hovered = self._file.is_hovered })
|
|
if not icon then
|
|
return ""
|
|
elseif self._file.is_hovered then
|
|
return icon.text .. " "
|
|
else
|
|
return ui.Line(icon.text .. " "):style(icon.style)
|
|
end
|
|
end
|
|
|
|
function Entity:prefix()
|
|
local prefix = self._file:prefix() or ""
|
|
return prefix ~= "" and prefix .. "/" or ""
|
|
end
|
|
|
|
function Entity:highlights()
|
|
local name, p = self._file.name, ui.printable
|
|
local highlights = self._file:highlights()
|
|
if not highlights or #highlights == 0 then
|
|
return p(name)
|
|
end
|
|
|
|
local spans, last = {}, 0
|
|
for _, h in ipairs(highlights) do
|
|
if h[1] > last then
|
|
spans[#spans + 1] = p(name:sub(last + 1, h[1]))
|
|
end
|
|
spans[#spans + 1] = ui.Span(p(name:sub(h[1] + 1, h[2]))):style(th.mgr.find_keyword)
|
|
last = h[2]
|
|
end
|
|
if last < #name then
|
|
spans[#spans + 1] = p(name:sub(last + 1))
|
|
end
|
|
return ui.Line(spans)
|
|
end
|
|
|
|
function Entity:found()
|
|
if not self._file.is_hovered then
|
|
return ""
|
|
end
|
|
|
|
local found = self._file:found()
|
|
if not found then
|
|
return ""
|
|
elseif found[1] >= 99 then
|
|
return ""
|
|
end
|
|
|
|
local s = string.format("[%d/%s]", found[1] + 1, found[2] >= 100 and "99+" or found[2])
|
|
return ui.Line { " ", ui.Span(s):style(th.mgr.find_position) }
|
|
end
|
|
|
|
function Entity:symlink()
|
|
if not rt.mgr.show_symlink then
|
|
return ""
|
|
end
|
|
|
|
local to = self._file.link_to
|
|
return to and ui.Span(string.format(" -> %s", to)):style(th.mgr.symlink_target) or ""
|
|
end
|
|
|
|
function Entity:redraw()
|
|
local lines = {}
|
|
for _, c in ipairs(self._children) do
|
|
local line = (type(c[1]) == "string" and self[c[1]] or c[1])(self)
|
|
c.width, lines[#lines + 1] = ui.width(line), line
|
|
end
|
|
return ui.Line(lines):style(self:style())
|
|
end
|
|
|
|
---@return ui.Style
|
|
function Entity:style()
|
|
local s = self._file:style() or ui.Style()
|
|
if not self._file.is_hovered then
|
|
return s
|
|
elseif self._file.in_current then
|
|
return s:patch(th.indicator.current)
|
|
elseif self._file.in_preview then
|
|
return s:patch(th.indicator.preview)
|
|
else
|
|
return s:patch(th.indicator.parent)
|
|
end
|
|
end
|
|
|
|
---@return ui.Style?
|
|
function Entity:style_rev()
|
|
local s = self:style()
|
|
local bg = s:bg(true)
|
|
if bg then
|
|
return ui.Style():fg(bg):bg(App.bg()):reverse(true)
|
|
elseif s:raw().reversed then
|
|
return ui.Style():bg(App.bg()):reverse(true)
|
|
end
|
|
end
|
|
|
|
function Entity:ellipsis(max)
|
|
local adv, f = 0, self._file
|
|
for _, child in ipairs(self._children) do
|
|
adv = adv + child.width
|
|
if adv >= max then
|
|
return not f.cha.is_dir and f.url.ext and "…." .. f.url.ext or nil
|
|
elseif child.id == 4 then
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Mouse events
|
|
function Entity:click(event, up)
|
|
if up or event.is_middle then
|
|
return
|
|
end
|
|
|
|
ya.emit("reveal", { self._file.url })
|
|
if event.is_right then
|
|
ya.emit("open", {})
|
|
end
|
|
end
|
|
|
|
-- Children
|
|
function Entity:children_add(fn, order)
|
|
self._inc = self._inc + 1
|
|
self._children[#self._children + 1] = { fn, id = self._inc, order = order }
|
|
table.sort(self._children, function(a, b) return a.order < b.order end)
|
|
return self._inc
|
|
end
|
|
|
|
function Entity:children_remove(id)
|
|
for i, child in ipairs(self._children) do
|
|
if child.id == id then
|
|
table.remove(self._children, i)
|
|
break
|
|
end
|
|
end
|
|
end
|