Update 2025-04-16

Update 2025-04-07

Update 2025-04-12

Update 2025-04-16
This commit is contained in:
Kristofers Solo 2025-04-05 13:06:19 +03:00
parent f298468e99
commit 1077cee297
19 changed files with 369 additions and 261 deletions

View File

@ -1,2 +0,0 @@
services:
git.modulation.lv: gitlab:git.modulation.lv/api/v4/projects

View File

@ -1,22 +1,32 @@
#
# GENERAL OPTIONS # GENERAL OPTIONS
# #
[options] [options]
PgpFetch PgpFetch
Devel Devel
Provides Provides
DevelSuffixes = -git -cvs -snv -bzr -darcs -always -hg DevelSuffixes = -git -cvs -svn -bzr -darcs -always -hg -fossil
UpgradeMenu #AurOnly
#BottomUp BottomUp
#RemoveMake RemoveMake
#SudoLoop #SudoLoop
#UseAsk #UseAsk
#CombineUpgrade #SaveChanges
#ClearAfter #CombinedUpgrade
#NewsOnUpgrade CleanAfter
#UpgradeMenu
NewsOnUpgrade
#LocalRepo
#Chroot
#Sign
#SignDb
#KeepRepoCache
# #
# Binary OPTIONS # Binary OPTIONS
# #
[bin] [bin]
FileManager = yazi FileManager = yazi
Sudo = /bin/doas #MFlags = --skippgpcheck
Sudo = doas

View File

@ -58,6 +58,7 @@ export HISTFILE="$XDG_DATA_HOME/history"
export HISTFILE="$XDG_STATE_HOME/bash/history" export HISTFILE="$XDG_STATE_HOME/bash/history"
export INPUTRC="$XDG_CONFIG_HOME/shell/inputrc" export INPUTRC="$XDG_CONFIG_HOME/shell/inputrc"
export IPYTHONDIR="$XDG_CONFIG_HOME/ipython" export IPYTHONDIR="$XDG_CONFIG_HOME/ipython"
export JUPYTER_CONFIG_DIR="$XDG_CONFIG_HOME/jupyter"
export KERAS_HOME="$XDG_DATA_HOME/keras" export KERAS_HOME="$XDG_DATA_HOME/keras"
export KODI_DATA="$XDG_DATA_HOME/kodi" export KODI_DATA="$XDG_DATA_HOME/kodi"
export MBSYNCRC="$XDG_CONFIG_HOME/mbsync/config" export MBSYNCRC="$XDG_CONFIG_HOME/mbsync/config"

View File

