diff --git a/modules/home/programs/terminal/tools/yazi/configs/init.lua b/modules/home/programs/terminal/tools/yazi/configs/init.lua index 6a08b4e78..bd0d30b5c 100644 --- a/modules/home/programs/terminal/tools/yazi/configs/init.lua +++ b/modules/home/programs/terminal/tools/yazi/configs/init.lua @@ -54,12 +54,12 @@ Status:children_add(function() local formatted_created = nil local formatted_modified = nil - if h.cha.created then - formatted_created = tostring(os.date("%Y-%m-%d %H:%M:%S", math.floor(h.cha.created))) + if h.cha.ctime then + formatted_created = tostring(os.date("%Y-%m-%d %H:%M:%S", math.floor(h.cha.ctime))) end - if h.cha.modified then - formatted_modified = tostring(os.date("%Y-%m-%d %H:%M:%S", math.floor(h.cha.modified))) + if h.cha.mtime then + formatted_modified = tostring(os.date("%Y-%m-%d %H:%M:%S", math.floor(h.cha.mtime))) end if formatted_created and formatted_modified then @@ -79,7 +79,7 @@ end, 400, Status.RIGHT) function Linemode:custom() local year = os.date("%Y") - local time = (self._file.cha.modified or 0) // 1 + local time = (self._file.cha.mtime or 0) // 1 if time > 0 and os.date("%Y", time) == year then time = os.date("%b %d %H:%M", time) diff --git a/modules/home/programs/terminal/tools/yazi/configs/plugins/chmod.yazi/init.lua b/modules/home/programs/terminal/tools/yazi/configs/plugins/chmod.yazi/init.lua index bfb097060..6d6c1c474 100644 --- a/modules/home/programs/terminal/tools/yazi/configs/plugins/chmod.yazi/init.lua +++ b/modules/home/programs/terminal/tools/yazi/configs/plugins/chmod.yazi/init.lua @@ -15,25 +15,28 @@ return { local urls = selected_or_hovered() if #urls == 0 then - return ya.notify { title = "Chmod", content = "No file selected", level = "warn", timeout = 5 } + return ya.notify({ title = "Chmod", content = "No file selected", level = "warn", timeout = 5 }) end - local value, event = ya.input { + local value, event = ya.input({ title = "Chmod:", position = { "top-center", y = 3, w = 40 }, - } + }) if event ~= 1 then return end local status, err = Command("chmod"):arg(value):args(urls):spawn():wait() if not status or not status.success then - ya.notify { + ya.notify({ title = "Chmod", - content = string.format("Chmod with selected files failed, exit code %s", status and status.code or err), + content = string.format( + "Chmod with selected files failed, exit code %s", + status and status.code or err + ), level = "error", timeout = 5, - } + }) end end, } diff --git a/modules/home/programs/terminal/tools/yazi/configs/plugins/diff.yazi/init.lua b/modules/home/programs/terminal/tools/yazi/configs/plugins/diff.yazi/init.lua index 32eb5fcb3..275e4edb3 100644 --- a/modules/home/programs/terminal/tools/yazi/configs/plugins/diff.yazi/init.lua +++ b/modules/home/programs/terminal/tools/yazi/configs/plugins/diff.yazi/init.lua @@ -1,9 +1,9 @@ local function info(content) - return ya.notify { + return ya.notify({ title = "Diff", content = content, timeout = 5, - } + }) end local selected_url = ya.sync(function() @@ -29,6 +29,8 @@ return { local output, err = Command("diff"):arg("-Naur"):arg(tostring(a)):arg(tostring(b)):output() if not output then return info("Failed to run diff, error: " .. err) + elseif output.stdout == "" then + return info("No differences found") end ya.clipboard(output.stdout) diff --git a/modules/home/programs/terminal/tools/yazi/configs/plugins/full-border.yazi/init.lua b/modules/home/programs/terminal/tools/yazi/configs/plugins/full-border.yazi/init.lua index e6c89176e..76a3fd65d 100644 --- a/modules/home/programs/terminal/tools/yazi/configs/plugins/full-border.yazi/init.lua +++ b/modules/home/programs/terminal/tools/yazi/configs/plugins/full-border.yazi/init.lua @@ -1,3 +1,12 @@ +-- TODO: remove this once v0.4 is released +local v4 = function(typ, area, ...) + if typ == "bar" then + return ui.Table and ui.Bar(...):area(area) or ui.Bar(area, ...) + else + return ui.Table and ui.Border(...):area(area) or ui.Border(area, ...) + end +end + local function setup(_, opts) local type = opts and opts.type or ui.Border.ROUNDED local old_build = Tab.build @@ -5,10 +14,11 @@ local function setup(_, opts) Tab.build = function(self, ...) local bar = function(c, x, y) if x <= 0 or x == self._area.w - 1 then - return ui.Bar(ui.Rect.default, ui.Bar.TOP) + return v4("bar", ui.Rect.default, ui.Bar.TOP) end - return ui.Bar( + return v4( + "bar", ui.Rect({ x = x, y = math.max(0, y), @@ -28,9 +38,9 @@ local function setup(_, opts) local style = THEME.manager.border_style self._base = ya.list_merge(self._base or {}, { - ui.Border(self._area, ui.Border.ALL):type(type):style(style), - ui.Bar(self._chunks[1], ui.Bar.RIGHT):style(style), - ui.Bar(self._chunks[3], ui.Bar.LEFT):style(style), + v4("border", self._area, ui.Border.ALL):type(type):style(style), + v4("bar", self._chunks[1], ui.Bar.RIGHT):style(style), + v4("bar", self._chunks[3], ui.Bar.LEFT):style(style), bar("┬", c[1].right - 1, c[1].y), bar("┴", c[1].right - 1, c[1].bottom - 1), diff --git a/modules/home/programs/terminal/tools/yazi/configs/plugins/glow.yazi/init.lua b/modules/home/programs/terminal/tools/yazi/configs/plugins/glow.yazi/init.lua index f7b6275a5..6611a7365 100644 --- a/modules/home/programs/terminal/tools/yazi/configs/plugins/glow.yazi/init.lua +++ b/modules/home/programs/terminal/tools/yazi/configs/plugins/glow.yazi/init.lua @@ -45,7 +45,7 @@ function M:peek() ) else lines = lines:gsub("\t", string.rep(" ", PREVIEW.tab_size)) - ya.preview_widgets(self, { ui.Paragraph.parse(self.area, lines) }) + ya.preview_widgets(self, { ui.Text.parse(self.area, lines) }) end end @@ -66,7 +66,7 @@ function M:fallback_to_builtin() ya.manager_emit("peek", { bound, only_if = self.file.url, upper_bound = true }) elseif err and not err:find("cancelled", 1, true) then ya.preview_widgets(self, { - ui.Paragraph(self.area, { ui.Line(err):reverse() }), + ui.Text(self.area, { ui.Line(err):reverse() }), }) end end diff --git a/modules/home/programs/terminal/tools/yazi/configs/plugins/hide-preview.yazi/init.lua b/modules/home/programs/terminal/tools/yazi/configs/plugins/hide-preview.yazi/init.lua index 504032165..f74f4d742 100644 --- a/modules/home/programs/terminal/tools/yazi/configs/plugins/hide-preview.yazi/init.lua +++ b/modules/home/programs/terminal/tools/yazi/configs/plugins/hide-preview.yazi/init.lua @@ -1,3 +1,5 @@ +--- @sync entry + local function entry(st) if st.old then Tab.layout, st.old = st.old, nil @@ -18,4 +20,8 @@ local function entry(st) ya.app_emit("resize", {}) end -return { entry = entry } +local function enabled(st) + return st.old ~= nil +end + +return { entry = entry, enabled = enabled } diff --git a/modules/home/programs/terminal/tools/yazi/configs/plugins/jump-to-char.yazi/init.lua b/modules/home/programs/terminal/tools/yazi/configs/plugins/jump-to-char.yazi/init.lua index 827cde97f..8074df1a9 100644 --- a/modules/home/programs/terminal/tools/yazi/configs/plugins/jump-to-char.yazi/init.lua +++ b/modules/home/programs/terminal/tools/yazi/configs/plugins/jump-to-char.yazi/init.lua @@ -6,7 +6,9 @@ local changed = ya.sync(function(st, new) return b or not cx.active.finder end) -local escape = function(s) return s == "." and "\\." or s end +local escape = function(s) + return s == "." and "\\." or s +end return { entry = function() @@ -15,7 +17,7 @@ return { cands[#cands + 1] = { on = AVAILABLE_CHARS:sub(i, i) } end - local idx = ya.which { cands = cands, silent = true } + local idx = ya.which({ cands = cands, silent = true }) if not idx then return end diff --git a/modules/home/programs/terminal/tools/yazi/configs/plugins/max-preview.yazi/init.lua b/modules/home/programs/terminal/tools/yazi/configs/plugins/max-preview.yazi/init.lua index d3d6083cf..81f637174 100644 --- a/modules/home/programs/terminal/tools/yazi/configs/plugins/max-preview.yazi/init.lua +++ b/modules/home/programs/terminal/tools/yazi/configs/plugins/max-preview.yazi/init.lua @@ -1,3 +1,5 @@ +--- @sync entry + local function entry(st) if st.old then Tab.layout, st.old = st.old, nil @@ -17,4 +19,8 @@ local function entry(st) ya.app_emit("resize", {}) end -return { entry = entry } +local function enabled(st) + return st.old ~= nil +end + +return { entry = entry, enabled = enabled } diff --git a/modules/home/programs/terminal/tools/yazi/configs/plugins/miller.yazi/init.lua b/modules/home/programs/terminal/tools/yazi/configs/plugins/miller.yazi/init.lua index f75820314..47a8a9f89 100644 --- a/modules/home/programs/terminal/tools/yazi/configs/plugins/miller.yazi/init.lua +++ b/modules/home/programs/terminal/tools/yazi/configs/plugins/miller.yazi/init.lua @@ -4,7 +4,7 @@ local M = {} -function M:peek() +function M:peek(job) local child = Command("mlr") :args({ "--icsv", @@ -16,60 +16,43 @@ function M:peek() "--value-color", "lightsteelblue1", "cat", - tostring(self.file.url), + tostring(job.file.url), }) :stdout(Command.PIPED) :stderr(Command.PIPED) :spawn() if not child then - return self:fallback_to_builtin() + return require("code"):peek(job) end - local limit = self.area.h + local limit = job.area.h local i, lines = 0, "" repeat local next, event = child:read_line() if event == 1 then - return self:fallback_to_builtin() + return require("code"):peek(job) elseif event ~= 0 then break end i = i + 1 - if i > self.skip then + if i > job.skip then lines = lines .. next end - until i >= self.skip + limit + until i >= job.skip + limit child:start_kill() - if self.skip > 0 and i < self.skip + limit then - ya.manager_emit( - "peek", - { tostring(math.max(0, i - limit)), only_if = tostring(self.file.url), upper_bound = "" } - ) + if job.skip > 0 and i < job.skip + limit then + ya.manager_emit("peek", { math.max(0, i - limit), only_if = job.file.url, upper_bound = true }) else lines = lines:gsub("\t", string.rep(" ", PREVIEW.tab_size)) - ya.preview_widgets(self, { ui.Paragraph.parse(self.area, lines) }) + ya.preview_widgets(job, { ui.Text.parse(lines):area(job.area) }) end end -function M:seek(units) - local h = cx.active.current.hovered - if h and h.url == self.file.url then - local step = math.floor(units * self.area.h / 10) - ya.manager_emit("peek", { - tostring(math.max(0, cx.active.preview.skip + step)), - only_if = tostring(self.file.url), - }) - end -end - -function M:fallback_to_builtin() - local _, bound = ya.preview_code(self) - if bound then - ya.manager_emit("peek", { tostring(bound), only_if = tostring(self.file.url), upper_bound = "" }) - end +function M:seek(job) + require("code"):seek(job) end return M diff --git a/modules/home/programs/terminal/tools/yazi/configs/plugins/ouch.yazi/init.lua b/modules/home/programs/terminal/tools/yazi/configs/plugins/ouch.yazi/init.lua index fd828adb9..e4cc74877 100644 --- a/modules/home/programs/terminal/tools/yazi/configs/plugins/ouch.yazi/init.lua +++ b/modules/home/programs/terminal/tools/yazi/configs/plugins/ouch.yazi/init.lua @@ -4,15 +4,15 @@ local M = {} -function M:peek() +function M:peek(job) local child = Command("ouch") - :args({ "l", "-t", "-y", tostring(self.file.url) }) + :args({ "l", "-t", "-y", tostring(job.file.url) }) :stdout(Command.PIPED) :stderr(Command.PIPED) :spawn() - local limit = self.area.h - local file_name = string.match(tostring(self.file.url), ".*[/\\](.*)") - local lines = string.format("\x1b[2m %s\x1b[0m\n", file_name) + local limit = job.area.h + local file_name = string.match(tostring(job.file.url), ".*[/\\](.*)") + local lines = string.format("📁 \x1b[2m%s\x1b[0m\n", file_name) local num_lines = 1 local num_skip = 0 repeat @@ -24,7 +24,7 @@ function M:peek() end if line:find("Archive", 1, true) ~= 1 and line:find("[INFO]", 1, true) ~= 1 then - if num_skip >= self.skip then + if num_skip >= job.skip then lines = lines .. line num_lines = num_lines + 1 else @@ -34,26 +34,116 @@ function M:peek() until num_lines >= limit child:start_kill() - if self.skip > 0 and num_lines < limit then - ya.manager_emit("peek", { - tostring(math.max(0, self.skip - (limit - num_lines))), - only_if = tostring(self.file.url), - upper_bound = "", - }) + if job.skip > 0 and num_lines < limit then + ya.manager_emit( + "peek", + { + tostring(math.max(0, job.skip - (limit - num_lines))), + only_if = tostring(job.file.url), + upper_bound = "", + } + ) else - ya.preview_widgets(self, { ui.Paragraph.parse(self.area, lines) }) + ya.preview_widgets(job, { ui.Text(lines):area(job.area) }) end end -function M:seek(units) +function M:seek(job) local h = cx.active.current.hovered - if h and h.url == self.file.url then - local step = math.floor(units * self.area.h / 10) + if h and h.url == job.file.url then + local step = math.floor(job.units * job.area.h / 10) ya.manager_emit("peek", { math.max(0, cx.active.preview.skip + step), - only_if = tostring(self.file.url), + only_if = tostring(job.file.url), }) end end +-- Check if file exists +local function file_exists(name) + local f = io.open(name, "r") + if f ~= nil then + io.close(f) + return true + else + return false + end +end + +-- Get the files that need to be compressed and infer a default archive name +local get_compression_target = ya.sync(function() + local tab = cx.active + local default_name + local paths = {} + if #tab.selected == 0 then + if tab.current.hovered then + local name = tab.current.hovered.name + default_name = name + table.insert(paths, name) + else + return + end + else + default_name = tab.current.cwd:name() + for _, url in pairs(tab.selected) do + table.insert(paths, tostring(url)) + end + -- The compression targets are aquired, now unselect them + ya.manager_emit("escape", {}) + end + return paths, default_name +end) + +local function invoke_compress_command(paths, name) + local cmd_output, err_code = + Command("ouch"):args({ "c", "-y" }):args(paths):arg(name):stderr(Command.PIPED):output() + if err_code ~= nil then + ya.notify({ + title = "Failed to run ouch command", + content = "Status: " .. err_code, + timeout = 5.0, + level = "error", + }) + elseif not cmd_output.status.success then + ya.notify({ + title = "Compression failed: status code " .. cmd_output.status.code, + content = cmd_output.stderr, + timeout = 5.0, + level = "error", + }) + end +end + +function M:entry(job) + local default_fmt = job.args[1] + + ya.manager_emit("escape", { visual = true }) + + -- Get the files that need to be compressed and infer a default archive name + local paths, default_name = get_compression_target() + + -- Get archive name from user + local output_name, name_event = ya.input({ + title = "Create archive:", + value = default_name .. "." .. default_fmt, + position = { "top-center", y = 3, w = 40 }, + }) + if name_event ~= 1 then + return + end + + -- Get confirmation if file exists + if file_exists(output_name) then + local confirm, confirm_event = ya.input({ + title = "Overwrite " .. output_name .. "? (y/N)", + position = { "top-center", y = 3, w = 40 }, + }) + if not (confirm_event == 1 and confirm:lower() == "y") then + return + end + end + + invoke_compress_command(paths, output_name) +end + return M diff --git a/modules/home/programs/terminal/tools/yazi/configs/plugins/smart-enter.yazi/init.lua b/modules/home/programs/terminal/tools/yazi/configs/plugins/smart-enter.yazi/init.lua index 2bdbbba8b..e2f201603 100644 --- a/modules/home/programs/terminal/tools/yazi/configs/plugins/smart-enter.yazi/init.lua +++ b/modules/home/programs/terminal/tools/yazi/configs/plugins/smart-enter.yazi/init.lua @@ -1,12 +1,12 @@ -return { - entry = function() - local h = cx.active.current.hovered - if h and h.cha.is_dir then - ya.manager_emit("enter", { hovered = true }) - elseif h and h:is_selected() then - ya.manager_emit("open", {}) - else - ya.manager_emit("open", { hovered = true }) - end - end, -} +--- @sync entry + +local function setup(self, opts) + self.open_multi = opts.open_multi +end + +local function entry(self) + local h = cx.active.current.hovered + ya.manager_emit(h and h.cha.is_dir and "enter" or "open", { hovered = not self.open_multi }) +end + +return { entry = entry, setup = setup } diff --git a/modules/home/programs/terminal/tools/yazi/configs/plugins/smart-filter.yazi/init.lua b/modules/home/programs/terminal/tools/yazi/configs/plugins/smart-filter.yazi/init.lua index 39198db95..c62a7a38a 100644 --- a/modules/home/programs/terminal/tools/yazi/configs/plugins/smart-filter.yazi/init.lua +++ b/modules/home/programs/terminal/tools/yazi/configs/plugins/smart-filter.yazi/init.lua @@ -12,12 +12,12 @@ local hovered = ya.sync(function() end) local function prompt() - return ya.input { + return ya.input({ title = "Smart filter:", position = { "center", w = 50 }, realtime = true, debounce = 0.1, - } + }) end local function entry() @@ -35,7 +35,7 @@ local function entry() local h = hovered() if h.unique and h.is_dir then ya.manager_emit("escape", { filter = true }) - ya.manager_emit("enter", { h.url }) + ya.manager_emit("enter", {}) input = prompt() elseif event == 1 then ya.manager_emit("escape", { filter = true }) diff --git a/modules/home/programs/terminal/tools/yazi/keymap/manager.nix b/modules/home/programs/terminal/tools/yazi/keymap/manager.nix index 573cdf0b2..9b993a447 100644 --- a/modules/home/programs/terminal/tools/yazi/keymap/manager.nix +++ b/modules/home/programs/terminal/tools/yazi/keymap/manager.nix @@ -14,17 +14,17 @@ in prepend_keymap = [ { on = [ "l" ]; - run = "plugin --sync smart-enter"; + run = "plugin smart-enter"; desc = "Enter the child directory, or open the file"; } { on = [ "" ]; - run = "plugin --sync smart-enter"; + run = "plugin smart-enter"; desc = "Enter the child directory, or open the file"; } { on = [ "" ]; - run = "shell 'dragon -x -i -T \"$1\"' --confirm"; + run = "shell 'dragon -x -i -T \"$1\"'"; desc = "Drag and drop files"; } { @@ -47,12 +47,12 @@ in } { on = [ "T" ]; - run = "plugin --sync hide-preview"; + run = "plugin hide-preview"; desc = "Hide or show preview"; } # { # on = [ "T" ]; - # run = "plugin --sync max-preview"; + # run = "plugin max-preview"; # desc = "Maximize or restore preview"; # } { diff --git a/modules/home/programs/terminal/tools/yazi/keymap/manager/selection.nix b/modules/home/programs/terminal/tools/yazi/keymap/manager/selection.nix index d493dadb7..d1a998f0e 100644 --- a/modules/home/programs/terminal/tools/yazi/keymap/manager/selection.nix +++ b/modules/home/programs/terminal/tools/yazi/keymap/manager/selection.nix @@ -5,7 +5,7 @@ _: { { on = [ "" ]; run = [ - "select --state=none" + "toggle" "arrow 1" ]; desc = "Toggle the current selection state"; @@ -22,12 +22,12 @@ _: { } { on = [ "" ]; - run = "select_all --state=true"; + run = "toggle_all --state=on"; desc = "Select all files"; } { on = [ "" ]; - run = "select_all --state=none"; + run = "toggle_all"; desc = "Inverse selection of all files"; } ]; diff --git a/modules/home/programs/terminal/tools/yazi/keymap/manager/sorting.nix b/modules/home/programs/terminal/tools/yazi/keymap/manager/sorting.nix index 098ada424..cb1d256d6 100644 --- a/modules/home/programs/terminal/tools/yazi/keymap/manager/sorting.nix +++ b/modules/home/programs/terminal/tools/yazi/keymap/manager/sorting.nix @@ -22,7 +22,7 @@ _: { "," "c" ]; - run = "sort created --reverse=no"; + run = "sort btime --reverse=no"; desc = "Sort by creation time"; } { @@ -30,7 +30,7 @@ _: { "," "C" ]; - run = "sort created --reverse"; + run = "sort btime --reverse"; desc = "Sort by creation time (reverse)"; } { @@ -38,7 +38,7 @@ _: { "," "m" ]; - run = "sort modified --reverse=no"; + run = "sort mtime --reverse=no"; desc = "Sort by modified time"; } { @@ -46,7 +46,7 @@ _: { "," "M" ]; - run = "sort modified --reverse"; + run = "sort mtime --reverse"; desc = "Sort by modified time (reverse)"; } { diff --git a/modules/home/programs/terminal/tools/yazi/yazi.nix b/modules/home/programs/terminal/tools/yazi/yazi.nix index 94fd04a4e..6e9c4a8df 100644 --- a/modules/home/programs/terminal/tools/yazi/yazi.nix +++ b/modules/home/programs/terminal/tools/yazi/yazi.nix @@ -210,7 +210,7 @@ ]; } { - mime = "inode/x-empty"; + mime = "inode/empty"; use = [ "edit" "reveal" @@ -245,35 +245,35 @@ ]; } { - mime = "application/x-tar"; + mime = "application/tar"; use = [ "extract" "reveal" ]; } { - mime = "application/x-bzip"; + mime = "application/bzip"; use = [ "extract" "reveal" ]; } { - mime = "application/x-bzip2"; + mime = "application/bzip2"; use = [ "extract" "reveal" ]; } { - mime = "application/x-7z-compressed"; + mime = "application/7z-compressed"; use = [ "extract" "reveal" ]; } { - mime = "application/x-rar"; + mime = "application/rar"; use = [ "extract" "reveal" @@ -376,7 +376,7 @@ run = "code"; } { - mime = "*/x-wine-extension-ini"; + mime = "*/wine-extension-ini"; run = "code"; } # JSON @@ -413,23 +413,23 @@ run = "archive"; } { - mime = "application/x-tar"; + mime = "application/tar"; run = "ouch"; } { - mime = "application/x-bzip"; + mime = "application/bzip"; run = "ouch"; } { - mime = "application/x-bzip2"; + mime = "application/bzip2"; run = "ouch"; } { - mime = "application/x-7z-compressed"; + mime = "application/7z-compressed"; run = "ouch"; } { - mime = "application/x-rar"; + mime = "application/rar"; run = "ouch"; } { @@ -456,7 +456,7 @@ ]; # create - create_title = "Create:"; + # create_title = "Create:"; create_origin = "top-center"; create_offset = [ 0 @@ -562,7 +562,7 @@ ]; }; - select = { + pick = { open_title = "Open with:"; open_origin = "hovered"; open_offset = [ diff --git a/modules/home/theme/catppuccin/yazi/filetype.nix b/modules/home/theme/catppuccin/yazi/filetype.nix index ddc509eff..acb7634b5 100644 --- a/modules/home/theme/catppuccin/yazi/filetype.nix +++ b/modules/home/theme/catppuccin/yazi/filetype.nix @@ -18,31 +18,7 @@ in fg = catppuccin.colors.yellow.hex; } { - mime = "application/zip"; - fg = catppuccin.colors.pink.hex; - } - { - mime = "application/gzip"; - fg = catppuccin.colors.pink.hex; - } - { - mime = "application/x-tar"; - fg = catppuccin.colors.pink.hex; - } - { - mime = "application/x-bzip"; - fg = catppuccin.colors.pink.hex; - } - { - mime = "application/x-bzip2"; - fg = catppuccin.colors.pink.hex; - } - { - mime = "application/x-7z-compressed"; - fg = catppuccin.colors.pink.hex; - } - { - mime = "application/x-rar"; + mime = "application/{tar,bzip*,7z-compressed,xz,rar,gzip}"; fg = catppuccin.colors.pink.hex; } # Orphan symbolic links