diff --git a/cspell.json b/cspell.json index 436947da..c1046902 100644 --- a/cspell.json +++ b/cspell.json @@ -1 +1 @@ -{"version":"0.2","language":"en","words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink"],"flagWords":[]} \ No newline at end of file +{"flagWords":[],"version":"0.2","language":"en","words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes"]} \ No newline at end of file diff --git a/yazi-plugin/preset/compat.lua b/yazi-plugin/preset/compat.lua index 96cf8fbf..bc76fcc9 100644 --- a/yazi-plugin/preset/compat.lua +++ b/yazi-plugin/preset/compat.lua @@ -4,37 +4,43 @@ Manager = {} Folder = {} File = {} -local b = false -function __yazi_check_and_warn_deprecated_api() - if b then - return - end - - local warn = function(name) - ya.notify { - title = "Deprecated API", - content = string.format( - [[The `%s` global variable has been removed in Yazi v0.3, please remove it from your `init.lua`. +local function warn(name) + ya.notify { + title = "Deprecated API", + content = string.format( + [[The `%s` global variable has been removed in Yazi v0.3, please remove it from your `init.lua`. See https://github.com/sxyazi/yazi/pull/1257 for details.]], - name - ), - timeout = 20, - level = "warn", - } + name + ), + timeout = 20, + level = "warn", + } +end + +local b1, b2, b3 = false, false, false +function __yazi_check_and_warn_deprecated_api() + if not b1 then + for _ in pairs(Manager) do + b1 = true + warn("Manager") + break + end end - b = true - for _ in pairs(Manager) do - warn("Manager") - break + if not b2 then + for _ in pairs(Folder) do + b2 = true + warn("Folder") + break + end end - for _ in pairs(Folder) do - warn("Folder") - break - end - for _ in pairs(File) do - warn("File") - break + + if not b3 then + for _ in pairs(File) do + b3 = true + warn("File") + break + end end end diff --git a/yazi-plugin/preset/components/current.lua b/yazi-plugin/preset/components/current.lua index 77c07ea9..e4d30883 100644 --- a/yazi-plugin/preset/components/current.lua +++ b/yazi-plugin/preset/components/current.lua @@ -29,14 +29,17 @@ function Current:render() return self:empty() end - local items = {} + local entities, linemodes = {}, {} for _, f in ipairs(files) do - items[#items + 1] = ui.ListItem(Entity:render(f)):style(Entity:style(f)) + linemodes[#linemodes + 1] = Linemode:new(f):render() + + local entity = Entity:new(f) + entities[#entities + 1] = ui.ListItem(entity:render()):style(entity:style()) end return { - ui.List(self._area, items), - ui.Paragraph(self._area, Linemode:render(files)):align(ui.Paragraph.RIGHT), + ui.List(self._area, entities), + ui.Paragraph(self._area, linemodes):align(ui.Paragraph.RIGHT), } end diff --git a/yazi-plugin/preset/components/entity.lua b/yazi-plugin/preset/components/entity.lua index 95d42b56..dd31c67e 100644 --- a/yazi-plugin/preset/components/entity.lua +++ b/yazi-plugin/preset/components/entity.lua @@ -2,36 +2,27 @@ Entity = { _inc = 1000, } -function Entity:style(file) - local style = file:style() - if not file:is_hovered() then - return style - elseif file:in_preview() then - return style and style:patch(THEME.manager.preview_hovered) or THEME.manager.preview_hovered - else - return style and style:patch(THEME.manager.hovered) or THEME.manager.hovered - end -end +function Entity:new(file) return setmetatable({ _file = file }, { __index = self }) end -function Entity:icon(file) - local icon = file:icon() +function Entity:icon() + local icon = self._file:icon() if not icon then return ui.Line("") - elseif file:is_hovered() then + elseif self._file:is_hovered() then return ui.Line(" " .. icon.text .. " ") else return ui.Line(" " .. icon.text .. " "):style(icon.style) end end -function Entity:prefix(file) - local prefix = file:prefix() or "" +function Entity:prefix() + local prefix = self._file:prefix() or "" return ui.Line(prefix ~= "" and prefix .. "/" or "") end -function Entity:highlights(file) - local name = file.name:gsub("\r", "?", 1) - local highlights = file:highlights() +function Entity:highlights() + local name = self._file.name:gsub("\r", "?", 1) + local highlights = self._file:highlights() if not highlights or #highlights == 0 then return ui.Line(name) end @@ -50,12 +41,12 @@ function Entity:highlights(file) return ui.Line(spans) end -function Entity:found(file) - if not file:is_hovered() then +function Entity:found() + if not self._file:is_hovered() then return ui.Line {} end - local found = file:found() + local found = self._file:found() if not found then return ui.Line {} end @@ -66,23 +57,34 @@ function Entity:found(file) } end -function Entity:symlink(file) +function Entity:symlink() if not MANAGER.show_symlink then return ui.Line {} end - local to = file.link_to + local to = self._file.link_to return ui.Line(to and { ui.Span(" -> " .. tostring(to)):italic() } or {}) end -function Entity:render(file) +function Entity:render() local lines = {} for _, child in ipairs(self._children) do - lines[#lines + 1] = child[1](self, file) + lines[#lines + 1] = child[1](self) end return ui.Line(lines) end +function Entity:style() + local s = self._file:style() + if not self._file:is_hovered() then + return s + elseif self._file:in_preview() then + return s and s:patch(THEME.manager.preview_hovered) or THEME.manager.preview_hovered + else + return s and s:patch(THEME.manager.hovered) or THEME.manager.hovered + end +end + -- Initialize children Entity._children = { { Entity.icon, id = 1, order = 1000 }, diff --git a/yazi-plugin/preset/components/header.lua b/yazi-plugin/preset/components/header.lua index d08e2e0e..f24f08de 100644 --- a/yazi-plugin/preset/components/header.lua +++ b/yazi-plugin/preset/components/header.lua @@ -1,5 +1,9 @@ Header = { + LEFT = 0, + RIGHT = 1, + _id = "header", + _inc = 1000, } function Header:new(area, tab) @@ -9,7 +13,12 @@ function Header:new(area, tab) }, { __index = self }) end -function Header:cwd(max) +function Header:cwd() + local max = self._area.w - self._right_width + if max <= 0 then + return ui.Span("") + end + local s = ya.readable_path(tostring(self._tab.current.cwd)) .. self:flags() return ui.Span(ya.truncate(s, { max = max, rtl = true })):style(THEME.manager.cwd) end @@ -75,8 +84,10 @@ function Header:tabs() end function Header:render() - local right = ui.Line { self:count(), self:tabs() } - local left = ui.Line { self:cwd(math.max(0, self._area.w - right:width())) } + local right = self:children_render(self.RIGHT) + self._right_width = right:width() + + local left = self:children_render(self.LEFT) return { ui.Paragraph(self._area, { left }), ui.Paragraph(self._area, { right }):align(ui.Paragraph.RIGHT), @@ -89,3 +100,40 @@ function Header:click(event, up) end function Header:scroll(event, step) end function Header:touch(event, step) end + +-- Initialize children +Header._left = { + { Header.cwd, id = 1, order = 1000 }, +} +Header._right = { + { Header.count, id = 1, order = 1000 }, + { Header.tabs, id = 2, order = 2000 }, +} + +function Header:children_add(fn, order, side) + self._inc = self._inc + 1 + local children = side == self.RIGHT and self._right or self._left + + children[#children + 1] = { fn, id = self._inc, order = order } + table.sort(children, function(a, b) return a.order < b.order end) + + return self._inc +end + +function Header:children_remove(id, side) + local children = side == self.RIGHT and self._right or self._left + for i, child in ipairs(children) do + if child.id == id then + table.remove(children, i) + break + end + end +end + +function Header:children_render(side) + local lines = {} + for _, child in ipairs(side == self.RIGHT and self._right or self._left) do + lines[#lines + 1] = child[1](self) + end + return ui.Line(lines) +end diff --git a/yazi-plugin/preset/components/linemode.lua b/yazi-plugin/preset/components/linemode.lua index 3e4ccc6a..1658d724 100644 --- a/yazi-plugin/preset/components/linemode.lua +++ b/yazi-plugin/preset/components/linemode.lua @@ -2,7 +2,9 @@ Linemode = { _inc = 1000, } -function Linemode:solo(file) +function Linemode:new(file) return setmetatable({ _file = file }, { __index = self }) end + +function Linemode:solo() local mode = cx.active.conf.linemode if mode == "none" or mode == "solo" then return ui.Line("") @@ -14,18 +16,18 @@ function Linemode:solo(file) return ui.Line { ui.Span(" "), - self[mode](self, file), + self[mode](self), ui.Span(" "), } end -function Linemode:size(file) - local size = file:size() +function Linemode:size() + local size = self._file:size() return ui.Line(size and ya.readable_size(size) or "") end -function Linemode:ctime(file) - local time = (file.cha.created or 0) // 1 +function Linemode:ctime() + local time = (self._file.cha.created or 0) // 1 if time == 0 then return ui.Line("") elseif os.date("%Y", time) == os.date("%Y") then @@ -35,8 +37,8 @@ function Linemode:ctime(file) end end -function Linemode:mtime(file) - local time = (file.cha.modified or 0) // 1 +function Linemode:mtime() + local time = (self._file.cha.modified or 0) // 1 if time == 0 then return ui.Line("") elseif os.date("%Y", time) == os.date("%Y") then @@ -46,20 +48,20 @@ function Linemode:mtime(file) end end -function Linemode:permissions(file) return ui.Line(file.cha:permissions() or "") end +function Linemode:permissions() return ui.Line(self._file.cha:permissions() or "") end -function Linemode:owner(file) - local user = file.cha.uid and ya.user_name(file.cha.uid) or file.cha.uid - local group = file.cha.gid and ya.group_name(file.cha.gid) or file.cha.gid +function Linemode:owner() + local user = self._file.cha.uid and ya.user_name(self._file.cha.uid) or self._file.cha.uid + local group = self._file.cha.gid and ya.group_name(self._file.cha.gid) or self._file.cha.gid return ui.Line(string.format("%s:%s", user or "-", group or "-")) end -function Linemode:render(files) +function Linemode:render() local lines = {} - for _, f in ipairs(files) do - lines[#lines + 1] = self:children_render(f) + for _, child in ipairs(self._children) do + lines[#lines + 1] = child[1](self) end - return lines + return ui.Line(lines) end -- Initialize children @@ -82,11 +84,3 @@ function Linemode:children_remove(id) end end end - -function Linemode:children_render(file) - local lines = {} - for _, child in ipairs(self._children) do - lines[#lines + 1] = child[1](self, file) - end - return ui.Line(lines) -end diff --git a/yazi-plugin/preset/components/parent.lua b/yazi-plugin/preset/components/parent.lua index e9de37b5..3caa5cec 100644 --- a/yazi-plugin/preset/components/parent.lua +++ b/yazi-plugin/preset/components/parent.lua @@ -17,7 +17,8 @@ function Parent:render() local items = {} for _, f in ipairs(self._folder.window) do - items[#items + 1] = ui.ListItem(Entity:render(f)):style(Entity:style(f)) + local entity = Entity:new(f) + items[#items + 1] = ui.ListItem(entity:render()):style(entity:style()) end return { diff --git a/yazi-plugin/preset/plugins/folder.lua b/yazi-plugin/preset/plugins/folder.lua index e853bc92..3f2064d3 100644 --- a/yazi-plugin/preset/plugins/folder.lua +++ b/yazi-plugin/preset/plugins/folder.lua @@ -20,7 +20,8 @@ function M:peek() local items = {} for _, f in ipairs(folder.window) do - items[#items + 1] = ui.ListItem(Entity:render(f)):style(Entity:style(f)) + local entity = Entity:new(f) + items[#items + 1] = ui.ListItem(entity:render()):style(entity:style()) end ya.preview_widgets(self, {