@ -1,4 +1,4 @@
-- require("relative-motions"):setup({ show_numbers = "relative", show_motion = true }) require("relative-motions"):setup({ show_numbers = "relative", show_motion = true })
require("full-border"):setup() require("full-border"):setup()
require("augment-command"):setup({ require("augment-command"):setup({
prompt = false, prompt = false,

View File

@ -13,30 +13,25 @@ use = "Reledia/hexyl"
rev = "228a9ef" rev = "228a9ef"
hash = "cdc65cfe4e60e1bf5afe5769d074fa9c" hash = "cdc65cfe4e60e1bf5afe5769d074fa9c"
[[plugin.deps]]
use = "Reledia/miller"
rev = "40e0265"
hash = "2d6d77583162aaf0a599e7a3091b5878"
[[plugin.deps]] [[plugin.deps]]
use = "Sonico98/exifaudio" use = "Sonico98/exifaudio"
rev = "4379fcf" rev = "7ff7141"
hash = "a8e15d3c21c02a5af41d46ed04778a02" hash = "666ccba55119fba4c25b8ad354b2855c"
[[plugin.deps]] [[plugin.deps]]
use = "dedukun/relative-motions" use = "dedukun/relative-motions"
rev = "8103065" rev = "61ae795"
hash = "9f13f0740fa3a0c18e47ec6fb62ddfaa" hash = "65d576a76597aac2a428dc7ec0eda2ce"
[[plugin.deps]] [[plugin.deps]]
use = "hankertrix/augment-command" use = "hankertrix/augment-command"
rev = "f4a904c" rev = "269e3cf"
hash = "60dff62dcb958c83b7c84dfb3d5ef68b" hash = "f8c8ddd15b2227340fa7f585df71580"
[[plugin.deps]] [[plugin.deps]]
use = "imsi32/yatline" use = "imsi32/yatline"
rev = "9328205" rev = "6b0fc1e"
hash = "3e51d1fd8a2e481fcfa8eab1251d1c5f" hash = "ab115c6cc77f5710c27f39dfa2f3d4d"
[[plugin.deps]] [[plugin.deps]]
use = "kirasok/torrent-preview" use = "kirasok/torrent-preview"
@ -45,38 +40,38 @@ hash = "6af40ce6b2cd849b5fa32de04a598b06"
[[plugin.deps]] [[plugin.deps]]
use = "ndtoan96/ouch" use = "ndtoan96/ouch"
rev = "ce6fb75" rev = "558188d"
hash = "ed6c185514109d7c5463f609282b220c" hash = "2d0afef7b50747c543c4304004a72cec"
[[plugin.deps]] [[plugin.deps]]
use = "pirafrank/what-size" use = "pirafrank/what-size"
rev = "b23e3a4" rev = "f1c6b69"
hash = "98e5f5af3efd3ba8bc2db0720187cc83" hash = "6e789212eb41d937bab04877ca361099"
[[plugin.deps]] [[plugin.deps]]
use = "yazi-rs/plugins:git" use = "yazi-rs/plugins:git"
rev = "3d0c7c6" rev = "9a09505"
hash = "771f18427fb75fb19990ce602bb322f4" hash = "e0ada736ea676c2bbb3ec705a49526ef"
[[plugin.deps]] [[plugin.deps]]
use = "yazi-rs/plugins:max-preview" use = "yazi-rs/plugins:max-preview"
rev = "3d0c7c6" rev = "9a09505"
hash = "a8025f2bb311e869069364fba01abffc" hash = "a8025f2bb311e869069364fba01abffc"
[[plugin.deps]] [[plugin.deps]]
use = "yazi-rs/plugins:chmod" use = "yazi-rs/plugins:chmod"
rev = "3d0c7c6" rev = "9a09505"
hash = "2f1053f89d1a301a648ab181d0948e38" hash = "2f1053f89d1a301a648ab181d0948e38"
[[plugin.deps]] [[plugin.deps]]
use = "yazi-rs/plugins:full-border" use = "yazi-rs/plugins:full-border"
rev = "3d0c7c6" rev = "9a09505"
hash = "9dce00232a0e0e2502565c7aa2b0ed4e" hash = "1f3dad061209081a6b04dd6ff2cb06c7"
[[plugin.deps]] [[plugin.deps]]
use = "yazi-rs/plugins:hide-preview" use = "yazi-rs/plugins:hide-preview"
rev = "3d0c7c6" rev = "9a09505"
hash = "53f826884e2c7e521cecc492a7f31d7e" hash = "53f826884e2c7e521cecc492a7f31d7e"
[flavor] [flavor]
deps = [ ] deps = []

View File

@ -40,7 +40,7 @@ plugin.
## Requirements ## Requirements
- [Yazi][yazi-link] v25.2.26+ - [Yazi][yazi-link] v25.3.2+
- [`7z` or `7zz` command][7z-link] - [`7z` or `7zz` command][7z-link]
- [`file` command][file-command-link] - [`file` command][file-command-link]

View File

@ -1,4 +1,4 @@
--- @since 25.2.26 --- @since 25.3.2
-- Plugin to make some Yazi commands smarter -- Plugin to make some Yazi commands smarter
-- Written in Lua 5.4 -- Written in Lua 5.4
@ -211,6 +211,7 @@ local ARCHIVE_FILE_EXTENSIONS = {
gzip = true, gzip = true,
rar = true, rar = true,
s7z = true, s7z = true,
svgz = true,
tar = true, tar = true,
tbz = true, tbz = true,
tbz2 = true, tbz2 = true,
@ -1043,11 +1044,17 @@ local get_tab_preferences = ya.sync(function(_)
return tab_preferences return tab_preferences
end) end)
-- [TODO]: Remove the stage.is_loading once stage() is stable
-- https://github.com/sxyazi/yazi/issues/2545
--
-- Function to get if Yazi is loading -- Function to get if Yazi is loading
---@type fun(): boolean ---@type fun(): boolean
local yazi_is_loading = ya.sync( local yazi_is_loading = ya.sync(function(_)
function(_) return cx.active.current.stage.is_loading end local stage = cx.active.current.stage
) local is_func, loaded = pcall(stage)
if not is_func then return stage.is_loading end
return not loaded
end)
-- Function to wait until Yazi is loaded -- Function to wait until Yazi is loaded
---@return nil ---@return nil
@ -2772,19 +2779,6 @@ local function execute_create(item_url, is_directory, args, config)
enter_or_open_created_item(item_url, is_directory, args, config) enter_or_open_created_item(item_url, is_directory, args, config)
end end
-- Function to get the confirm component border foreground colour
---@type fun(): Color
local get_confirm_border_fg = ya.sync(
--
-- I have no idea how to type it such that the theme
-- is accessible only within a synchronous function,
-- so disabling the diagnostic seems to be the
-- best course of action
---@diagnostic disable-next-line: undefined-global
function() return THEME.confirm.border.fg end
)
-- Function to handle the create command -- Function to handle the create command
---@type CommandFunction ---@type CommandFunction
local function handle_create(args, config) local function handle_create(args, config)
@ -2850,7 +2844,7 @@ local function handle_create(args, config)
ui.Line("Will overwrite the following file:") ui.Line("Will overwrite the following file:")
:align(ui.Line.CENTER), :align(ui.Line.CENTER),
ui.Line(string.rep("", DEFAULT_CONFIRM_OPTIONS.pos.w - 2)) ui.Line(string.rep("", DEFAULT_CONFIRM_OPTIONS.pos.w - 2))
:style(ui.Style():fg(get_confirm_border_fg())) :style(ui.Style(th.confirm.border))
:align(ui.Line.LEFT), :align(ui.Line.LEFT),
ui.Line(tostring(full_url)):align(ui.Line.LEFT), ui.Line(tostring(full_url)):align(ui.Line.LEFT),
}):wrap(ui.Text.WRAP_TRIM) }):wrap(ui.Text.WRAP_TRIM)
@ -3387,6 +3381,11 @@ local wraparound_arrow = ya.sync(function(_, args)
ya.mgr_emit("reveal", merge_tables(args, { item_url })) ya.mgr_emit("reveal", merge_tables(args, { item_url }))
end) end)
-- [TODO]: Make use of the arrow prev and arrow next commands
-- once stabilised.
-- PR: https://github.com/sxyazi/yazi/pull/2485
-- Docs: https://yazi-rs.github.io/docs/configuration/keymap/#manager.arrow
--
-- Function to handle the arrow command -- Function to handle the arrow command
---@type CommandFunction ---@type CommandFunction
local function handle_arrow(args, config) local function handle_arrow(args, config)

