Files
dotfiles/yazi/plugins/yaziline.yazi/main.lua
2025-06-14 20:26:14 +02:00

199 lines
5.7 KiB
Lua

local function setup(_, options)
options = options or {}
local default_separators = {
angly = { "", "", "", "" },
curvy = { "", "", "", "" },
liney = { "", "", "|", "|" },
empty = { "", "", "", "" },
}
local separators = default_separators[options.separator_style or "angly"]
local config = {
separator_styles = {
separator_open = options.separator_open or separators[1],
separator_close = options.separator_close or separators[2],
separator_open_thin = options.separator_open_thin or separators[3],
separator_close_thin = options.separator_close_thin or separators[4],
separator_head = options.separator_head or "",
separator_tail = options.separator_tail or "",
},
select_symbol = options.select_symbol or "S",
yank_symbol = options.yank_symbol or "Y",
filename_max_length = options.filename_max_length or 24,
filename_truncate_length = options.filename_truncate_length or 6,
filename_truncate_separator = options.filename_truncate_separator or "...",
color = options.color or nil,
default_files_color = options.default_files_color
or th.which.separator_style.fg
or "darkgray",
selected_files_color = options.selected_files_color
or th.mgr.count_selected.bg
or "white",
yanked_files_color = options.selected_files_color
or th.mgr.count_copied.bg
or "green",
cut_files_color = options.cut_files_color
or th.mgr.count_cut.bg
or "red",
}
local current_separator_style = config.separator_styles
function Header:count()
return ui.Line({})
end
function Status:mode()
local mode = tostring(self._tab.mode):upper()
local style = self:style()
return ui.Line({
ui.Span(current_separator_style.separator_head)
:fg(config.color or style.main.bg),
ui.Span(" " .. mode .. " ")
:fg(th.which.mask.bg)
:bg(config.color or style.main.bg),
})
end
function Status:size()
local h = self._current.hovered
local size = h and ya.readable_size(h:size() or h.cha.len)
local style = self:style()
return ui.Span(current_separator_style.separator_close .. " " .. size .. " ")
:fg(config.color or style.main.bg)
:bg(th.which.separator_style.fg)
end
function Status:utf8_sub(str, start_char, end_char)
local start_byte = utf8.offset(str, start_char)
local end_byte = end_char and (utf8.offset(str, end_char + 1) - 1) or #str
if not start_byte or not end_byte then
return ""
end
return string.sub(str, start_byte, end_byte)
end
function Status:truncate_name(filename, max_length)
local base_name, extension = filename:match("^(.+)(%.[^%.]+)$")
base_name = base_name or filename
extension = extension or ""
if utf8.len(base_name) > max_length then
base_name = self:utf8_sub(base_name, 1, config.filename_truncate_length)
.. config.filename_truncate_separator
.. self:utf8_sub(base_name, -config.filename_truncate_length)
end
return base_name .. extension
end
function Status:name()
local h = self._current.hovered
if not h then
return ""
end
local truncated_name = self:truncate_name(h.name, config.filename_max_length)
local style = self:style()
return ui.Line {
ui.Span(current_separator_style.separator_close .. " ")
:fg(th.which.separator_style.fg),
ui.Span(truncated_name)
:fg(config.color or style.main.bg),
}
end
function Status:files()
local files_yanked = #cx.yanked
local files_selected = #cx.active.selected
local files_cut = cx.yanked.is_cut
local selected_fg = files_selected > 0
and config.selected_files_color
or config.default_files_color
local yanked_fg = files_yanked > 0
and
(files_cut
and config.cut_files_color
or config.yanked_files_color
)
or config.default_files_color
local yanked_text = files_yanked > 0
and config.yank_symbol .. " " .. files_yanked
or config.yank_symbol .. " 0"
return ui.Line({
ui.Span(" " .. current_separator_style.separator_close_thin .. " ")
:fg(th.which.separator_style.fg),
ui.Span(config.select_symbol .. " " .. files_selected .. " ")
:fg(selected_fg),
ui.Span(yanked_text .. " ")
:fg(yanked_fg),
})
end
function Status:modified()
local hovered = cx.active.current.hovered
local cha = hovered.cha
local time = (cha.mtime or 0) // 1
return ui.Span(os.date("%Y-%m-%d %H:%M", time) .. " " .. current_separator_style.separator_open_thin .. " ")
:fg(th.which.separator_style.fg)
end
function Status:percent()
local percent = 0
local cursor = self._tab.current.cursor
local length = #self._tab.current.files
if cursor ~= 0 and length ~= 0 then
percent = math.floor((cursor + 1) * 100 / length)
end
if percent == 0 then
percent = " Top "
elseif percent == 100 then
percent = " Bot "
else
percent = string.format(" %2d%% ", percent)
end
local style = self:style()
return ui.Line({
ui.Span(" " .. current_separator_style.separator_open)
:fg(th.which.separator_style.fg),
ui.Span(percent)
:fg(config.color or style.main.bg)
:bg(th.which.separator_style.fg),
ui.Span(current_separator_style.separator_open)
:fg(config.color or style.main.bg)
:bg(th.which.separator_style.fg),
})
end
function Status:position()
local cursor = self._tab.current.cursor
local length = #self._tab.current.files
local style = self:style()
return ui.Line({
ui.Span(string.format(" %2d/%-2d ", math.min(cursor + 1, length), length))
:fg(th.which.mask.bg)
:bg(config.color or style.main.bg),
ui.Span(current_separator_style.separator_tail):fg(config.color or style.main.bg),
})
end
Status:children_add(Status.files, 4000, Status.LEFT)
Status:children_add(Status.modified, 0, Status.RIGHT)
end
return { setup = setup }