199 lines
5.7 KiB
Lua
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 } |