View File

@ -185,8 +185,11 @@ end
function M:preload(job) function M:preload(job)
local cache = ya.file_cache(job) local cache = ya.file_cache(job)
if not cache or fs.cha(cache) then if not cache or fs.cha(cache) then
if not ya.__250127 then -- TODO: remove this
return 1 return 1
end end
return true
end
local mediainfo_template = 'General;"\ local mediainfo_template = 'General;"\
$if(%Track%,Title: %Track%,)\ $if(%Track%,Title: %Track%,)\
@ -222,10 +225,13 @@ Channels: %Channel(s)%"\
:output() :output()
if not output then if not output then
if not ya.__250127 then -- TODO: remove this
return 0 return 0
end end
return true, Err("Couldn't extract cover art, error: %s", err)
end
return fs.write(cache, output.stdout) and 1 or 2 return fs.write(cache, output.stdout) and true or false
end end
return M return M

View File

@ -6,7 +6,7 @@ local function setup(_, opts)
Tab.build = function(self, ...) Tab.build = function(self, ...)
local bar = function(c, x, y) local bar = function(c, x, y)
if x <= 0 or x == self._area.w - 1 then if x <= 0 or x == self._area.w - 1 or th.mgr.border_symbol ~= "" then
return ui.Bar(ui.Bar.TOP) return ui.Bar(ui.Bar.TOP)
end end

View File

