diff options
| author | Don Williams <don.e.williams@gmail.com> | 2026-08-20 13:14:01 -0400 |
|---|---|---|
| committer | Pinapelz <yukais@pinapelz.com> | 2026-08-29 21:41:34 -0700 |
| commit | d638689871215af0a73d0df637abd4d7df9dbd84 (patch) | |
| tree | 498e3f1b2256d3745c1a790098cf5c7ae920e766 | |
| parent | 1b2cd94522c33e1c3c0d7bcf54ea42d49446218d (diff) | |
Removed yazi backup file
Signed-off-by: Don Williams <don.e.williams@gmail.com>
| -rw-r--r-- | config/yazi/plugins/yatline.yazi/main.lua.bak-20260815-174119 | 1464 |
1 files changed, 0 insertions, 1464 deletions
diff --git a/config/yazi/plugins/yatline.yazi/main.lua.bak-20260815-174119 b/config/yazi/plugins/yatline.yazi/main.lua.bak-20260815-174119 deleted file mode 100644 index eda7213b..00000000 --- a/config/yazi/plugins/yatline.yazi/main.lua.bak-20260815-174119 +++ /dev/null @@ -1,1464 +0,0 @@ ---- @since 25.12.29 ---- @diagnostic disable: undefined-global, undefined-field ---- @alias Mode Mode Comes from Yazi. ---- @alias Rect Rect Comes from Yazi. ---- @alias Paragraph Paragraph Comes from Yazi. ---- @alias Line Line Comes from Yazi. ---- @alias Span Span Comes from Yazi. ---- @alias Color Color Comes from Yazi. - ---==================-- --- Type Declaration -- ---==================-- - ---- @enum Side -local Side = { - LEFT = 0, -- The left side of either the header-line or status-line. [ LEFT ... ] - RIGHT = 1, -- The right side of either the header-line or status-line. [ ... RIGHT] -} - ---- @enum SeparatorType -local SeparatorType = { - OUTER = 0, -- Separators on the outer side of sections. [ c o | c o | c o ... ] or [ ... o c | o c | o c ] - INNER = 1, -- Separators on the inner side of sections. [ c i c | c i c | c i c ... ] or [ ... c i c | c i c | c i c ] -} - ---- @enum ComponentType -local ComponentType = { - A = 0, -- Components on the first section. [ A | | ... ] or [ ... | | A ] - B = 1, -- Components on the second section. [ | B | ... ] or [ ... | B | ] - C = 2, -- Components on the third section. [ | | C ... ] or [ ... C | | ] -} - ---- @alias Colored [string, Color] Stores text and its foreground color. ---- @alias Coloreds Colored[] The array of Coloreds. - ---- @generic T ---- @alias T T Type of the component. - ---- @class Yatline ---- @field config YatlineConfig Configuration of Yatline. ---- @field string? {} Table that stores string components. ---- @field line? {} Table that stores Line components. ---- @field coloreds? {} Table that stores Coloreds components. -Yatline = {} - ---- @class (exact) ComponentConfig ---- @field type string Defines the type of the component (T). ---- @field custom? boolean Toggles the usage of a function defined or name field. ---- @field name string | T Either defined function name or variable of defined type T. ---- @field params? {} Contains the parameters that can be used by the function called. - ---- @class (exact) SideConfig ---- @field section_a ComponentConfig[] Array of configuration of components in the first section. ---- @field section_b ComponentConfig[] Array of configuration of components in the second section. ---- @field section_c ComponentConfig[] Array of configuration of components in the third section. - ---- @class (exact) LineConfig ---- @field left SideConfig Configuration of the left side of the line. ---- @field right SideConfig Configuration of the right side of the line. - ---- @class (exact) YatlineConfig ---- @field section_separator {open: string, close: string} Separators that are between sections. ---- @field part_separator {open: string, close: string} Separators that are between components. ---- @field inverse_separator {open: string, close: string} Separators that are used when foreground color of separator is reset. ---- @field padding {inner: integer, outer: integer} Number of space padding surronding the component. ---- @field style_a {bg: Color, fg: Color, bg_mode: {normal: Color, select: Color, un_set: Color}} Style of the first section. ---- @field style_b {bg: Color, fg: Color} Style of the second section. ---- @field style_c {bg: Color, fg: Color} Style of the third section. ---- @field permissions_t_fg Color Foreground color of the type of permission. ---- @field permissions_r_fg Color Foreground color of the read permission. ---- @field permissions_w_fg Color Foreground color of the write permission. ---- @field permissions_x_fg Color Foreground color of the execute permission. ---- @field permissions_s_fg Color Foreground color of the separators between permission. ---- @field tab_width integer Maximum tab width of the tabs component. ---- @field selected {icon: string, fg: Color} Configuration for the count of files that selected. ---- @field copied {icon: string, fg: Color} Configuration for the count of files that copied. ---- @field cut {icon: string, fg: Color} Configuration for the count of files that cut. ---- @field files {icon: string, fg: Color} Configuration for the count of files in the active tab. ---- @field filtereds {icon: string, fg: Color} Configuration for the count of files in the active tab that are filtered. ---- @field total {icon: string, fg: Color} Configuration for the count of progress tasks that finished. ---- @field success {icon: string, fg: Color} Configuration for the count of progress tasks that successed. ---- @field failed {icon: string, fg: Color} Configuration for the count of progress tasks that failed. ---- @field show_background boolean Toggle the visibility of the background where no component exists. ---- @field display_header_line boolean Toggle the visibility of the header-line. ---- @field display_status_line boolean Toggle the visibility of the status-line. ---- @field component_positions string[] Arrange positions of the Yazi sections. ---- @field header_line LineConfig Configuration of header-line components. ---- @field status_line LineConfig Configuration of status-line components. -Yatline.config = { - section_separator = { open = "", close = "" }, - part_separator = { open = "", close = "" }, - inverse_separator = { open = "", close = "" }, - - padding = { inner = 1, outer = 1 }, - - style_a = { - bg = "white", - fg = "black", - bg_mode = { - normal = "white", - select = "brightyellow", - un_set = "brightred", - }, - }, - style_b = { bg = "brightblack", fg = "brightwhite" }, - style_c = { bg = "black", fg = "brightwhite" }, - - permissions_t_fg = "green", - permissions_r_fg = "yellow", - permissions_w_fg = "red", - permissions_x_fg = "cyan", - permissions_s_fg = "white", - - tab_width = 20, - - selected = { icon = "", fg = "yellow" }, - copied = { icon = "", fg = "green" }, - cut = { icon = "", fg = "red" }, - - files = { icon = "", fg = "blue" }, - filtereds = { icon = "", fg = "magenta" }, - - total = { icon = "", fg = "yellow" }, - success = { icon = "", fg = "green" }, - failed = { icon = "", fg = "red" }, - - show_background = true, - - display_header_line = true, - display_status_line = true, - - component_positions = { "header", "tab", "status" }, - - header_line = { - left = { - section_a = { - { type = "line", name = "tabs" }, - }, - section_b = {}, - section_c = {}, - }, - right = { - section_a = { - { type = "string", name = "date", params = { "%A, %d %B %Y" } }, - }, - section_b = { - { type = "string", name = "date", params = { "%X" } }, - }, - section_c = {}, - }, - }, - - status_line = { - left = { - section_a = { - { type = "string", name = "tab_mode" }, - }, - section_b = { - { type = "string", name = "hovered_size" }, - }, - section_c = { - { type = "string", name = "hovered_path" }, - { type = "coloreds", name = "count" }, - }, - }, - right = { - section_a = { - { type = "string", name = "cursor_position" }, - }, - section_b = { - { type = "string", name = "cursor_percentage" }, - }, - section_c = { - { type = "string", name = "hovered_file_extension", params = { true } }, - { type = "coloreds", name = "permissions" }, - }, - }, - }, -} - ---=================-- --- Component Setup -- ---=================-- - ---- Sets the background of style_a according to the tab's mode. ---- @param mode Mode The mode of the active tab. ---- @see cx.active.mode To get the active tab's mode. -local function set_mode_style(mode) - if mode.is_select then - Yatline.config.style_a.bg = Yatline.config.style_a.bg_mode.select - elseif mode.is_unset then - Yatline.config.style_a.bg = Yatline.config.style_a.bg_mode.un_set - else - Yatline.config.style_a.bg = Yatline.config.style_a.bg_mode.normal - end -end - ---- Helper function to apply style table to a component ---- @param component Span The component to style ---- @param style table The style table with fg and/or bg fields -local function apply_style_table(component, style) - if not style then - return component - end - -- Apply manually - if style.fg then - component:fg(style.fg) - end - if style.bg then - component:bg(style.bg) - end - if style.bold then - component:bold() - end - if style.dim then - component:dim() - end - if style.italic then - component:italic() - end - if style.underline then - component:underline() - end - if style.blink then - component:blink() - end - if style.blink_rapid then - component:blink_rapid() - end - if style.reverse then - component:reverse() - end - if style.hidden then - component:hidden() - end - if style.crossed then - component:crossed() - end - - return component -end - ---- Helper function to apply style table to a component ---- @param component Span The component to style ---- @param style table The style table with fg and/or bg fields -local function apply_style_table(component, style) - if not style then - return component - end - -- Apply manually - if style.fg then component:fg(style.fg) end - if style.bg then component:bg(style.bg) end - if style.bold then component:bold() end - if style.dim then component:dim() end - if style.italic then component:italic() end - if style.underline then component:underline() end - if style.blink then component:blink() end - if style.blink_rapid then component:blink_rapid() end - if style.reverse then component:reverse() end - if style.hidden then component:hidden() end - if style.crossed then component:crossed() end - return component -end - ---- Sets the style of the component according to the its type. ---- @param component Span Component that will be styled. ---- @param component_type ComponentType Which section component will be in [ a | b | c ]. ---- @see Style To see how to style, in Yazi's documentation. -local function set_component_style(component, component_type) - if component_type == ComponentType.A then - apply_style_table(component, Yatline.config.style_a):bold() - elseif component_type == ComponentType.B then - apply_style_table(component, Yatline.config.style_b) - else - apply_style_table(component, Yatline.config.style_c) - end -end - ---- Surronds component with paddings. ---- @param component string | Span | Line Component that will be connected to paddings. ---- @param component_type ComponentType Which section component will be in [ a | b | c ]. ---- @param in_side Side Left or right side of the either header-line or status-line. ---- @return Line line A Line which is a component that has padding. -local function connect_padding(component, component_type, in_side) - local inner = ui.Span(string.rep(" ", Yatline.config.padding.inner)) - local outer = ui.Span(string.rep(" ", Yatline.config.padding.outer)) - - set_mode_style(cx.active.mode) - set_component_style(inner, component_type) - set_component_style(outer, component_type) - - if in_side == Side.LEFT then - return ui.Line({ outer, component, inner }) - else - return ui.Line({ inner, component, outer }) - end -end - ---- Connects component to a separator. ---- @param component Span Component that will be connected to separator. ---- @param in_side Side Left or right side of the either header-line or status-line. ---- @param separator_type SeparatorType Where will there be a separator in the section. ---- @param separator_style {bg: string?, fg: string?} Holds the style of the separator. ---- @return Line line A Line which may have either both component and separator, or component. -local function connect_separator(component, in_side, separator_type, separator_style) - local open, close - if - separator_type == SeparatorType.OUTER and not (separator_style.bg == "reset" and separator_style.fg == "reset") - then - open = ui.Span(Yatline.config.section_separator.open) - close = ui.Span(Yatline.config.section_separator.close) - - if separator_style.fg == "reset" then - if separator_style.bg ~= "" then - open = ui.Span(Yatline.config.inverse_separator.open) - close = ui.Span(Yatline.config.inverse_separator.close) - - separator_style.fg, separator_style.bg = separator_style.bg, separator_style.fg - else - return ui.Line({ component }) - end - end - else - open = ui.Span(Yatline.config.part_separator.open) - close = ui.Span(Yatline.config.part_separator.close) - end - - apply_style_table(open, separator_style) - apply_style_table(close, separator_style) - - if in_side == Side.LEFT then - return ui.Line({ component, close }) - else - return ui.Line({ open, component }) - end -end - ---==================-- --- Helper Functions -- ---==================-- - ---- Gets the file name from given file extension. ---- @param file_name string The name of a file whose extension will be taken. ---- @return string file_extension Extension of a file. -local function get_file_extension(file_name) - local extension = file_name:match("^.+%.(.+)$") - - if extension == nil or extension == "" then - return "null" - else - return extension - end -end - ---- Reverse the order of given array ---- @param array Line Array which wants to be reversed. ---- @return table reversed Reversed ordered given array. -local function reverse_order(array) - local reversed = {} - for i = #array, 1, -1 do - table.insert(reversed, array[i]) - end - - return reversed -end - ---- the number of characters in a UTF-8 string ---- @param s string The string to process. ---- @return integer The number of characters in the string. -local function utf8len(s) - -- count the number of non-continuing bytes - return select(2, s:gsub("[^\128-\193]", "")) -end - ---- like string.sub() but i, j are utf8 strings ---- a utf8-safe string.sub() ---- @param s string The string to process. ---- @param i integer The start position. ---- @param j integer The end position. ---- @return string The substring. -local function utf8sub(s, i, j) - -- pattern for matching UTF-8 characters - local pattern = "[%z\1-\127\194-\244][\128-\191]*" - - -- helper function for position calculation - --- @param pos integer The position of the character. - --- @param len integer The length of the string. - --- @return integer The relative position of the character. - local function posrelat(pos, len) - if pos < 0 then - pos = len + pos + 1 - end - return pos - end - - -- helper function to iterate over UTF-8 chars - local function chars(_s, no_subs) - local function map(f) - local _i = 0 - if no_subs then - for b, e in _s:gmatch("()" .. pattern .. "()") do - _i = _i + 1 - local c = e - b - f(_i, c, b) - end - else - for b, c in _s:gmatch("()(" .. pattern .. ")") do - _i = _i + 1 - f(_i, c, b) - end - end - end - return coroutine.wrap(function() - return map(coroutine.yield) - end) - end - - local l = utf8len(s) - - i = posrelat(i, l) - j = j and posrelat(j, l) or l - - if i < 1 then - i = 1 - end - if j > l then - j = l - end - - if i > j then - return "" - end - - local diff = j - i - local iter = chars(s, true) - - -- advance up to i - for _ = 1, i - 1 do - iter() - end - - local c, b = select(2, iter()) - - -- becareful with the edge case of empty string - if not b then - return "" - end - - -- i and j are the same, single-character sub - if diff == 0 then - return string.sub(s, b, b + c - 1) - end - - i = b - - -- advance up to j - for _ = 1, diff - 1 do - iter() - end - - c, b = select(2, iter()) - - return string.sub(s, i, b + c - 1) -end - ---- Trims the filename if it is longer than the max_length. ---- @param filename string The name of a file which will be trimmed. ---- @param max_length integer Maximum length of the filename. ---- @param trim_length integer Length of the trimmed filename. ---- @return string trimmed_filename Trimmed filename. -local function trim_filename(filename, max_length, trim_length) - if not max_length or not trim_length then - return filename - end - - -- Count UTF-8 characters - local len = utf8len(filename) - - if len <= max_length then - return filename - end - - if len <= trim_length * 2 then - return filename - end - - return utf8sub(filename, 1, trim_length) .. "..." .. utf8sub(filename, len - trim_length + 1, len) -end - ---========================-- --- Component String Group -- ---========================-- - -Yatline.string = {} -Yatline.string.get = {} -Yatline.string.has_separator = true - ---- Creates a component from given string according to other parameters. ---- @param string string The text which will be shown inside of the component. ---- @param component_type ComponentType Which section component will be in [ a | b | c ]. ---- @return Line line Customized Line which follows desired style of the parameters. ---- @see set_mode_style To know how mode style selected. ---- @see set_component_style To know how component style applied. -function Yatline.string.create(string, component_type) - local span = ui.Span(string) - set_mode_style(cx.active.mode) - set_component_style(span, component_type) - - return ui.Line({ span }) -end - ---- Gets the hovered file's name of the current active tab. ---- @param trimmed? boolean Whether to trim the filename if it's too long (default: false) ---- @param max_length? integer Maximum length of the filename (default: 24) ---- @param trim_length? integer Length of each end when trimming (default: 10) ---- @param show_symlink? boolean Whether to show symlink target (default: false) ---- @return string name Current active tab's hovered file's name -function Yatline.string.get:hovered_name(trimmed, max_length, trim_length, show_symlink) - trimmed = trimmed or false - max_length = max_length or 24 - trim_length = trim_length or 10 - show_symlink = show_symlink or false - - local hovered = cx.active.current.hovered - if not hovered then - return "" - end - - local link_delimiter = " -> " - local linked = (show_symlink and hovered.link_to ~= nil) and (link_delimiter .. tostring(hovered.link_to)) or "" - - if trimmed then - local trimmed_name = trim_filename(hovered.name, max_length, trim_length) - local trimmed_linked = #linked ~= 0 - and link_delimiter .. trim_filename( - string.sub(linked, #link_delimiter + 1, -1), - max_length, - trim_length - ) - or "" - return trimmed_name .. trimmed_linked - else - return hovered.name .. linked - end -end - ---- Gets the hovered file's path of the current active tab. ---- @param trimmed? boolean Whether to trim the file path if it's too long (default: false) ---- @param max_length? integer Maximum length of the file path (default: 24) ---- @param trim_length? integer Length of each end when trimming (default: 10) ---- @return string path Current active tab's hovered file's path. -function Yatline.string.get:hovered_path(trimmed, max_length, trim_length) - trimmed = trimmed or false - max_length = max_length or 24 - trim_length = trim_length or 10 - - local hovered = cx.active.current.hovered - if not hovered then - return "" - end - - if trimmed then - return trim_filename(ya.readable_path(tostring(hovered.url)), max_length, trim_length) - else - return ya.readable_path(tostring(hovered.url)) - end -end - ---- Gets the hovered file's size of the current active tab. ---- @return string size Current active tab's hovered file's size. -function Yatline.string.get:hovered_size() - local hovered = cx.active.current.hovered - if hovered then - return ya.readable_size(hovered:size() or hovered.cha.len) - else - return "" - end -end - ---- Gets the hovered file's path of the current active tab. ---- @return string mime Current active tab's hovered file's mime. -function Yatline.string.get:hovered_mime() - local hovered = cx.active.current.hovered - if hovered then - return hovered:mime() - else - return "" - end -end - ---- Gets the hovered file's user and group ownership of the current active tab. ---- Unix-like systems only. ---- @return string ownership Current active tab's hovered file's user and group ownership. -function Yatline.string.get:hovered_ownership() - local hovered = cx.active.current.hovered - - if hovered then - if not hovered.cha.uid or not hovered.cha.gid then - return "" - end - - local username = ya.user_name(hovered.cha.uid) or tostring(hovered.cha.uid) - local groupname = ya.group_name(hovered.cha.gid) or tostring(hovered.cha.gid) - - return username .. ":" .. groupname - else - return "" - end -end - ---- Gets the hovered file's extension of the current active tab. ---- @param show_icon boolean Whether or not an icon will be shown. ---- @return string file_extension Current active tab's hovered file's extension. -function Yatline.string.get:hovered_file_extension(show_icon) - local hovered = cx.active.current.hovered - - if hovered then - local cha = hovered.cha - - local name - if cha.is_dir then - name = "dir" - else - name = get_file_extension(hovered.url.name) - end - - if show_icon then - local icon = hovered:icon().text - return icon .. " " .. name - else - return name - end - else - return "" - end -end - ---- Gets the path of the current active tab. ---- @param trimmed? boolean Whether to trim the current active tab's path if it's too long (default: false) ---- @param max_length? integer Maximum length of the current active tab's path (default: 24) ---- @param trim_length? integer Length of each end when trimming (default: 10) ---- @return string path Current active tab's path. -function Yatline.string.get:tab_path(trimmed, max_length, trim_length) - trimmed = trimmed or false - max_length = max_length or 24 - trim_length = trim_length or 10 - - local cwd = cx.active.current.cwd - local filter = cx.active.current.files.filter - local finder = cx.active.finder - - local t = {} - if cwd.is_search then - t[#t + 1] = string.format("search: %s", cwd.domain) - end - if filter then - t[#t + 1] = string.format("filter: %s", filter) - end - if finder then - t[#t + 1] = string.format("find: %s", finder) - end - - local suffix - if #t ~= 0 then - suffix = " (" .. table.concat(t, ", ") .. ")" - else - suffix = "" - end - - if trimmed then - return trim_filename(ya.readable_path(tostring(cwd)), max_length, trim_length) .. suffix - else - return ya.readable_path(tostring(cwd)) .. suffix - end -end - ---- Gets the filtered query. ---- @param key? string Key value that indicates filtered query (default: "filter:") ---- @return string query Filtered query. -function Yatline.string.get:filter_query(key) - key = key or "filter:" - - local filter = cx.active.current.files.filter - - if filter then - return string.format("%s %s", key, tostring(filter)) - else - return "" - end -end - ---- Gets the searched query. ---- @param key? string Key value that indicates searched query (default: "search:") ---- @return string query Searched query. -function Yatline.string.get:search_query(key) - key = key or "search:" - - local cwd = cx.active.current.cwd - - if cwd.is_search then - return string.format("%s %s", key, cwd.domain) - else - return "" - end -end - ---- Gets the finded query. ---- @param key? string Key value that indicates finded query (default: "find:") ---- @return string query Finded query. -function Yatline.string.get:finder_query(key) - key = key or "find:" - - local finder = cx.active.finder - - if finder then - return string.format("%s %s", key, tostring(finder)) - else - return "" - end -end - ---- Gets the mode of active tab. ---- @return string mode Active tab's mode. -function Yatline.string.get:tab_mode() - local mode = tostring(cx.active.mode):upper() - if mode == "UNSET" then - mode = "UN-SET" - end - - return mode -end - ---- Gets the number of files in the current active tab. ---- @return string num_files Number of files in the current active tab. -function Yatline.string.get:tab_num_files() - return tostring(#cx.active.current.files) -end - ---- Gets the cursor position in the current active tab. ---- @return string cursor_position Current active tab's cursor position. -function Yatline.string.get:cursor_position() - local cursor = cx.active.current.cursor - local length = #cx.active.current.files - - if length ~= 0 then - return string.format("%d/%d", cursor + 1, length) - else - return "0" - end -end - ---- Gets the cursor position as percentage which is according to the number of files inside of current active tab. ---- @return string percentage Percentage of current active tab's cursor position and number of percentages. -function Yatline.string.get:cursor_percentage() - local percentage = 0 - local cursor = cx.active.current.cursor - local length = #cx.active.current.files - if cursor ~= 0 and length ~= 0 then - percentage = math.floor((cursor + 1) * 100 / length) - end - - if percentage == 0 then - return "Top" - elseif percentage == 100 then - return "Bot" - else - return string.format("%d%%", percentage) - end -end - ---- Gets the local date or time values. ---- @param format string Format for giving desired date or time values. ---- @return string date Date or time values. ---- @see os.date To see how format works. -function Yatline.string.get:date(format) - return tostring(os.date(format)) -end - ---======================-- --- Component Line Group -- ---======================-- - -Yatline.line = {} -Yatline.line.get = {} -Yatline.line.has_separator = false - ---- To follow component group naming and functions, returns the given line without any changes. ---- @param line Line The line already pre-defined. ---- @param component_type ComponentType Which section component will be in [ a | b | c ]. Will not be used. ---- @return Line line The given line as an input. -function Yatline.line.create(line, component_type) - return line -end - ---- Creates and returns line component for tabs. ---- @param side? string Left or right side of the either header-line or status-line. ---- @return Line line Customized Line which contains tabs. ---- @see set_mode_style To know how mode style selected. ---- @see set_component_style To know how component style applied. ---- @see connect_padding To know how components have paddings. ---- @see connect_separator To know how component and separator connected. -function Yatline.line.get:tabs(side) - side = side or "left" - - local tabs = #cx.tabs - local lines = {} - - local in_side - if side == "left" then - in_side = Side.LEFT - else - in_side = Side.RIGHT - end - - for i = 1, tabs do - local text = tostring(i) - if Yatline.config.tab_width > 2 then - text = ui.truncate(text .. " " .. cx.tabs[i].name, { max = Yatline.config.tab_width }) - end - - local separator_style = { bg = nil, fg = nil } - if i == cx.tabs.idx then - local tab = connect_padding(text, ComponentType.A, in_side) - set_mode_style(cx.tabs[i].mode) - set_component_style(tab, ComponentType.A) - - if Yatline.config.style_a.bg ~= "reset" or Yatline.config.show_background then - separator_style.fg = Yatline.config.style_a.bg - if Yatline.config.show_background then - separator_style.bg = Yatline.config.style_c.bg - end - - lines[#lines + 1] = connect_separator(tab, in_side, SeparatorType.OUTER, separator_style) - else - separator_style.fg = Yatline.config.style_a.fg - - lines[#lines + 1] = connect_separator(tab, in_side, SeparatorType.INNER, separator_style) - end - else - local tab = ui.Span(text) - local inner = ui.Span(string.rep(" ", Yatline.config.padding.inner)) - local outer = ui.Span(string.rep(" ", Yatline.config.padding.outer)) - - if Yatline.config.show_background then - set_component_style(inner, ComponentType.C) - set_component_style(outer, ComponentType.C) - set_component_style(tab, ComponentType.C) - else - apply_style_table(tab, { fg = Yatline.config.style_c.fg }) - end - - if in_side == Side.LEFT then - tab = ui.Line({ outer, tab, inner }) - else - tab = ui.Line({ inner, tab, outer }) - end - - if i == cx.tabs.idx - 1 then - set_mode_style(cx.tabs[i + 1].mode) - - local open, close - if - Yatline.config.style_a.bg ~= "reset" - or (Yatline.config.show_background and Yatline.config.style_c.bg ~= "reset") - then - if - not Yatline.config.show_background - or (Yatline.config.show_background and Yatline.config.style_c.bg == "reset") - then - separator_style.fg = Yatline.config.style_a.bg - if Yatline.config.show_background then - separator_style.bg = Yatline.config.style_c.bg - end - - open = ui.Span(Yatline.config.inverse_separator.open) - close = ui.Span(Yatline.config.inverse_separator.close) - else - separator_style.bg = Yatline.config.style_a.bg - if Yatline.config.show_background then - separator_style.fg = Yatline.config.style_c.bg - end - - open = ui.Span(Yatline.config.section_separator.open) - close = ui.Span(Yatline.config.section_separator.close) - end - else - separator_style.fg = Yatline.config.style_c.fg - - open = ui.Span(Yatline.config.part_separator.open) - close = ui.Span(Yatline.config.part_separator.close) - end - - apply_style_table(open, separator_style) - apply_style_table(close, separator_style) - - if in_side == Side.LEFT then - lines[#lines + 1] = ui.Line({ tab, close }) - else - lines[#lines + 1] = ui.Line({ open, tab }) - end - else - separator_style.fg = Yatline.config.style_c.fg - if Yatline.config.show_background then - separator_style.bg = Yatline.config.style_c.bg - end - - lines[#lines + 1] = connect_separator(tab, in_side, SeparatorType.INNER, separator_style) - end - end - end - - if in_side == Side.RIGHT then - return ui.Line(reverse_order(lines)) - else - return ui.Line(lines) - end -end - ---==========================-- --- Component Coloreds Group -- ---==========================-- - -Yatline.coloreds = {} -Yatline.coloreds.get = {} -Yatline.coloreds.has_separator = true - ---- Creates a component from given Coloreds according to other parameters. ---- The component it created, can contain multiple strings with different foreground color. ---- @param coloreds Coloreds The array which contains an array which contains text which will be shown inside of the component and its foreground color. ---- @param component_type ComponentType Which section component will be in [ a | b | c ]. ---- @return Line line Customized Line which follows desired style of the parameters. ---- @see set_mode_style To know how mode style selected. ---- @see set_component_style To know how component style applied. -function Yatline.coloreds.create(coloreds, component_type) - set_mode_style(cx.active.mode) - - local spans = {} - for i, colored in ipairs(coloreds) do - local span = ui.Span(colored[1]) - set_component_style(span, component_type) - span:fg(colored[2]) - - spans[i] = span - end - - return ui.Line(spans) -end - ---- Gets the hovered file's permissions of the current active tab. ---- Unix-like systems only. ---- @return Coloreds? coloreds Current active tab's hovered file's permissions -function Yatline.coloreds.get:permissions() - local hovered = cx.active.current.hovered - - if hovered then - local perm = hovered.cha:perm() - - if perm then - local coloreds = {} - - for i = 1, #perm do - local c = perm:sub(i, i) - - local fg = Yatline.config.permissions_t_fg - if c == "-" then - fg = Yatline.config.permissions_s_fg - elseif c == "r" then - fg = Yatline.config.permissions_r_fg - elseif c == "w" then - fg = Yatline.config.permissions_w_fg - elseif c == "x" or c == "s" or c == "S" or c == "t" or c == "T" then - fg = Yatline.config.permissions_x_fg - end - - table.insert(coloreds, { c, fg }) - end - - return coloreds - else - return nil - end - else - return nil - end -end - ---- Gets the number of selected and yanked files and also number of files or filtered files of the active tab. ---- @param filter? boolean Whether or not number of files (or filtered files) will be shown. ---- @param zero_check? boolean Whether or not counts will be shown if count is zero. ---- @return Coloreds? coloreds Active tab's number of selected and yanked files and also number of files or filtered files -function Yatline.coloreds.get:count(filter, zero_check) - filter = filter or false - zero_check = zero_check or false - - local num_yanked = #cx.yanked - local num_selected = #cx.active.selected - local num_files = #cx.active.current.files - - local coloreds = {} - - if filter then - local files_count_fg, files_count_icon - if cx.active.current.files.filter or cx.active.current.cwd.is_search then - files_count_fg = Yatline.config.filtereds.fg - files_count_icon = Yatline.config.filtereds.icon - else - files_count_fg = Yatline.config.files.fg - files_count_icon = Yatline.config.files.icon - end - - if (zero_check and num_files > 0) or not zero_check then - table.insert(coloreds, { string.format("%s %d", files_count_icon, num_files), files_count_fg }) - end - end - - if (zero_check and num_selected > 0) or not zero_check then - if #coloreds > 0 then - table.insert(coloreds, { " ", Yatline.config.selected.fg }) - end - - table.insert( - coloreds, - { string.format("%s %d", Yatline.config.selected.icon, num_selected), Yatline.config.selected.fg } - ) - end - - if (zero_check and num_yanked > 0) or not zero_check then - local yanked_fg, yanked_icon - if cx.yanked.is_cut then - yanked_fg = Yatline.config.cut.fg - yanked_icon = Yatline.config.cut.icon - else - yanked_fg = Yatline.config.copied.fg - yanked_icon = Yatline.config.copied.icon - end - - if #coloreds > 0 then - table.insert(coloreds, { " ", yanked_fg }) - end - - table.insert(coloreds, { string.format("%s %d", yanked_icon, num_yanked), yanked_fg }) - end - - if #coloreds > 0 then - return coloreds - else - return nil - end -end - ---- Gets the number of task states. ---- @param zero_check? boolean Whether or not counts will be shown if count is zero. ---- @return Coloreds? coloreds Number of task states. -function Yatline.coloreds.get:task_states(zero_check) - zero_check = zero_check or false - - local summary = cx.tasks.summary - local coloreds = {} - - if (zero_check and summary.total > 0) or not zero_check then - table.insert( - coloreds, - { string.format("%s %d", Yatline.config.total.icon, summary.total), Yatline.config.total.fg } - ) - end - - if (zero_check and summary.success > 0) or not zero_check then - if #coloreds > 0 then - table.insert(coloreds, { " ", Yatline.config.success.fg }) - end - - table.insert( - coloreds, - { string.format("%s %d", Yatline.config.success.icon, summary.success), Yatline.config.success.fg } - ) - end - - if (zero_check and summary.failed > 0) or not zero_check then - if #coloreds > 0 then - table.insert(coloreds, { " ", Yatline.config.failed.fg }) - end - - table.insert( - coloreds, - { string.format("%s %d", Yatline.config.failed.icon, summary.failed), Yatline.config.failed.fg } - ) - end - - if #coloreds > 0 then - return coloreds - else - return nil - end -end - ---- Gets colored which contains string based component's string and desired foreground color. ---- @param component_name string String based component's name. ---- @param fg Color Desired foreground color. ---- @param params? table Array of parameters of string based component. It is optional. ---- @return Coloreds? coloreds Array of solely array of string based component's string and desired foreground color. -function Yatline.coloreds.get:string_based_component(component_name, fg, params) - local getter = Yatline.string.get[component_name] - - if getter then - local output - if params then - output = getter(Yatline.string.get, table.unpack(params)) - else - output = getter() - end - - if output ~= nil and output ~= "" then - return { { output, fg } } - end - end - - return nil -end - ---===============-- --- Configuration -- ---===============-- - ---- Configure separators if it is need to be added to the components. ---- Connects them with each component. ---- @param section_components [Line, boolean][] Array of components in one of the sections. ---- @param component_type ComponentType Which section component will be in [ a | b | c ]. ---- @param in_side Side Left or right side of the either header-line or status-line. ---- @param num_section_b_components integer Number of components in section-b. ---- @param num_section_c_components integer Number of components in section-c. ---- @return table section_line_components Array of line components whether or not connected with separators. ---- @see connect_padding To know how components have paddings. ---- @see connect_separator To know how component and separator connected. -local function config_components_separators( - section_components, - component_type, - in_side, - num_section_b_components, - num_section_c_components -) - local num_section_components = #section_components - local section_line_components = {} - for i, component in ipairs(section_components) do - if component[2] == true then -- Does component have separator? - local separator_style = { bg = nil, fg = nil } - - local separator_type - if i ~= num_section_components then -- Does component is not at the end of the section? - separator_type = SeparatorType.INNER - - if component_type == ComponentType.A then - separator_style = Yatline.config.style_a - elseif component_type == ComponentType.B then - separator_style = Yatline.config.style_b - else - separator_style = Yatline.config.style_c - end - else -- Does component is at the end of the section? - separator_type = SeparatorType.OUTER - - if component_type == ComponentType.A then - separator_style.fg = Yatline.config.style_a.bg - elseif component_type == ComponentType.B then - separator_style.fg = Yatline.config.style_b.bg - else - separator_style.fg = Yatline.config.style_c.bg - end - - if component_type == ComponentType.A and num_section_b_components ~= 0 then - separator_style.bg = Yatline.config.style_b.bg - elseif num_section_c_components == 0 or component_type == ComponentType.C then - if Yatline.config.show_background then - separator_style.bg = Yatline.config.style_c.bg - end - else - separator_style.bg = Yatline.config.style_c.bg - end - end - - component[1] = connect_padding(component[1], component_type, in_side) - section_line_components[i] = connect_separator(component[1], in_side, separator_type, separator_style) - else - section_line_components[i] = component[1] - end - end - - return section_line_components -end - ---- Creates configured section according to its components' config. ---- @param section ComponentConfig[] Array of components' config in a section. ---- @param component_type ComponentType Which section that components will be. ---- @return [Line, boolean][] section_components Configured components array whose components are in section. -local function config_section(section, component_type) - --- @type [Line, boolean][] - local section_components = {} - - for _, component in ipairs(section) do - local component_group = Yatline[component.type] - - if component_group then -- Does component group exist? - if component.custom then -- Does component is custom? - if component.name ~= nil and component.name ~= "" and #component.name ~= 0 then -- Does component name is valid? - section_components[#section_components + 1] = -- Insert component to the table. - { component_group.create(component.name, component_type), component_group.has_separator } - end - else - local getter = component_group.get[component.name] -- Get component function that will be called. - - if getter then -- Does function exist? - local output -- Output of the function. - if component.params then -- Does component function has parameters? - output = getter(component_group.get, table.unpack(component.params)) - else - output = getter() - end - - if output ~= nil and output ~= "" then -- Does component is not empty? - section_components[#section_components + 1] = -- Insert component to the table. - { component_group.create(output, component_type), component_group.has_separator } - end - end - end - end - end - - return section_components -end - ---- Automatically creates and configures either header-line or status-line. ---- @param side SideConfig Configuration of either left or right side. ---- @param in_side Side Which side components will be. ---- @return Line left_line Consist of components that are in left side of the line. ---- @return Line right_line Consist of components that are in right side of the line. ---- @see config_section To know how components are gotten from sections' config. ---- @see config_components_separators To know how components are connected with separators. -local function config_line(side, in_side) - -- Configures components of sections. - local section_a_components = config_section(side.section_a, ComponentType.A) - local section_b_components = config_section(side.section_b, ComponentType.B) - local section_c_components = config_section(side.section_c, ComponentType.C) - - local num_section_b_components = #section_b_components - local num_section_c_components = #section_c_components - - -- Connects components of section by separators. - local section_a_line_components = config_components_separators( - section_a_components, - ComponentType.A, - in_side, - num_section_b_components, - num_section_c_components - ) - local section_b_line_components = config_components_separators( - section_b_components, - ComponentType.B, - in_side, - num_section_b_components, - num_section_c_components - ) - local section_c_line_components = config_components_separators( - section_c_components, - ComponentType.C, - in_side, - num_section_b_components, - num_section_c_components - ) - - if in_side == Side.RIGHT then -- Reverse the order of the components if it is in the right side. - section_a_line_components = reverse_order(section_a_line_components) - section_b_line_components = reverse_order(section_b_line_components) - section_c_line_components = reverse_order(section_c_line_components) - end - - -- Combines components of section into single components. - local section_a_line = ui.Line(section_a_line_components) - local section_b_line = ui.Line(section_b_line_components) - local section_c_line = ui.Line(section_c_line_components) - - if in_side == Side.LEFT then - return ui.Line({ section_a_line, section_b_line, section_c_line }) - else - return ui.Line({ section_c_line, section_b_line, section_a_line }) - end -end - ---- Checks if either header-line or status-line contains components. ---- @param line LineConfig Configuration of either header-line or status-line. ---- @return boolean show_line Returns yes if it contains components, otherwise returns no. -local function show_line(line) - for _, side in pairs(line) do - for _, section in pairs(side) do - if #section ~= 0 then - return true - end - end - end - - return false -end - ---- Creates and configures paragraph which is used as left or right of either ---- header-line or status-line. ---- @param area Rect The area where paragraph will be placed in. ---- @param line? Line The line which used in paragraph. It is optional. ---- @return Paragraph paragraph Configured parapgraph. -local function config_paragraph(area, line) - local line_array = { line } or {} - if Yatline.config.show_background then - return apply_style_table(ui.Text(line_array):area(area), Yatline.config.style_c) - else - return ui.Text(line_array):area(area) - end -end - -return { - setup = function(_, config, pre_theme) - if config then - -- Fills the sections that are not given if the line exists. - for _, line in ipairs({ "header_line", "status_line" }) do - if config[line] then - for _, side in ipairs({ "left", "right" }) do - if config[line][side] then - for _, section in ipairs({ "section_a", "section_b", "section_c" }) do - config[line][side][section] = config[line][side][section] or {} - end - else - config[line][side] = {} - for _, section in ipairs({ "section_a", "section_b", "section_c" }) do - config[line][side][section] = {} - end - end - end - end - end - - -- Get the current theme according to the light/dark mode. (default: config.theme) - config.theme = (not rt.term.light and config.theme_dark) - or (rt.term.light and config.theme_light) - or config.theme - - -- Extracts theme fields to the config unless that fields does not exists. - if config.theme then - for key, value in pairs(config.theme) do - if not config[key] then - config[key] = value - end - end - end - - -- Extracts config fields to the YatlineConfig if that fields exists. - for key, value in pairs(config) do - if Yatline.config[key] then - Yatline.config[key] = value - end - end - end - - -- Extracts pre_theme fields to the YatlineConfig if that fields exists. - if pre_theme then - for key, value in pairs(pre_theme) do - if Yatline.config[key] then - Yatline.config[key] = value - end - end - end - - if Yatline.config.display_header_line then -- Controls displaying header-line. - if show_line(Yatline.config.header_line) then -- Controls recoding of header-line. - -- Empties default Yazi header-line. - Header._left = {} - Header._right = {} - - Header.redraw = function(self) - -- Gets Yazi components. - local right = self:children_redraw(self.RIGHT) - self._right_width = right:width() - local left = self:children_redraw(self.LEFT) - - -- Gets Yatline components. - local left_line = config_line(Yatline.config.header_line.left, Side.LEFT) - local right_line = config_line(Yatline.config.header_line.right, Side.RIGHT) - - return { - config_paragraph(self._area, ui.Line({ left_line, left })), -- Styles left_line if show_background set. - ui.Line({ right, right_line }):area(self._area):align(ui.Align.RIGHT), - } - end - end - else - Header.redraw = function() - return {} - end - end - - if Yatline.config.display_status_line then -- Controls displaying status-line. - if show_line(Yatline.config.status_line) then -- Controls recoding of status-line. - -- Empties default Yazi status-line. - Status._left = {} - Status._right = {} - - Status.redraw = function(self) - -- Gets Yazi components. - local left = self:children_redraw(self.LEFT) - local right = self:children_redraw(self.RIGHT) - - -- Gets Yatline components. - local left_line = config_line(Yatline.config.status_line.left, Side.LEFT) - local right_line = config_line(Yatline.config.status_line.right, Side.RIGHT) - - local sum_right = ui.Line({ right, right_line }) -- Needed for error prevention. - return { - config_paragraph(self._area, ui.Line({ left_line, left })), -- Styles left_line if show_background set. - sum_right:area(self._area):align(ui.Align.RIGHT), - table.unpack(ui.redraw(Progress:new(self._area, sum_right:width()))), -- Inserts Progress bar. - } - end - end - else - Status.redraw = function() - return {} - end - end - - Root.layout = function(self) - local constraints = {} - -- Sets Yazi layout according to the given positions. - for _, component in ipairs(Yatline.config.component_positions) do - if - (component == "header" and Yatline.config.display_header_line) - or (component == "status" and Yatline.config.display_status_line) - then - table.insert(constraints, ui.Constraint.Length(1)) - elseif component == "tab" then - table.insert(constraints, ui.Constraint.Fill(1)) - end - end - - self._chunks = ui.Layout():direction(ui.Layout.VERTICAL):constraints(constraints):split(self._area) - end - - Root.build = function(self) - local childrens = {} - -- Fills the layout according to the given positions. - local i = 1 - for _, component in ipairs(Yatline.config.component_positions) do - if component == "header" and Yatline.config.display_header_line then - table.insert(childrens, Header:new(self._chunks[i], cx.active)) - i = i + 1 - elseif component == "tab" then - table.insert(childrens, Tab:new(self._chunks[i], cx.active)) - i = i + 1 - elseif component == "status" and Yatline.config.display_status_line then - table.insert(childrens, Status:new(self._chunks[i], cx.active)) - i = i + 1 - end - end - - table.insert(childrens, Modal:new(self._area)) - - self._children = childrens - end - end, -} |
