added toggle-preview plugin in yazi, status bar with omp

This commit is contained in:
liph22
2026-01-13 15:39:15 +01:00
parent 5fc9e27e67
commit b9fe2697a0
17 changed files with 982 additions and 11 deletions

View File

@@ -1,8 +1,8 @@
source = $HOME/.config/hypr/mocha.conf source = /home/liph/.config/hypr/niri_mocha.conf
$accent = $mauve $accent = $mauve
$accentAlpha = $mauveAlpha $accentAlpha = $mauveAlpha
$font = JetBrainsMono Nerd Font $font = Inconsolata Nerd Font
# GENERAL # GENERAL
general { general {

View File

@@ -4,14 +4,16 @@ include current-theme.conf
# END_KITTY_THEME # END_KITTY_THEME
# #
font_family Inconsolata Nerd Font font_family JetBrainsMono Nerd Font
bold_font auto bold_font JetBrainsMono Nerd Font Bold
italic_font auto italic_font JetBrainsMono Nerd Font Italic
bold_italic_font auto bold_italic_font JetBrainsMono Nerd Font Bold Italic
font_size 14 font_size 12
background_opacity 0.90 background_opacity 0.90
term xterm-256color term xterm-256color
allow_hyperlinks yes

View File

@@ -86,6 +86,7 @@ gestures {
workspace "1" workspace "1"
workspace "2" workspace "2"
workspace "3" workspace "3"
workspace "4"
// Example: block out two password managers from screen capture. // Example: block out two password managers from screen capture.
// (This example rule is commented out with a "/-" in front.) // (This example rule is commented out with a "/-" in front.)

View File

@@ -72,7 +72,7 @@
"format-full": "<span font='14' color='#8caaee'>{icon}</span> {capacity}%", "format-full": "<span font='14' color='#8caaee'>{icon}</span> {capacity}%",
"format-charging": "<span font='14' color='#8caaee'>󰂄</span> {capacity}%", "format-charging": "<span font='14' color='#8caaee'>󰂄</span> {capacity}%",
"format-plugged": "<span font='14' color='#8caaee'>󰂄</span> {capacity}%", "format-plugged": "<span font='14' color='#8caaee'>󰂄</span> {capacity}%",
"format-icons": ["󰁺", "󰁼", "󰁾", "󰂀", "󰂂"], "format-icons": ["󰁺", "󰁼", "󰁾", "󰂀", "󰂂", "󰁹"],
}, },
"power-profiles-daemon": { "power-profiles-daemon": {
"format": "{icon}", "format": "{icon}",

View File

@@ -1,6 +1,6 @@
* { * {
font-family: "FiraCode Nerd Font"; font-family: "JetBrainsMono";
font-size: 13px; font-size: 12px;
} }
window#waybar { window#waybar {
background-color: rgba(43, 48, 59, 0.5); background-color: rgba(43, 48, 59, 0.5);

View File

@@ -1,3 +1,5 @@
require("omp"):setup({ config = "/home/liph/.config/yazi/omp/omp.toml" })
require("mime-ext"):setup({ require("mime-ext"):setup({
-- with_files = { -- with_files = {
-- tex = "text/makefile", -- tex = "text/makefile",
@@ -9,9 +11,9 @@ require("mime-ext"):setup({
}) })
require("full-border"):setup({ require("full-border"):setup({
-- Available values: ui.Border.PLAIN, ui.Border.ROUNDED
type = ui.Border.ROUNDED, type = ui.Border.ROUNDED,
}) })
-- git-yazi plugin -- git-yazi plugin
-- th.git = th.git or {} -- th.git = th.git or {}
-- th.git.modified = ui.Style():fg("blue") -- th.git.modified = ui.Style():fg("blue")

View File

@@ -1,5 +1,12 @@
[mgr] [mgr]
prepend_keymap = [ prepend_keymap = [
# toggle-pane plugin
{ on = "T", run = "plugin toggle-pane max-preview", desc = "Maximize or restore the preview pane" },
# what size plugin
{ on = [
".",
"s",
], run = "plugin what-size", desc = "Calc size of selection or cwd" },
{ on = "F", run = "plugin smart-filter", desc = "Smart filter" }, { on = "F", run = "plugin smart-filter", desc = "Smart filter" },
# rsync plugin # rsync plugin
{ on = [ { on = [

View File

@@ -0,0 +1,163 @@
{
"$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
"palette": {
"gb_bright_aqua": "#8ec07c",
"gb_bright_blue": "#83a598",
"gb_bright_green": "#b8bb26",
"gb_bright_orange": "#fe8019",
"gb_bright_purple": "#d3869b",
"gb_bright_red": "#fb4934",
"gb_bright_yellow": "#fabd2f",
"gb_dark0": "#282828",
"gb_dark0_hard": "#1d2021",
"gb_dark0_soft": "#32302f",
"gb_dark1": "#3c3836",
"gb_dark2": "#504945",
"gb_dark3": "#665c54",
"gb_dark4": "#7c6f64",
"gb_dark4_256": "#7c6f64",
"gb_faded_aqua": "#427b58",
"gb_faded_blue": "#076678",
"gb_faded_green": "#79740e",
"gb_faded_orange": "#af3a03",
"gb_faded_purple": "#8f3f71",
"gb_faded_red": "#9d0006",
"gb_faded_yellow": "#b57614",
"gb_gray_244": "#928374",
"gb_gray_245": "#928374",
"gb_light0": "#fbf1c7",
"gb_light0_hard": "#f9f5d7",
"gb_light0_soft": "#f2e5bc",
"gb_light1": "#ebdbb2",
"gb_light2": "#d5c4a1",
"gb_light3": "#bdae93",
"gb_light4": "#a89984",
"gb_light4_256": "#a89984",
"gb_neutral_aqua": "#689d6a",
"gb_neutral_blue": "#458588",
"gb_neutral_green": "#98971a",
"gb_neutral_orange": "#d65d0e",
"gb_neutral_purple": "#b16286",
"gb_neutral_red": "#cc241d",
"gb_neutral_yellow": "#d79921"
},
"var": {
"Dir": "",
"Documents": "📝",
"Downloads": "📥",
"Duration": "\u231b",
"Exit": "\u21a9\ufe0f",
"GitHub": "\ueba1",
"Home": "🏠",
"Host": " ",
"LeftDelim": "\ue0b3",
"LeftSep": "\ue0b2",
"LeftSepRound": "\ue0b6",
"Music": "🎵",
"Pictures": "🖼\ufe0f",
"RightDelim": "\ue0b1",
"RightSep": "\ue0b0",
"RightSepRound": "\ue0b4",
"Tag": "🔖 ",
"Time": "🕓",
"root": "🔴",
"ssh": "🌐",
"user": ""
},
"pwd": "osc7",
"blocks": [
{
"type": "prompt",
"alignment": "left",
"segments": [
{
"properties": {
"cache_duration": "none"
},
"leading_diamond": "\ue0b6",
"trailing_diamond": "\ue0b0",
"template": "{{if .Root}}{{.Var.root}}{{else}}{{.Var.user}}{{end}}{{.UserName}} {{.Var.Host}}{{ .HostName }}{{ if .SSHSession }} {{.Var.ssh}}{{ end }}",
"foreground": "p:gb_dark0_hard",
"background": "p:gb_bright_purple",
"type": "session",
"style": "diamond"
},
{
"properties": {
"cache_duration": "none",
"folder_icon": "\ueaf7",
"folder_separator_icon": " \ue0b1 ",
"home_icon": "🏠",
"mapped_locations": {},
"max_depth": 2,
"max_width": 6,
"mixed_threshold": 6,
"style": "mixed"
},
"leading_diamond": "<transparent,#427b58>\ue0b0</>",
"trailing_diamond": "\ue0b0",
"template": "<#fabd2f,#427b58>{{.Var.Dir}}</><#427b58,p:gb_bright_aqua>{{.Var.RightSep}}</><transparent,p:gb_bright_aqua> {{ .Path}}</>",
"foreground": "transparent",
"background": "p:gb_bright_aqua",
"type": "path",
"style": "diamond"
},
{
"properties": {
"branch_max_length": 35,
"cache_duration": "none",
"fetch_stash_count": true,
"fetch_status": true,
"fetch_upstream_icon": true,
"status_formats": {
"Added": " %d",
"Deleted": " %d",
"Modified": " %d",
"Untracked": " %d",
"Unmerged": "󰰧 %d"
}
},
"leading_diamond": "<transparent,background>\ue0b0</>",
"trailing_diamond": "\ue0b0",
"template": " {{ .UpstreamIcon }} {{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }} -> {{.Upstream}}{{ end }}{{ if .Working.Changed }}<p:gb_faded_red> {{ .Working.String }}</>{{ end }}{{ if and (.Working.Changed) (.Staging.Changed) }}{{ end }}{{ if .Staging.Changed }} <p:gb_faded_green>{{ .Staging.String }}</>{{ end }}{{ if gt .StashCount 0 }} \uf51e {{ .StashCount }}{{ end }} ",
"foreground": "#193549",
"background": "#fffb38",
"type": "git",
"style": "diamond",
"background_templates": [
"{{ if or (.Working.Changed) (.Staging.Changed) }}#FF9248{{ end }}",
"{{ if and (gt .Ahead 0) (gt .Behind 0) }}#ff4500{{ end }}",
"{{ if gt .Ahead 0 }}#B388FF{{ end }}",
"{{ if gt .Behind 0 }}#B388FF{{ end }}"
]
},
{
"properties": {
"cache_duration": "none",
"fetch_version": true
},
"template": " \ue718 {{ if .PackageManagerIcon }}{{ .PackageManagerIcon }} {{ end }}{{ .Full }} ",
"foreground": "#ffffff",
"powerline_symbol": "\ue0b0",
"background": "#6CA35E",
"type": "node",
"style": "powerline"
},
{
"properties": {
"cache_duration": "none",
"display_mode": "files",
"fetch_virtual_env": false
},
"template": " \ue235 {{ if .Error }}{{ .Error }}{{ else }}{{ .Full }}{{ end }} ",
"foreground": "#111111",
"powerline_symbol": "\ue0b0",
"background": "#FFDE57",
"type": "python",
"style": "powerline"
}
]
}
],
"version": 3
}

View File

@@ -0,0 +1,96 @@
"$schema" = "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json"
pwd = "osc7"
version = 3
[palette]
gb_bright_lavender = "#b4befe"
gb_bright_maroon = "#f2cdcd"
gb_dark0_hard = "#1d2021"
gb_faded_green = "#79740e"
gb_faded_red = "#9d0006"
gb_text = "#ebdbb2"
[var]
user = ""
ssh = "🌐"
# LEFT SIDE PROMPT
[[blocks]]
type = "prompt"
alignment = "left"
[[blocks.segments]]
template = "{{ if .Root }}# {{ else }}{{ end }}{{ .UserName }}{{ if .SSHSession }} {{.Var.ssh}}{{ end }} "
foreground = "p:gb_text"
background = "transparent"
type = "session"
style = "plain"
[blocks.segments.properties]
cache_duration = "none"
[[blocks.segments]]
template = "{{ .Path }} "
foreground = "p:gb_bright_lavender"
background = "transparent"
type = "path"
style = "plain"
[blocks.segments.properties]
style = "full"
enable_hyperlink = true
[[blocks.segments]]
template = "{{ .HEAD }}{{ if .Working.Changed }} {{ .Working.String }}{{ end }}{{ if .Staging.Changed }} {{ .Staging.String }}{{ end }} "
foreground = "p:gb_bright_maroon"
background = "transparent"
type = "git"
style = "plain"
[blocks.segments.properties]
fetch_status = true
[blocks.segments.properties.status_formats]
Added = "+%d"
Deleted = "-%d"
Modified = "~%d"
Untracked = "?%d"
# RIGHT SIDE PROMPT
[[blocks]]
type = "rprompt"
alignment = "right"
[[blocks.segments]]
template = " {{ .Full }}"
foreground = "p:gb_faded_green"
background = "transparent"
type = "node"
style = "plain"
[blocks.segments.properties]
display_mode = "files"
[[blocks.segments]]
template = " {{ if .Venv }}({{ .Venv }}) {{ end }}{{ .Full }}"
foreground = "p:gb_faded_green"
background = "transparent"
type = "python"
style = "plain"
[blocks.segments.properties]
display_mode = "always"
fetch_virtual_env = true
# NEWLINE FOR INPUT
[[blocks]]
type = "prompt"
alignment = "left"
newline = true
[[blocks.segments]]
template = " "
foreground = "p:gb_bright_aqua"
background = "transparent"
type = "text"
style = "plain"

View File

@@ -0,0 +1,157 @@
"$schema" = "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json"
pwd = "osc7"
version = 3
[palette]
gb_bright_aqua = "#8ec07c"
gb_bright_blue = "#83a598"
gb_bright_green = "#b8bb26"
gb_bright_orange = "#fe8019"
gb_bright_purple = "#d3869b"
gb_bright_red = "#fb4934"
gb_bright_yellow = "#fabd2f"
gb_dark0 = "#282828"
gb_dark0_hard = "#1d2021"
gb_dark0_soft = "#32302f"
gb_dark1 = "#3c3836"
gb_dark2 = "#504945"
gb_dark3 = "#665c54"
gb_dark4 = "#7c6f64"
gb_dark4_256 = "#7c6f64"
gb_faded_aqua = "#427b58"
gb_faded_blue = "#076678"
gb_faded_green = "#79740e"
gb_faded_orange = "#af3a03"
gb_faded_purple = "#8f3f71"
gb_faded_red = "#9d0006"
gb_faded_yellow = "#b57614"
gb_gray_244 = "#928374"
gb_gray_245 = "#928374"
gb_light0 = "#fbf1c7"
gb_light0_hard = "#f9f5d7"
gb_light0_soft = "#f2e5bc"
gb_light1 = "#ebdbb2"
gb_light2 = "#d5c4a1"
gb_light3 = "#bdae93"
gb_light4 = "#a89984"
gb_light4_256 = "#a89984"
gb_neutral_aqua = "#689d6a"
gb_neutral_blue = "#458588"
gb_neutral_green = "#98971a"
gb_neutral_orange = "#d65d0e"
gb_neutral_purple = "#b16286"
gb_neutral_red = "#cc241d"
gb_neutral_yellow = "#d79921"
[var]
Dir = "📂"
Documents = "📝"
Downloads = "📥"
Duration = "⌛"
Exit = "↩️"
GitHub = ""
Home = "🏠"
Host = " "
LeftDelim = ""
LeftSep = ""
LeftSepRound = ""
Music = "🎵"
Pictures = "🖼️"
RightDelim = ""
RightSep = ""
RightSepRound = ""
Tag = "🔖 "
Time = "🕓"
root = "🔴"
ssh = "🌐"
user = "👤"
[[blocks]]
type = "prompt"
alignment = "left"
[[blocks.segments]]
leading_diamond = ""
trailing_diamond = ""
template = "{{if .Root}}{{.Var.root}}{{else}}{{.Var.user}}{{end}}{{.UserName}} {{.Var.Host}}{{ .HostName }}{{ if .SSHSession }} {{.Var.ssh}}{{ end }}"
foreground = "p:gb_dark0_hard"
background = "p:gb_bright_purple"
type = "session"
style = "diamond"
[blocks.segments.properties]
cache_duration = "none"
[[blocks.segments]]
leading_diamond = "<transparent,#427b58></>"
trailing_diamond = ""
template = "<#fabd2f,#427b58>{{.Var.Dir}}</><#427b58,p:gb_bright_aqua>{{.Var.RightSep}}</><transparent,p:gb_bright_aqua> {{ .Path}}</>"
foreground = "transparent"
background = "p:gb_bright_aqua"
type = "path"
style = "diamond"
[blocks.segments.properties]
cache_duration = "none"
folder_icon = ""
folder_separator_icon = "  "
home_icon = "🏠"
mapped_locations = {}
max_depth = 2
max_width = 6
mixed_threshold = 6
style = "mixed"
[[blocks.segments]]
leading_diamond = "<transparent,background></>"
trailing_diamond = ""
template = " {{ .UpstreamIcon }} {{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }} -> {{.Upstream}}{{ end }}{{ if .Working.Changed }}<p:gb_faded_red> {{ .Working.String }}</>{{ end }}{{ if and (.Working.Changed) (.Staging.Changed) }}{{ end }}{{ if .Staging.Changed }} <p:gb_faded_green>{{ .Staging.String }}</>{{ end }}{{ if gt .StashCount 0 }}  {{ .StashCount }}{{ end }} "
foreground = "#193549"
background = "#fffb38"
type = "git"
style = "diamond"
background_templates = [
"{{ if or (.Working.Changed) (.Staging.Changed) }}#FF9248{{ end }}",
"{{ if and (gt .Ahead 0) (gt .Behind 0) }}#ff4500{{ end }}",
"{{ if gt .Ahead 0 }}#B388FF{{ end }}",
"{{ if gt .Behind 0 }}#B388FF{{ end }}",
]
[blocks.segments.properties]
branch_max_length = 35
cache_duration = "none"
fetch_stash_count = true
fetch_status = true
fetch_upstream_icon = true
[blocks.segments.properties.status_formats]
Added = " %d"
Deleted = " %d"
Modified = " %d"
Untracked = " %d"
Unmerged = "󰰧 %d"
[[blocks.segments]]
template = "  {{ if .PackageManagerIcon }}{{ .PackageManagerIcon }} {{ end }}{{ .Full }} "
foreground = "#ffffff"
powerline_symbol = ""
background = "#6CA35E"
type = "node"
style = "powerline"
[blocks.segments.properties]
cache_duration = "none"
fetch_version = true
[[blocks.segments]]
template = "  {{ if .Error }}{{ .Error }}{{ else }}{{ .Full }}{{ end }} "
foreground = "#111111"
powerline_symbol = ""
background = "#FFDE57"
type = "python"
style = "powerline"
[blocks.segments.properties]
cache_duration = "none"
display_mode = "files"
fetch_virtual_env = false

View File

@@ -88,6 +88,16 @@ use = "yazi-rs/plugins:full-border"
rev = "68f7d48" rev = "68f7d48"
hash = "3996fc74044bc44144b323686f887e1" hash = "3996fc74044bc44144b323686f887e1"
[[plugin.deps]]
use = "pirafrank/what-size"
rev = "179ebf6"
hash = "57056b9728006881d580ccabe8154a9c"
[[plugin.deps]]
use = "yazi-rs/plugins:toggle-pane"
rev = "57f1863"
hash = "8a7c58225816a163a6e8730c0adafbc8"
[[flavor.deps]] [[flavor.deps]]
use = "yazi-rs/flavors:catppuccin-mocha" use = "yazi-rs/flavors:catppuccin-mocha"
rev = "4a1802a" rev = "4a1802a"

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 yazi-rs
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

@@ -0,0 +1,80 @@
# toggle-pane.yazi
Toggle the show, hide, and maximize states for different panes: parent, current, and preview. It respects the user's [`ratio` settings](https://yazi-rs.github.io/docs/configuration/yazi#mgr.ratio)!
Assume the user's `ratio` is $$[A, B, C]$$, that is, $$\text{parent}=A, \text{current}=B, \text{preview}=C$$:
- `min-parent`: Toggles between $$0$$ and $$A$$ - the parent is either completely hidden or showed with width $$A$$.
- `max-parent`: Toggles between $$A$$ and $$\infty$$ - the parent is either showed with width $$A$$ or fills the entire screen.
- `min-current`: Toggles between $$0$$ and $$B$$ - the current is either completely hidden or showed with width $$B$$.
- `max-current`: Toggles between $$B$$ and $$\infty$$ - the current is either showed with width $$B$$ or fills the entire screen.
- `min-preview`: Toggles between $$0$$ and $$C$$ - the preview is either completely hidden or showed with width $$C$$.
- `max-preview`: Toggles between $$C$$ and $$\infty$$ - the preview is either showed with width $$C$$ or fills the entire screen.
- `reset`: Resets to the user's configured `ratio`.
## Installation
```sh
ya pkg add yazi-rs/plugins:toggle-pane
```
## Usage
Hide/Show preview:
```toml
# keymap.toml
[[mgr.prepend_keymap]]
on = "T"
run = "plugin toggle-pane min-preview"
desc = "Show or hide the preview pane"
```
Maximize/Restore preview:
```toml
# keymap.toml
[[mgr.prepend_keymap]]
on = "T"
run = "plugin toggle-pane max-preview"
desc = "Maximize or restore the preview pane"
```
You can replace `preview` with `current` or `parent` to toggle the other panes.
Note that, the keybindings above are just examples, please tune them up as needed to ensure they don't conflict with your other commands/plugins.
## Advanced
In addition to triggering the plugin with a keypress, you can also trigger it in your `init.lua` file:
```lua
if os.getenv("NVIM") then
require("toggle-pane"):entry("min-preview")
end
```
In the example above, when it detects that you're [using Yazi in nvim](https://yazi-rs.github.io/docs/resources#vim), the preview is hidden by default — you can always press `T` (or any key you've bound) to show it again.
## Tips
This plugin only maximizes the "available preview area", without actually changing the content size.
This means that the appearance of your preview largely depends on the previewer you are using.
However, most previewers tend to make the most of the available space, so this usually isn't an issue.
For image previews, you may want to tune up the [`max_width`][max-width] and [`max_height`][max-height] options in your `yazi.toml`:
```toml
[preview]
# Change them to your desired values
max_width = 1000
max_height = 1000
```
[max-width]: https://yazi-rs.github.io/docs/configuration/yazi/#preview.max_width
[max-height]: https://yazi-rs.github.io/docs/configuration/yazi/#preview.max_height
## License
This plugin is MIT-licensed. For more information, check the [LICENSE](LICENSE) file.

View File

@@ -0,0 +1,45 @@
--- @since 25.5.31
--- @sync entry
local function entry(st, job)
local R = rt.mgr.ratio
job = type(job) == "string" and { args = { job } } or job
st.parent = st.parent or R.parent
st.current = st.current or R.current
st.preview = st.preview or R.preview
local act, to = string.match(job.args[1] or "", "(.-)-(.+)")
if act == "min" then
st[to] = st[to] == R[to] and 0 or R[to]
elseif act == "max" then
local max = st[to] == 65535 and R[to] or 65535
st.parent = st.parent == 65535 and R.parent or st.parent
st.current = st.current == 65535 and R.current or st.current
st.preview = st.preview == 65535 and R.preview or st.preview
st[to] = max
end
if not st.old then
st.old = Tab.layout
Tab.layout = function(self)
local all = st.parent + st.current + st.preview
self._chunks = ui.Layout()
:direction(ui.Layout.HORIZONTAL)
:constraints({
ui.Constraint.Ratio(st.parent, all),
ui.Constraint.Ratio(st.current, all),
ui.Constraint.Ratio(st.preview, all),
})
:split(self._area)
end
end
if not act then
Tab.layout, st.old = st.old, nil
st.parent, st.current, st.preview = nil, nil, nil
end
ya.emit("app:resize", {})
end
return { entry = entry }

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Francesco Pira
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

@@ -0,0 +1,128 @@
# what-size.yazi
A plugin for [yazi](https://github.com/sxyazi/yazi) to calculate the size of the current selection or the current working directory (if no selection is made).
## Compatibility
what-size supports Yazi on Linux, macOS, and Windows.
### OS
- Linux since first commit
- macOS since commit `42c6a0e` ([link](https://github.com/pirafrank/what-size.yazi/commit/42c6a0efb7245badb16781da5380be1a1705f3f2))
- Windows since commit `4a56ead` ([link](https://github.com/pirafrank/what-size.yazi/commit/4a56ead2a84c5969791fb17416e0b451ab906c5d))
### Yazi
In an effort to make things easy, I keep `compatibility/yazi-x.y.z` branches with each pointing to the most up-to-date commit compatible with yazi release `x.y.z`. Full table below.
|Yazi releases|what-size branch name|
|---|---|
|*[latest stable](https://github.com/sxyazi/yazi/releases/latest)*|`main`|
|`25.5.28`|`compatibility/yazi-25.5.28`|
|`25.x`-`25.4.8`|`compatibility/yazi-25.4.8`|
|`0.4.x`|`compatibility/yazi-0.4.x`|
|`0.3.x`|`compatibility/yazi-0.3.x`|
Please notice that `nightly` releses may work but are not explicitly supported.
## Requirements
### Before Yazi's version 25.5.28
- Use this commit: [Old version](https://github.com/pirafrank/what-size.yazi/commit/d8966568f2a80394bf1f9a1ace6708ddd4cc8154)
- `du` on Linux and macOS
- PowerShell on Windows
### On Yazi's version 25.5.28 or newer
- No requirement
## Installation
```sh
ya pkg add pirafrank/what-size
```
or (**DEPRECATED** - use only for yazi `25.4.8` and older):
```sh
ya pack -a 'pirafrank/what-size'
```
## Usage
### Keymap
Add this to your `~/.config/yazi/keymap.toml`:
```toml
[[mgr.prepend_keymap]]
on = [ ".", "s" ]
run = "plugin what-size"
desc = "Calc size of selection or cwd"
```
If you want to copy the result to clipboard, you can add `--clipboard` or `-c` as 2nd positional argument:
```toml
[[mgr.prepend_keymap]]
on = [ ".", "s" ]
run = "plugin what-size -- '--clipboard'"
desc = "Calc size of sel/cwd + paste to clipboard"
```
```toml
[[mgr.prepend_keymap]]
on = [ ".", "s" ]
run = "plugin what-size -- '-c'"
desc = "Calc size of sel/cwd + paste to clipboard"
```
Change to whatever keybinding you like.
### User interface (optional)
If you want to place the size value exactly where you want, modify the priority value. Also changing two strings `LEFT` and `RIGHT` will add them to the left and right side of the value. Remember to add to and change these lines inside your `init.lua` file if you want to customize, or the plugin will use this configuration by default:
```lua
require("what-size"):setup({
priority = 400,
LEFT = "",
RIGHT = " ",
})
```
## 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.
### Plugin definition
The repo already has a `.luarc.json` file. You only need to run the following to add the `types` plugin dependency:
```sh
ya pkg add yazi-rs/plugins:types
```
as per the [docs](https://github.com/yazi-rs/plugins/tree/main/types.yazi).
## Contributing
Contributions are welcome. Please fork the repository and submit a PR.
## License
MIT

View File

@@ -0,0 +1,238 @@
--- @since 25.5.28
-- This plugin is now only supporting Yazi's version 25.5.28 or newer
-- since commit https://github.com/sxyazi/yazi/pull/2695
-- TODO: Asynchronous calculating and dynamic displaying in statusline,
-- perhaps by using this:
-- https://yazi-rs.github.io/docs/plugins/utils/#ps.sub
-- and by using ui.render() method
-- See also:
-- https://github.com/sxyazi/yazi/pull/1903
-- https://yazi-rs.github.io/docs/dds/#kinds
-- https://github.com/sxyazi/yazi/pull/2210
-- https://github.com/imsi32/yatline.yazi
-- TODO: Add options to choose displaying in popup box or in statusline
-- TODO: Add spotter and previewer widget to support simpler displaying
-- TODO: Remove note [1] and [2] after add them to the setup
-- configuration
-- Get selected paths {{{1
local get_selected_paths = ya.sync(function(state)
local result = {}
if cx and cx.active and cx.active.selected then
for _, url in pairs(cx.active.selected) do
result[#result + 1] = url
end
end
return result
end)
-- }}}1
-- Get current working directory in sync context {{{1
local get_cwd = ya.sync(function(state)
if cx and cx.active and cx.active.current and cx.active.current.cwd then
return cx.active.current.cwd
end
return nil
end)
-- }}}1
-- Function to get paths of selected files or current directory {{{1
--- @param selected table Table of selected urls
--- @return paths table Table of selected urls
local function get_paths(selected)
-- If no files are selected, get current directory
if #selected == 0 then
local paths = {}
-- Try fs.cwd() first (async, optimized for slow devices)
local cwd, err = fs.cwd()
if cwd then
paths[1] = cwd
else
-- Fallback to cx.active.current.cwd (via sync block)
local sync_cwd = get_cwd()
if sync_cwd then
paths[1] = sync_cwd
else
ya.notify {
title = "What size",
content = "Cannot get current working directory: " .. (err or "unknown error"),
timeout = 5,
level = "error",
}
end
end
return paths
else
-- This variable is a table of urls already
return selected
end
end
-- }}}1
-- Function to get total size using Yazi's fs.calc_size API {{{1
-- See: https://github.com/sxyazi/yazi/pull/2695
-- See: https://github.com/sxyazi/yazi/blob/main/yazi-plugin/preset/plugins/folder.lua
local function get_total_size(items)
local total = 0
for _, url in ipairs(items) do
local it = fs.calc_size(url)
while true do
local next = it:recv()
if next then
total = total + next
else
break
end
end
end
return total
end
-- }}}1
-- Function to format files/folders size {{{1
local function format_size(size)
local units = { "B", "KB", "MB", "GB", "TB" }
local unit_index = 1
while size > 1024 and unit_index < #units do
size = size / 1024
unit_index = unit_index + 1
end
return string.format("%.2f %s", size, units[unit_index])
end
-- }}}1
-- Generic setter for any state field {{{1
local set_state = ya.sync(function(state, field, value)
state[field] = value
end)
-- }}}1
-- Generic getter for any state field {{{1
local get_state = ya.sync(function(state, field)
return state[field] or nil
end)
-- }}}1
-- Get selecting state {{{1
local get_selected = ya.sync(function()
return (not cx.active.mode.is_visual) and (#cx.active.selected ~= 0)
end)
-- }}}1
-- Set separators {{{1
local set_separator = ya.sync(function(state, table)
if table and table.LEFT and table.RIGHT then
state.LEFT = table.LEFT
state.RIGHT = table.RIGHT
else
state.LEFT = " "
state.RIGHT = " "
end
end)
-- }}}1
-- Get separators {{{1
local get_separator = ya.sync(function(state)
return {state.LEFT, state.RIGHT}
end)
-- }}}1
-- Redraw statusline {{{1
local redraw_statusline = ya.sync(function(state)
ui.render()
end)
-- }}}1
-- Set ui line in statusline for size, clean up when no selection exists {{{1
-- @return of get_state("renewed_state") number or nil Returning -1
-- means never show the size - suitable for setup function;
-- returning 0 means the size will be shown after triggering the
-- calculation, but without unselect the selections, or it will be
-- hidden after nothing is selected; returning 1 means hidden when
-- nothing is selected as said.
local set_ui_line = function(state)
local sep_left, sep_right = table.unpack(get_separator())
if get_state("renewed_state") == -1 then
return ""
else
if not get_selected() then
if not get_state("is_held") then
set_state("renewed_state", 1)
return ""
end
-- NOTE [1]: Set this line if DON'T want to clear the value
-- in the statusline when move the cursor, after calculating
-- with NO selection(s). Or just return ""
return ui.Span(sep_left .. get_state("size") .. sep_right)
end
if get_state("renewed_state") == 0 then
return ui.Span(sep_left .. get_state("size") .. sep_right)
else
-- NOTE [2]: Set this line if want to clear the value in the
-- statusline when move the cursor, after calculating WITH
-- selection: return ui.Span(sep_left .. get_state("size") .. sep_right)
-- or just remove after the unselection like below
return ""
end
end
end
-- }}}1
--- @since 25.12.29
return {
entry = function(self, job)
local clipboard = job.args.clipboard or job.args[1] == '-c'
local selected = get_selected_paths()
local prepend_msg
-- Keep showing the size after CWD calculation (no selections)
if #selected == 0 then
set_state("is_held", true)
prepend_msg = "Current Dir: "
else
set_state("is_held", false)
prepend_msg = "Selected: "
end
local items = get_paths(selected)
if not items or #items == 0 then
ya.notify {
title = "What size",
content = "Failed to get paths",
timeout = 5,
}
return
end
local total_size = get_total_size(items)
if not total_size then
ya.notify {
title = "What size",
content = "Failed to calculate size",
timeout = 5,
}
return
end
local formatted_size = format_size(total_size)
local notification_content = prepend_msg .. formatted_size
if clipboard then
ya.clipboard(formatted_size)
notification_content = notification_content .. "\nCopied to clipboard."
end
ya.notify {
title = "What size",
content = notification_content,
timeout = 4,
}
set_state("size", formatted_size)
set_state("renewed_state", 0)
redraw_statusline()
end,
setup = function(state, opts)
opts = opts or {}
local priority = opts.priority or 400
set_separator(opts)
set_state("renewed_state", -1)
if Status and type(Status.children_add) == "function" then
Status:children_add(set_ui_line, priority, Status.RIGHT)
else
ya.err("Failed to initialize status bar: Status or children_add not available")
end
end,
}