@ -1,7 +1,7 @@
# git.yazi # git.yazi
> [!NOTE] > [!NOTE]
> Yazi v25.2.7 or later is required for this plugin to work. > Yazi v25.2.26 or later is required for this plugin to work.
Show the status of Git file changes as linemode in the file list. Show the status of Git file changes as linemode in the file list.
@ -39,38 +39,38 @@ run = "git"
You can customize the [Style](https://yazi-rs.github.io/docs/plugins/layout#style) of the status sign with: You can customize the [Style](https://yazi-rs.github.io/docs/plugins/layout#style) of the status sign with:
- `THEME.git.modified` - `th.git.modified`
- `THEME.git.added` - `th.git.added`
- `THEME.git.untracked` - `th.git.untracked`
- `THEME.git.ignored` - `th.git.ignored`
- `THEME.git.deleted` - `th.git.deleted`
- `THEME.git.updated` - `th.git.updated`
For example: For example:
```lua ```lua
-- ~/.config/yazi/init.lua -- ~/.config/yazi/init.lua
THEME.git = THEME.git or {} th.git = th.git or {}
THEME.git.modified = ui.Style():fg("blue") th.git.modified = ui.Style():fg("blue")
THEME.git.deleted = ui.Style():fg("red"):bold() th.git.deleted = ui.Style():fg("red"):bold()
``` ```
You can also customize the text of the status sign with: You can also customize the text of the status sign with:
- `THEME.git.modified_sign` - `th.git.modified_sign`
- `THEME.git.added_sign` - `th.git.added_sign`
- `THEME.git.untracked_sign` - `th.git.untracked_sign`
- `THEME.git.ignored_sign` - `th.git.ignored_sign`
- `THEME.git.deleted_sign` - `th.git.deleted_sign`
- `THEME.git.updated_sign` - `th.git.updated_sign`
For example: For example:
```lua ```lua
-- ~/.config/yazi/init.lua -- ~/.config/yazi/init.lua
THEME.git = THEME.git or {} th.git = th.git or {}
THEME.git.modified_sign = "M" th.git.modified_sign = "M"
THEME.git.deleted_sign = "D" th.git.deleted_sign = "D"
``` ```
## License ## License

View File

@ -1,29 +1,45 @@
--- @since 25.2.7 --- @since 25.4.4
local WIN = ya.target_family() == "windows" local WINDOWS = ya.target_family() == "windows"
local PATS = {
{ "[MT]", 6 }, -- Modified -- The code of supported git status,
{ "[AC]", 5 }, -- Added -- also used to determine which status to show for directories when they contain different statuses
{ "?$", 4 }, -- Untracked -- see `bubble_up`
{ "!$", 3 }, -- Ignored local CODES = {
{ "D", 2 }, -- Deleted excluded = 100, -- ignored directory
{ "U", 1 }, -- Updated ignored = 6, -- ignored file
{ "[AD][AD]", 1 }, -- Updated untracked = 5,
modified = 4,
added = 3,
deleted = 2,
updated = 1,
unknown = 0,
}
local PATTERNS = {
{ "!$", CODES.ignored },
{ "?$", CODES.untracked },
{ "[MT]", CODES.modified },
{ "[AC]", CODES.added },
{ "D", CODES.deleted },
{ "U", CODES.updated },
{ "[AD][AD]", CODES.updated },
} }
local function match(line) local function match(line)
local signs = line:sub(1, 2) local signs = line:sub(1, 2)
for _, p in ipairs(PATS) do for _, p in ipairs(PATTERNS) do
local path local path, pattern, code = nil, p[1], p[2]
if signs:find(p[1]) then if signs:find(pattern) then
path = line:sub(4, 4) == '"' and line:sub(5, -2) or line:sub(4) path = line:sub(4, 4) == '"' and line:sub(5, -2) or line:sub(4)
path = WIN and path:gsub("/", "\\") or path path = WINDOWS and path:gsub("/", "\\") or path
end end
if not path then if not path then
elseif path:find("[/\\]$") then elseif path:find("[/\\]$") then
return p[2] == 3 and 30 or p[2], path:sub(1, -2) -- Mark the ignored directory as `excluded`, so we can process it further within `propagate_down`
return code == CODES.ignored and CODES.excluded or code, path:sub(1, -2)
else else
return p[2], path return code, path
end end
end end
end end
@ -44,34 +60,36 @@ local function root(cwd)
if cha and (cha.is_dir or is_worktree(next)) then if cha and (cha.is_dir or is_worktree(next)) then
return tostring(cwd) return tostring(cwd)
end end
cwd = cwd:parent() cwd = cwd.parent
until not cwd until not cwd
end end
local function bubble_up(changed) local function bubble_up(changed)
local new, empty = {}, Url("") local new, empty = {}, Url("")
for k, v in pairs(changed) do for path, code in pairs(changed) do
if v ~= 3 and v ~= 30 then if code ~= CODES.ignored then
local url = Url(k):parent() local url = Url(path).parent
while url and url ~= empty do while url and url ~= empty do
local s = tostring(url) local s = tostring(url)
new[s] = (new[s] or 0) > v and new[s] or v new[s] = (new[s] or CODES.unknown) > code and new[s] or code
url = url:parent() url = url.parent
end end
end end
end end
return new return new
end end
local function propagate_down(ignored, cwd, repo) local function propagate_down(excluded, cwd, repo)
local new, rel = {}, cwd:strip_prefix(repo) local new, rel = {}, cwd:strip_prefix(repo)
for k, v in pairs(ignored) do for _, path in ipairs(excluded) do
if v == 30 then if rel:starts_with(path) then
if rel:starts_with(k) then -- If `cwd` is a subdirectory of an excluded directory, also mark it as `excluded`
new[tostring(repo:join(rel))] = 30 new[tostring(cwd)] = CODES.excluded
elseif cwd == repo:join(k):parent() then elseif cwd == repo:join(path).parent then
new[k] = 3 -- If `path` is a direct subdirectory of `cwd`, mark it as `ignored`
end new[path] = CODES.ignored
else
-- Skipping, we only care about `cwd` itself and its direct subdirectories for maximum performance
end end
end end
return new return new
@ -80,84 +98,84 @@ end
local add = ya.sync(function(st, cwd, repo, changed) local add = ya.sync(function(st, cwd, repo, changed)
st.dirs[cwd] = repo st.dirs[cwd] = repo
st.repos[repo] = st.repos[repo] or {} st.repos[repo] = st.repos[repo] or {}
for k, v in pairs(changed) do for path, code in pairs(changed) do
if v == 0 then if code == CODES.unknown then
st.repos[repo][k] = nil st.repos[repo][path] = nil
elseif v == 30 then elseif code == CODES.excluded then
st.dirs[k] = "" -- Mark the directory with a special value `excluded` so that it can be distinguished during UI rendering
st.dirs[path] = CODES.excluded
else else
st.repos[repo][k] = v st.repos[repo][path] = code
end end
end end
ya.render() ya.render()
end) end)
local remove = ya.sync(function(st, cwd) local remove = ya.sync(function(st, cwd)
local dir = st.dirs[cwd] local repo = st.dirs[cwd]
if not dir then if not repo then
return return
end end
ya.render() ya.render()
st.dirs[cwd] = nil st.dirs[cwd] = nil
if not st.repos[dir] then if not st.repos[repo] then
return return
end end
for _, r in pairs(st.dirs) do for _, r in pairs(st.dirs) do
if r == dir then if r == repo then
return return
end end
end end
st.repos[dir] = nil st.repos[repo] = nil
end) end)
local function setup(st, opts) local function setup(st, opts)
st.dirs = {} st.dirs = {} -- Mapping between a directory and its corresponding repository
st.repos = {} st.repos = {} -- Mapping between a repository and the status of each of its files
opts = opts or {} opts = opts or {}
opts.order = opts.order or 1500 opts.order = opts.order or 1500
-- Chosen by ChatGPT fairly, PRs are welcome to adjust them local t = th.git or {}
local t = THEME.git or {}
local styles = { local styles = {
[6] = t.modified and ui.Style(t.modified) or ui.Style():fg("#ffa500"), [CODES.ignored] = t.ignored and ui.Style(t.ignored) or ui.Style():fg("darkgray"),
[5] = t.added and ui.Style(t.added) or ui.Style():fg("#32cd32"), [CODES.untracked] = t.untracked and ui.Style(t.untracked) or ui.Style():fg("magenta"),
[4] = t.untracked and ui.Style(t.untracked) or ui.Style():fg("#a9a9a9"), [CODES.modified] = t.modified and ui.Style(t.modified) or ui.Style():fg("yellow"),
[3] = t.ignored and ui.Style(t.ignored) or ui.Style():fg("#696969"), [CODES.added] = t.added and ui.Style(t.added) or ui.Style():fg("green"),
[2] = t.deleted and ui.Style(t.deleted) or ui.Style():fg("#ff4500"), [CODES.deleted] = t.deleted and ui.Style(t.deleted) or ui.Style():fg("red"),
[1] = t.updated and ui.Style(t.updated) or ui.Style():fg("#1e90ff"), [CODES.updated] = t.updated and ui.Style(t.updated) or ui.Style():fg("yellow"),
} }
local signs = { local signs = {
[6] = t.modified_sign and t.modified_sign or "", [CODES.ignored] = t.ignored_sign or "",
[5] = t.added_sign and t.added_sign or "", [CODES.untracked] = t.untracked_sign or "?",
[4] = t.untracked_sign and t.untracked_sign or "", [CODES.modified] = t.modified_sign or "",
[3] = t.ignored_sign and t.ignored_sign or "", [CODES.added] = t.added_sign or "",
[2] = t.deleted_sign and t.deleted_sign or "", [CODES.deleted] = t.deleted_sign or "",
[1] = t.updated_sign and t.updated_sign or "U", [CODES.updated] = t.updated_sign or "",
} }
Linemode:children_add(function(self) Linemode:children_add(function(self)
local url = self._file.url local url = self._file.url
local dir = st.dirs[tostring(url:parent())] local repo = st.dirs[tostring(url.base)]
local change local code
if dir then if repo then
change = dir == "" and 3 or st.repos[dir][tostring(url):sub(#dir + 2)] code = repo == CODES.excluded and CODES.ignored or st.repos[repo][tostring(url):sub(#repo + 2)]
end end
if not change or signs[change] == "" then if not code or signs[code] == "" then
return "" return ""
elseif self._file:is_hovered() then elseif self._file.is_hovered then
return ui.Line { " ", signs[change] } return ui.Line { " ", signs[code] }
else else
return ui.Line { " ", ui.Span(signs[change]):style(styles[change]) } return ui.Line { " ", ui.Span(signs[code]):style(styles[code]) }
end end
end, opts.order) end, opts.order)
end end
local function fetch(_, job) local function fetch(_, job)
local cwd = job.files[1].url:parent() local cwd = job.files[1].url.base
local repo = root(cwd) local repo = root(cwd)
if not repo then if not repo then
remove(tostring(cwd)) remove(tostring(cwd))
@ -165,8 +183,8 @@ local function fetch(_, job)
end end
local paths = {} local paths = {}
for _, f in ipairs(job.files) do for _, file in ipairs(job.files) do
paths[#paths + 1] = tostring(f.url) paths[#paths + 1] = tostring(file.url)
end end
-- stylua: ignore -- stylua: ignore
@ -180,27 +198,28 @@ local function fetch(_, job)
return true, Err("Cannot spawn `git` command, error: %s", err) return true, Err("Cannot spawn `git` command, error: %s", err)
end end
local changed, ignored = {}, {} local changed, excluded = {}, {}
for line in output.stdout:gmatch("[^\r\n]+") do for line in output.stdout:gmatch("[^\r\n]+") do
local sign, path = match(line) local code, path = match(line)
if sign == 30 then if code == CODES.excluded then
ignored[path] = sign excluded[#excluded + 1] = path
else else
changed[path] = sign changed[path] = code
end end
end end
if job.files[1].cha.is_dir then if job.files[1].cha.is_dir then
ya.dict_merge(changed, bubble_up(changed)) ya.dict_merge(changed, bubble_up(changed))
ya.dict_merge(changed, propagate_down(ignored, cwd, Url(repo))) end
else ya.dict_merge(changed, propagate_down(excluded, cwd, Url(repo)))
ya.dict_merge(changed, propagate_down(ignored, cwd, Url(repo)))
-- Reset the status of any files that don't appear in the output of `git status` to `unknown`,
-- so that cleaning up outdated statuses from `st.repos`
for _, path in ipairs(paths) do
local s = path:sub(#repo + 2)
changed[s] = changed[s] or CODES.unknown
end end
for _, p in ipairs(paths) do
local s = p:sub(#repo + 2)
changed[s] = changed[s] or 0
end
add(tostring(cwd), repo, changed) add(tostring(cwd), repo, changed)
return false return false

View File

@ -1,7 +0,0 @@
Copyright © 2024 Reledia <reledia@prontonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,27 +0,0 @@
# miller.yazi
[Miller](https://github.com/johnkerl/miller) now in [yazi](https://github.com/sxyazi/yazi). To install, use the command `ya pack -a Reledia/miller` and add to your `yazi.toml`:
```toml
[plugin]
prepend_previewers = [
{ mime = "text/csv", run = "miller"},
]
```
## Preview
![preview](https://github.com/Reledia/miller.yazi/blob/main/preview.png?raw=true)
## Color
To change colors of keys and values, edit the `init.lua` file after the `--key-color` and `--value-color` flags. To view a list of possible colors, use `mlr --list-color-names`. Make sure to have miller installed and inside your PATH.
## Other types of file
To adapt this plugin to the other format supported from miller (like json):
- copy the plugin folder
- change the name of the copied folder into miller\_(fmt)
- change the `--icsv` flag inside `init.lua` to `--i(fmt)`
- add the correct mime/name rule into `prepend_previewers` and the exec as `miller_(fmt)`

View File

@ -10,7 +10,12 @@
## Installation ## Installation
If you use Yazi from latest main branch ### Yazi package manager
```bash
ya pack -a ndtoan96/ouch
```
### Git
```bash ```bash
# Linux/macOS # Linux/macOS
git clone https://github.com/ndtoan96/ouch.yazi.git ~/.config/yazi/plugins/ouch.yazi git clone https://github.com/ndtoan96/ouch.yazi.git ~/.config/yazi/plugins/ouch.yazi
@ -22,18 +27,6 @@ git clone https://github.com/ndtoan96/ouch.yazi.git %AppData%\yazi\config\plugin
git clone https://github.com/ndtoan96/ouch.yazi.git "$($env:APPDATA)\yazi\config\plugins\ouch.yazi" git clone https://github.com/ndtoan96/ouch.yazi.git "$($env:APPDATA)\yazi\config\plugins\ouch.yazi"
``` ```
If you use Yazi < 0.4.3
```bash
# Linux/macOS
git clone --branch v0.4.0 --single-branch https://github.com/ndtoan96/ouch.yazi.git ~/.config/yazi/plugins/ouch.yazi
# Windows with cmd
git clone --branch v0.4.0 --single-branch https://github.com/ndtoan96/ouch.yazi.git %AppData%\yazi\config\plugins\ouch.yazi
# Windows with powershell
git clone --branch v0.4.0 --single-branch https://github.com/ndtoan96/ouch.yazi.git "$($env:APPDATA)\yazi\config\plugins\ouch.yazi"
```
Make sure you have [ouch](https://github.com/ouch-org/ouch) installed and in your `PATH`. Make sure you have [ouch](https://github.com/ouch-org/ouch) installed and in your `PATH`.
## Usage ## Usage
@ -64,11 +57,13 @@ For compession, add this to your `keymap.toml`:
```toml ```toml
[[manager.prepend_keymap]] [[manager.prepend_keymap]]
on = ["C"] on = ["C"]
run = "plugin ouch --args=zip" run = "plugin ouch"
desc = "Compress with ouch" desc = "Compress with ouch"
``` ```
The `--args=zip` part tells the plugin that default format is `zip`. You can change that to whatever format you want. The plugin uses `zip` format by default. You can change the format when you name the output file, `ouch` will detect format based on file extension.
And, for example, if you would like to set `7z` as default format, you can use `plugin ouch 7z`.
### Decompression ### Decompression
This plugin does not provide a decompression feature because it already is supported by Yazi. This plugin does not provide a decompression feature because it already is supported by Yazi.

View File

@ -112,6 +112,9 @@ end
function M:entry(job) function M:entry(job)
local default_fmt = job.args[1] local default_fmt = job.args[1]
if default_fmt == nil then
default_fmt = "zip"
end
ya.manager_emit("escape", { visual = true }) ya.manager_emit("escape", { visual = true })

View File

@ -92,7 +92,7 @@ end)
local render_numbers = ya.sync(function(_, mode) local render_numbers = ya.sync(function(_, mode)
ya.render() ya.render()
Entity.number = function(_, index, file, hovered) Entity.number = function(_, index, total, file, hovered)
local idx local idx
if mode == SHOW_NUMBERS_RELATIVE then if mode == SHOW_NUMBERS_RELATIVE then
idx = math.abs(hovered - index) idx = math.abs(hovered - index)
@ -106,13 +106,13 @@ local render_numbers = ya.sync(function(_, mode)
end end
end end
local num_format = "%" .. #tostring(total) .. "d"
-- emulate vim's hovered offset -- emulate vim's hovered offset
if idx >= 100 then if hovered == index then
return ui.Span(string.format("%4d ", idx)) return ui.Span(string.format(num_format .. " ", idx))
elseif hovered == index then
return ui.Span(string.format("%3d ", idx))
else else
return ui.Span(string.format(" %3d ", idx)) return ui.Span(string.format(" " .. num_format, idx))
end end
end end
@ -124,7 +124,13 @@ local render_numbers = ya.sync(function(_, mode)
local hovered_index local hovered_index
for i, f in ipairs(files) do for i, f in ipairs(files) do
if f:is_hovered() then -- TODO: Removed f:is_hovered() support in next Yazi release
if type(f.is_hovered) == "boolean" then
hovered = f.is_hovered
else
hovered = f:is_hovered()
end
if hovered then
hovered_index = i hovered_index = i
break break
end end
@ -135,7 +141,8 @@ local render_numbers = ya.sync(function(_, mode)
linemodes[#linemodes + 1] = Linemode:new(f):redraw() linemodes[#linemodes + 1] = Linemode:new(f):redraw()
local entity = Entity:new(f) local entity = Entity:new(f)
entities[#entities + 1] = ui.Line({ Entity:number(i, f, hovered_index), entity:redraw() }):style(entity:style()) entities[#entities + 1] = ui.Line({ Entity:number(i, #self._folder.files, f, hovered_index), entity:redraw() })
:style(entity:style())
end end
return { return {

View File

@ -4,12 +4,24 @@ A plugin for [yazi](https://github.com/sxyazi/yazi) to calculate the size of the
## Compatibility ## Compatibility
what-size supports Yazi on Linux, macOS, and Windows.
### OS
- Linux since first commit
- macOS since commit `42c6a0efb7245badb16781da5380be1a1705f3f2` ([link](https://github.com/pirafrank/what-size.yazi/commit/42c6a0efb7245badb16781da5380be1a1705f3f2))
- Windows since commit `4a56ead2a84c5969791fb17416e0b451ab906c5d` ([link](https://github.com/pirafrank/what-size.yazi/commit/4a56ead2a84c5969791fb17416e0b451ab906c5d))
### Yazi
- yazi `25.x` since commit `fce1778d911621dc57796cdfdf11dcda3c2e28de` ([link](https://github.com/pirafrank/what-size.yazi/commit/fce1778d911621dc57796cdfdf11dcda3c2e28de)).
- yazi `0.4.x` since commit `2780de5aeef1ed16d1973dd6e0cd4d630c900d56` ([link](https://github.com/pirafrank/what-size.yazi/commit/2780de5aeef1ed16d1973dd6e0cd4d630c900d56)). - yazi `0.4.x` since commit `2780de5aeef1ed16d1973dd6e0cd4d630c900d56` ([link](https://github.com/pirafrank/what-size.yazi/commit/2780de5aeef1ed16d1973dd6e0cd4d630c900d56)).
- yazi `0.3.x` up to commit `f08f7f2d5c94958ac4cb66c51a7c24b4319c6c93` ([link](https://github.com/pirafrank/what-size.yazi/commit/f08f7f2d5c94958ac4cb66c51a7c24b4319c6c93)). - yazi `0.3.x` up to commit `f08f7f2d5c94958ac4cb66c51a7c24b4319c6c93` ([link](https://github.com/pirafrank/what-size.yazi/commit/f08f7f2d5c94958ac4cb66c51a7c24b4319c6c93)).
## Requirements ## Requirements
- `du` on Linux. macOS and Windows support is planned. - `du` on Linux and macOS
- PowerShell on Windows
## Installation ## Installation
@ -28,17 +40,44 @@ prepend_keymap = [
] ]
``` ```
If you want to copy the result to clipboard, you can add `--clipboard` or `-c` as first argument: If you want to copy the result to clipboard, you can add `--clipboard` or `-c` as 2nd positional argument:
```toml ```toml
[manager] [manager]
prepend_keymap = [ prepend_keymap = [
{ on = [ ".", "s" ], run = "plugin what-size --args='--clipboard'", desc = "Calc size of selection or cwd" }, { on = [ ".", "s" ], run = "plugin what-size -- '--clipboard'", desc = "Calc size of selection or cwd" },
]
```
```toml
[manager]
prepend_keymap = [
{ on = [ ".", "s" ], run = "plugin what-size -- '-c'", desc = "Calc size of selection or cwd" },
] ]
``` ```
Change to whatever keybinding you like. Change to whatever keybinding you like.
## Feedback
If you have any feedback, suggestions, or ideas please let me know by opening an issue.
## Dev setup
Check the debug config [here](https://yazi-rs.github.io/docs/plugins/overview/#debugging).
To get debug logs while develoing use `ya.dbg()` in your code, then set the `YAZI_LOG` environment variable to `debug` before running Yazi.
```sh
YAZI_LOG=debug yazi
```
Logs will be saved to `~.local/state/yazi/yazi.log` file.
## Contributing
Contributions are welcome. Please fork the repository and submit a PR.
## License ## License
MIT MIT

View File

@ -1,6 +1,6 @@
-- function to get paths of selected elements or current directory -- function to get paths of selected elements or current directory
-- of no elements are selected -- if no elements are selected
local get_paths = ya.sync(function() local get_paths = ya.sync(function()
local paths = {} local paths = {}
-- get selected files -- get selected files
@ -18,43 +18,68 @@ local get_paths = ya.sync(function()
return paths return paths
end) end)
-- Function to get total size from du output -- Function to get total size from output
local get_total_size = function(s) -- Unix use `du`, Windows use PowerShell
local function get_total_size(items)
local is_windows = package.config:sub(1,1) == '\\'
if is_windows then
local total = 0
for _, path in ipairs(items) do
path = path:gsub('"', '\\"')
local ps_cmd = string.format(
[[powershell -Command "& { $p = '%s'; if (Test-Path $p) { if ((Get-ChildItem -Path $p -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object Length -Sum).Sum) { (Get-ChildItem -Path $p -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object Length -Sum).Sum } else { (Get-Item $p).Length } } }"]],
path
)
local pipe = io.popen(ps_cmd)
local result = pipe:read("*a")
-- Debug
-- ya.notify {
-- title = "Debug Output",
-- content = result,
-- timeout = 5,
-- }
pipe:close()
local num = tonumber(result)
if num then total = total + num end
end
return total
else
local arg = ya.target_os() == "macos" and "-scA" or "-scb"
local output, err = Command("du"):arg(arg):args(items):output()
if not output then
ya.err("Failed to run du: " .. err)
end
local lines = {} local lines = {}
for line in s:gmatch("[^\n]+") do lines[#lines + 1] = line end for line in output.stdout:gmatch("[^\n]+") do
lines[#lines + 1] = line
end
local last_line = lines[#lines] local last_line = lines[#lines]
local last_line_parts = {} local size = tonumber(last_line:match("^(%d+)"))
for part in last_line:gmatch("%S+") do last_line_parts[#last_line_parts + 1] = part end return ya.target_os() == "macos" and size * 512 or size
local total_size = last_line_parts[1] end
return total_size
end end
-- Function to format file size -- Function to format file size
local function format_size(size) local function format_size(size)
local units = { "B", "KB", "MB", "GB", "TB" } local units = { "B", "KB", "MB", "GB", "TB" }
local unit_index = 1 local unit_index = 1
while size > 1024 and unit_index < #units do while size > 1024 and unit_index < #units do
size = size / 1024 size = size / 1024
unit_index = unit_index + 1 unit_index = unit_index + 1
end end
return string.format("%.2f %s", size, units[unit_index]) return string.format("%.2f %s", size, units[unit_index])
end end
return { return {
entry = function(self, job) -- as per doc: https://yazi-rs.github.io/docs/plugins/overview#functional-plugin
entry = function(_, job)
-- defaults not to use clipboard, use it only if required by the user -- defaults not to use clipboard, use it only if required by the user
local clipboard = job.args.clipboard or job.args[1] == '-c' local clipboard = job.args.clipboard == true or job.args[1] == "--clipboard" or job.args[1] == "-c"
local items = get_paths() local items = get_paths()
local cmd = "du" local total_size = get_total_size(items)
local output, err = Command(cmd):arg("-scb"):args(items):output() local formatted_size = format_size(total_size)
if not output then
ya.err("Failed to run diff, error: " .. err)
else
local total_size = get_total_size(output.stdout)
local formatted_size = format_size(tonumber(total_size))
local notification_content = "Total size: " .. formatted_size local notification_content = "Total size: " .. formatted_size
if clipboard then if clipboard then
@ -65,8 +90,7 @@ return {
ya.notify { ya.notify {
title = "What size", title = "What size",
content = notification_content, content = notification_content,
timeout = 5, timeout = 4,
} }
end
end, end,
} }

View File

@ -62,10 +62,14 @@ local tab_width
local selected_icon local selected_icon
local copied_icon local copied_icon
local cut_icon local cut_icon
local files_icon
local filtereds_icon
local selected_fg local selected_fg
local copied_fg local copied_fg
local cut_fg local cut_fg
local files_fg
local filtereds_fg
local task_total_icon local task_total_icon
local task_succ_icon local task_succ_icon
@ -748,11 +752,13 @@ function Yatline.coloreds.get:permissions()
end end
end end
--- Gets the number of selected and yanked files of the active tab. --- Gets the number of selected and yanked files and also number of files or filtered files of the active tab.
--- @return Coloreds coloreds Active tab's number of selected and yanked files. --- @param filter? boolean Whether or not number of files (or filtered files) will be shown.
function Yatline.coloreds.get:count() --- @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)
local num_yanked = #cx.yanked local num_yanked = #cx.yanked
local num_selected = #cx.active.selected local num_selected = #cx.active.selected
local num_files = #cx.active.current.files
local yanked_fg, yanked_icon local yanked_fg, yanked_icon
if cx.yanked.is_cut then if cx.yanked.is_cut then
@ -763,10 +769,28 @@ function Yatline.coloreds.get:count()
yanked_icon = copied_icon yanked_icon = copied_icon
end end
local coloreds = { local files_count_fg, files_count_icon
if cx.active.current.files.filter or cx.active.current.cwd.is_search then
files_count_icon = filtereds_icon
files_count_fg = filtereds_fg
else
files_count_icon = files_icon
files_count_fg = files_fg
end
local coloreds
if filter then
coloreds = {
{ string.format(" %s %d ", files_count_icon, num_files), files_count_fg },
{ string.format(" %s %d ", selected_icon, num_selected), selected_fg }, { string.format(" %s %d ", selected_icon, num_selected), selected_fg },
{ string.format(" %s %d ", yanked_icon, num_yanked), yanked_fg }, { string.format(" %s %d ", yanked_icon, num_yanked), yanked_fg },
} }
else
coloreds = {
{ string.format(" %s %d ", selected_icon, num_selected), selected_fg },
{ string.format(" %s %d ", yanked_icon, num_yanked), yanked_fg },
}
end
return coloreds return coloreds
end end
@ -1082,7 +1106,11 @@ return {
} }
if config.theme then if config.theme then
config = config.theme for key, value in pairs(config.theme) do
if not config[key] then
config[key] = value
end
end
end end
if config.section_separator then if config.section_separator then
@ -1156,6 +1184,22 @@ return {
cut_fg = "red" cut_fg = "red"
end end
if config.files then
files_icon = config.files.icon
files_fg = config.files.fg
else
files_icon = ""
files_fg = "blue"
end
if config.filtereds then
filtereds_icon = config.filtereds.icon
filtereds_fg = config.filtereds.fg
else
filtereds_icon = ""
filtereds_fg = "magenta"
end
if config.total then if config.total then
task_total_icon = config.total.icon task_total_icon = config.total.icon
task_total_fg = config.total.fg task_total_fg = config.total.fg
@ -1196,6 +1240,8 @@ return {
task_processed_fg = "green" task_processed_fg = "green"
end end
config = nil
Progress.partial_render = function(self) Progress.partial_render = function(self)
local progress = cx.tasks.progress local progress = cx.tasks.progress
if progress.total == 0 then if progress.total == 0 then
@ -1204,9 +1250,9 @@ return {
local gauge = ui.Gauge():area(self._area) local gauge = ui.Gauge():area(self._area)
if progress.fail == 0 then if progress.fail == 0 then
gauge = gauge:gauge_style(THEME.status.progress_normal) gauge = gauge:gauge_style(th.status.progress_normal)
else else
gauge = gauge:gauge_style(THEME.status.progress_error) gauge = gauge:gauge_style(th.status.progress_error)
end end
local percent = 99 local percent = 99
@ -1218,7 +1264,7 @@ return {
return { return {
gauge gauge
:percent(percent) :percent(percent)
:label(ui.Span(string.format("%3d%%, %d left", percent, left)):style(THEME.status.progress_label)), :label(ui.Span(string.format("%3d%%, %d left", percent, left)):style(th.status.progress_label)),
} }
end end