fixing yazi plugins
This commit is contained in:
parent
d618ecf02e
commit
38f162562e
17 changed files with 43 additions and 822 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "modules/home/yazi/plugins/yazi-plugins"]
|
||||
path = modules/home/yazi/plugins/yazi-plugins
|
||||
url = git@github.com:yazi-rs/plugins.git
|
42
flake.lock
generated
42
flake.lock
generated
|
@ -70,11 +70,11 @@
|
|||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1743700520,
|
||||
"narHash": "sha256-FTgOgaZks+xkyqqukNOe7FXHPshCYmQ38wxzxJ6T3RQ=",
|
||||
"lastModified": 1743783783,
|
||||
"narHash": "sha256-6SYZkfwTEyuLkM2wal5s5CiYrnFJ6Pa9bA/Y6FZ4fcA=",
|
||||
"owner": "nix-community",
|
||||
"repo": "emacs-overlay",
|
||||
"rev": "8c76e5792ef50a67e89ad54e792769f89d721f4a",
|
||||
"rev": "441e7ba4e4a128422b85039fe6b9662b259ba5eb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -357,11 +357,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1743648554,
|
||||
"narHash": "sha256-23JFd+zd2GamTTdnGuFVeIg8x8C3hLpQJRh/PGTORzo=",
|
||||
"lastModified": 1743788974,
|
||||
"narHash": "sha256-2LeVyQZI2wTkSzMLvnN/kJjXVWp4HCVUoq17Bv8TNTk=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "107352dde4ff3c01cb5a0b3fe17f5beef37215bc",
|
||||
"rev": "0f5908daf890c3d7e7052bef1d6deb0f2710aaa1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -744,11 +744,11 @@
|
|||
"xwayland-satellite-unstable": "xwayland-satellite-unstable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1743644801,
|
||||
"narHash": "sha256-z8x/j/RuDBo/5lNt3XYatKRpIMFMHVE2HK7TKVxYn+c=",
|
||||
"lastModified": 1743778191,
|
||||
"narHash": "sha256-Fc4kJeTawHVUd+TTpqLJRvvNusTTwqWE1vLz9IpH0NA=",
|
||||
"owner": "sodiboo",
|
||||
"repo": "niri-flake",
|
||||
"rev": "f3fca85fe72c70d58f44f4c6ad2f27a91aa54d0d",
|
||||
"rev": "612390f7f196eec4b832e3fca17719d412f5f69c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -777,11 +777,11 @@
|
|||
"niri-unstable": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1743492917,
|
||||
"narHash": "sha256-OqLDg0Ody1HX23hgjvjIkfZPNhYKxbkj/ONcDjdD4Ik=",
|
||||
"lastModified": 1743774669,
|
||||
"narHash": "sha256-xrg3m1RP7mvBi0sLPJjnn9UiCqN+NKqU94DZJMoaXZU=",
|
||||
"owner": "YaLTeR",
|
||||
"repo": "niri",
|
||||
"rev": "60034a57efd9c8130b05797b37cbc187a8c13145",
|
||||
"rev": "e8da89a430f4af0accfe80efe286b2cffd20a4aa",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1013,11 +1013,11 @@
|
|||
},
|
||||
"nixpkgs-stable_4": {
|
||||
"locked": {
|
||||
"lastModified": 1743576891,
|
||||
"narHash": "sha256-vXiKURtntURybE6FMNFAVpRPr8+e8KoLPrYs9TGuAKc=",
|
||||
"lastModified": 1743703532,
|
||||
"narHash": "sha256-s1KLDALEeqy+ttrvqV3jx9mBZEvmthQErTVOAzbjHZs=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "44a69ed688786e98a101f02b712c313f1ade37ab",
|
||||
"rev": "bdb91860de2f719b57eef819b5617762f7120c70",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1255,11 +1255,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1743604509,
|
||||
"narHash": "sha256-Hf5aYGP3hP+uNbcd4NrEMUAR+1o518uGzoeVyMzzJwo=",
|
||||
"lastModified": 1743756170,
|
||||
"narHash": "sha256-2b11EYa08oqDmF3zEBLkG1AoNn9rB1k39ew/T/mSvbU=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "4521de68fba1a36fae8caebce3d6e047179661f7",
|
||||
"rev": "cff8437c5fe8c68fc3a840a21bf1f4dc801da40d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1562,11 +1562,11 @@
|
|||
"rust-overlay": "rust-overlay_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1743669585,
|
||||
"narHash": "sha256-uAOZg2vsMooemIpV0jdgy7JicuVNBbJl2gRN7m/N0ZM=",
|
||||
"lastModified": 1743786211,
|
||||
"narHash": "sha256-WW/qwf6wVFWNJGMRbmDT4l/K8KMlX7+69jwd7mBHgwc=",
|
||||
"owner": "sxyazi",
|
||||
"repo": "yazi",
|
||||
"rev": "b725b86be13ffc127094dbb981d667d3d7d8c64a",
|
||||
"rev": "75fad253c0948a06bcfed57b99ca60ecca39a0c3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -58,28 +58,24 @@
|
|||
tree
|
||||
emoji-picker
|
||||
|
||||
sox
|
||||
imgcat
|
||||
ghostscript
|
||||
playerctl
|
||||
tesseract
|
||||
dockfmt
|
||||
trash-cli
|
||||
poppler_utils
|
||||
|
||||
fishPlugins.foreign-env
|
||||
fishPlugins.fzf-fish
|
||||
fishPlugins.fifc
|
||||
fishPlugins.bass
|
||||
fishPlugins.autopair
|
||||
fishPlugins.forgit
|
||||
fishPlugins.colored-man-pages
|
||||
|
||||
sox
|
||||
|
||||
imgcat
|
||||
ghostscript
|
||||
playerctl
|
||||
|
||||
tesseract
|
||||
|
||||
dockfmt
|
||||
|
||||
trash-cli
|
||||
|
||||
poppler_utils
|
||||
|
||||
fossil
|
||||
television
|
||||
];
|
||||
|
||||
programs = {
|
||||
|
@ -99,6 +95,7 @@
|
|||
};
|
||||
interactiveShellInit = ''
|
||||
bind --erase \ct
|
||||
fzf_configure_bindings --variables=\e\cv
|
||||
'';
|
||||
plugins = [
|
||||
{
|
||||
|
@ -141,7 +138,6 @@
|
|||
git = true;
|
||||
icons = "auto";
|
||||
colors = "auto";
|
||||
# extraOptions = [ "--header" ];
|
||||
};
|
||||
fd = {
|
||||
enable = true;
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
{ on = "!"; run = "shell '$SHELL' --block"; desc = "Open shell here"; }
|
||||
{ on = ["c" "d"]; run = "shell 'ripdrag \"$@\" -x 2>/dev/null &' --confirm"; desc = "Drag selection";}
|
||||
{ on = ["c" "c"]; run = "yank"; desc = "Copy file"; }
|
||||
{ on = ["c" "n"]; run = "copy filename"; desc = "Copy file name"; }
|
||||
{ on = ["c" "N"]; run = "copy name_without_ext"; desc = "Copy file name without extension"; }
|
||||
{ on = "y"; run = ["shell 'for path in \"$@\"; do echo \"file://$path\"; done | wl-copy -t text/uri-list'\n" "yank"]; }
|
||||
{ on = ["g" "r"]; run = "shell 'ya emit cd \"$(git rev-parse --show-toplevel)\"'\n"; desc = "Go to top of git repo"; }
|
||||
{ on = ["g" "p"]; run = "cd ~/Projects"; desc = "Go to ~/Projects"; }
|
||||
|
@ -26,15 +24,12 @@
|
|||
{ on = "M"; run = "plugin mount"; }
|
||||
{ on = "p"; run = "plugin smart-paste"; desc = "Paste into the hovered directory or CWD"; }
|
||||
{ on = ["g" "l"]; run = "plugin lazygit"; desc = "lazygit"; }
|
||||
{ on = "k"; run = "plugin arrow -1"; desc = "up"; }
|
||||
{ on = "j"; run = "plugin arrow 1"; desc = "down"; }
|
||||
{ on = "<Up>"; run = "plugin arrow -1"; desc = "up"; }
|
||||
{ on = "<Down>"; run = "plugin arrow 1"; desc = "down"; }
|
||||
# { on = "k"; run = "arrow -1"; desc = "up"; }
|
||||
# { on = "j"; run = "arrow 1"; desc = "down"; }
|
||||
# { on = "<Up>"; run = "arrow -1"; desc = "up"; }
|
||||
# { on = "<Down>"; run = "arrow 1"; desc = "down"; }
|
||||
{ on = "C"; run = "plugin ouch zip"; }
|
||||
{ on = "T"; run = "plugin smart-tab"; desc = "Create a tab and enter the hovered directory"; }
|
||||
{ on = "l"; run = "plugin smart-enter"; desc = "Enter the child directory, or open the file"; }
|
||||
{ on = "<Enter>"; run = "plugin smart-enter"; desc = "Enter the child directory, or open the file"; }
|
||||
{ on = "<Right>"; run = "plugin smart-enter"; desc = "Enter the child directory, or open the file"; }
|
||||
{ on = "<Backspace>"; run = "remove"; }
|
||||
|
||||
{ on = [ "t" "s" ]; run = "plugin what-size"; desc = "Calc size of selection or cwd"; }
|
||||
|
@ -42,9 +37,8 @@
|
|||
{ on = ["d" "u"]; run = "plugin restore"; desc = "Restore last deleted files/folders"; }
|
||||
{ on = ["d" "d"]; run = "remove"; desc = "Delete files/folders"; }
|
||||
|
||||
{ on = ["F" "g"]; run = "plugin fg"; desc = "Find file by content (fuzzy)"; }
|
||||
{ on = ["F" "G"]; run = "plugin fg rg"; desc = "Find file by content (ripgrep)"; }
|
||||
{ on = ["F" "f"]; run = "plugin fg fzf"; desc = "Find file by name (fuzzy)"; }
|
||||
{ on = "f"; run = "find --smart"; desc = "Find file"; }
|
||||
{ on = "F"; run = "filter --smart"; desc = "Find file"; }
|
||||
];
|
||||
};
|
||||
settings = {
|
||||
|
|
|
@ -6,22 +6,10 @@ require("starship"):setup {
|
|||
config_file = "~/.config/starship.toml",
|
||||
}
|
||||
|
||||
require("smart-enter"):setup {
|
||||
open_multi = true,
|
||||
}
|
||||
|
||||
require("fg"):setup({
|
||||
default_action = "menu",
|
||||
})
|
||||
|
||||
-- ~/.config/yazi/init.lua
|
||||
THEME.git = THEME.git or {}
|
||||
THEME.git.added_sign = "A"
|
||||
THEME.git.ignored_sign = "I"
|
||||
THEME.git.updated_sign = "U"
|
||||
THEME.git.modified_sign = "M"
|
||||
THEME.git.deleted_sign = "D"
|
||||
|
||||
require("yatline"):setup({
|
||||
--theme = my_theme,
|
||||
section_separator = { open = "", close = "" },
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
--- @sync entry
|
||||
return {
|
||||
entry = function(_, job)
|
||||
local current = cx.active.current
|
||||
local new = (current.cursor + job.args[1]) % #current.files
|
||||
ya.manager_emit("arrow", { new - current.cursor })
|
||||
end,
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
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.
|
|
@ -1,28 +0,0 @@
|
|||
# chmod.yazi
|
||||
|
||||
Execute `chmod` on the selected files to change their mode. This plugin is only available on Unix platforms since it relies on [`chmod(2)`](https://man7.org/linux/man-pages/man2/chmod.2.html).
|
||||
|
||||
https://github.com/yazi-rs/plugins/assets/17523360/7aa3abc2-d057-498c-8473-a6282c59c464
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
ya pack -a yazi-rs/plugins:chmod
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Add this to your `~/.config/yazi/keymap.toml`:
|
||||
|
||||
```toml
|
||||
[[manager.prepend_keymap]]
|
||||
on = [ "c", "m" ]
|
||||
run = "plugin chmod"
|
||||
desc = "Chmod on selected files"
|
||||
```
|
||||
|
||||
Make sure the <kbd>c</kbd> => <kbd>m</kbd> key is not used elsewhere.
|
||||
|
||||
## License
|
||||
|
||||
This plugin is MIT-licensed. For more information check the [LICENSE](LICENSE) file.
|
|
@ -1,39 +0,0 @@
|
|||
local selected_or_hovered = ya.sync(function()
|
||||
local tab, paths = cx.active, {}
|
||||
for _, u in pairs(tab.selected) do
|
||||
paths[#paths + 1] = tostring(u)
|
||||
end
|
||||
if #paths == 0 and tab.current.hovered then
|
||||
paths[1] = tostring(tab.current.hovered.url)
|
||||
end
|
||||
return paths
|
||||
end)
|
||||
|
||||
return {
|
||||
entry = function()
|
||||
ya.manager_emit("escape", { visual = true })
|
||||
|
||||
local urls = selected_or_hovered()
|
||||
if #urls == 0 then
|
||||
return ya.notify { title = "Chmod", content = "No file selected", level = "warn", timeout = 5 }
|
||||
end
|
||||
|
||||
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 {
|
||||
title = "Chmod",
|
||||
content = string.format("Chmod on selected files failed, error: %s", status and status.code or err),
|
||||
level = "error",
|
||||
timeout = 5,
|
||||
}
|
||||
end
|
||||
end,
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
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.
|
|
@ -1,78 +0,0 @@
|
|||
# git.yazi
|
||||
|
||||
> [!NOTE]
|
||||
> Yazi v0.4.1 or later is required for this plugin to work.
|
||||
|
||||
Show the status of Git file changes as linemode in the file list.
|
||||
|
||||
https://github.com/user-attachments/assets/34976be9-a871-4ffe-9d5a-c4cdd0bf4576
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
ya pack -a yazi-rs/plugins:git
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
Add the following to your `~/.config/yazi/init.lua`:
|
||||
|
||||
```lua
|
||||
require("git"):setup()
|
||||
```
|
||||
|
||||
And register it as fetchers in your `~/.config/yazi/yazi.toml`:
|
||||
|
||||
```toml
|
||||
[[plugin.prepend_fetchers]]
|
||||
id = "git"
|
||||
name = "*"
|
||||
run = "git"
|
||||
|
||||
[[plugin.prepend_fetchers]]
|
||||
id = "git"
|
||||
name = "*/"
|
||||
run = "git"
|
||||
```
|
||||
|
||||
## Advanced
|
||||
|
||||
You can customize the [Style](https://yazi-rs.github.io/docs/plugins/layout#style) of the status sign with:
|
||||
|
||||
- `THEME.git.modified`
|
||||
- `THEME.git.added`
|
||||
- `THEME.git.untracked`
|
||||
- `THEME.git.ignored`
|
||||
- `THEME.git.deleted`
|
||||
- `THEME.git.updated`
|
||||
|
||||
For example:
|
||||
|
||||
```lua
|
||||
-- ~/.config/yazi/init.lua
|
||||
THEME.git = THEME.git or {}
|
||||
THEME.git.modified = ui.Style():fg("blue")
|
||||
THEME.git.deleted = ui.Style():fg("red"):bold()
|
||||
```
|
||||
|
||||
You can also customize the text of the status sign with:
|
||||
|
||||
- `THEME.git.modified_sign`
|
||||
- `THEME.git.added_sign`
|
||||
- `THEME.git.untracked_sign`
|
||||
- `THEME.git.ignored_sign`
|
||||
- `THEME.git.deleted_sign`
|
||||
- `THEME.git.updated_sign`
|
||||
|
||||
For example:
|
||||
|
||||
```lua
|
||||
-- ~/.config/yazi/init.lua
|
||||
THEME.git = THEME.git or {}
|
||||
THEME.git.modified_sign = "M"
|
||||
THEME.git.deleted_sign = "D"
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This plugin is MIT-licensed. For more information check the [LICENSE](LICENSE) file.
|
|
@ -1,217 +0,0 @@
|
|||
local WIN = ya.target_family() == "windows"
|
||||
local PATS = {
|
||||
{ "[MT]", 6 }, -- Modified
|
||||
{ "[AC]", 5 }, -- Added
|
||||
{ "?$", 4 }, -- Untracked
|
||||
{ "!$", 3 }, -- Ignored
|
||||
{ "D", 2 }, -- Deleted
|
||||
{ "U", 1 }, -- Updated
|
||||
{ "[AD][AD]", 1 }, -- Updated
|
||||
}
|
||||
|
||||
local function match(line)
|
||||
local signs = line:sub(1, 2)
|
||||
for _, p in ipairs(PATS) do
|
||||
local path
|
||||
if signs:find(p[1]) then
|
||||
path = line:sub(4, 4) == '"' and line:sub(5, -2) or line:sub(4)
|
||||
path = WIN and path:gsub("/", "\\") or path
|
||||
end
|
||||
if not path then
|
||||
elseif path:find("[/\\]$") then
|
||||
return p[2] == 3 and 30 or p[2], path:sub(1, -2)
|
||||
else
|
||||
return p[2], path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function root(cwd)
|
||||
local is_worktree = function(url)
|
||||
local file, head = io.open(tostring(url)), nil
|
||||
if file then
|
||||
head = file:read(8)
|
||||
file:close()
|
||||
end
|
||||
return head == "gitdir: "
|
||||
end
|
||||
|
||||
repeat
|
||||
local next = cwd:join(".git")
|
||||
local cha = fs.cha(next)
|
||||
if cha and (cha.is_dir or is_worktree(next)) then
|
||||
return tostring(cwd)
|
||||
end
|
||||
cwd = cwd:parent()
|
||||
until not cwd
|
||||
end
|
||||
|
||||
local function bubble_up(changed)
|
||||
local new, empty = {}, Url("")
|
||||
for k, v in pairs(changed) do
|
||||
if v ~= 3 and v ~= 30 then
|
||||
local url = Url(k):parent()
|
||||
while url and url ~= empty do
|
||||
local s = tostring(url)
|
||||
new[s] = (new[s] or 0) > v and new[s] or v
|
||||
url = url:parent()
|
||||
end
|
||||
end
|
||||
end
|
||||
return new
|
||||
end
|
||||
|
||||
local function propagate_down(ignored, cwd, repo)
|
||||
local new, rel = {}, cwd:strip_prefix(repo)
|
||||
for k, v in pairs(ignored) do
|
||||
if v == 30 then
|
||||
if rel:starts_with(k) then
|
||||
new[tostring(repo:join(rel))] = 30
|
||||
elseif cwd == repo:join(k):parent() then
|
||||
new[k] = 3
|
||||
end
|
||||
end
|
||||
end
|
||||
return new
|
||||
end
|
||||
|
||||
local add = ya.sync(function(st, cwd, repo, changed)
|
||||
st.dirs[cwd] = repo
|
||||
st.repos[repo] = st.repos[repo] or {}
|
||||
for k, v in pairs(changed) do
|
||||
if v == 0 then
|
||||
st.repos[repo][k] = nil
|
||||
elseif v == 30 then
|
||||
st.dirs[k] = ""
|
||||
else
|
||||
st.repos[repo][k] = v
|
||||
end
|
||||
end
|
||||
ya.render()
|
||||
end)
|
||||
|
||||
local remove = ya.sync(function(st, cwd)
|
||||
local dir = st.dirs[cwd]
|
||||
if not dir then
|
||||
return
|
||||
end
|
||||
|
||||
ya.render()
|
||||
st.dirs[cwd] = nil
|
||||
if not st.repos[dir] then
|
||||
return
|
||||
end
|
||||
|
||||
for _, r in pairs(st.dirs) do
|
||||
if r == dir then
|
||||
return
|
||||
end
|
||||
end
|
||||
st.repos[dir] = nil
|
||||
end)
|
||||
|
||||
local function setup(st, opts)
|
||||
st.dirs = {}
|
||||
st.repos = {}
|
||||
|
||||
opts = opts or {}
|
||||
opts.order = opts.order or 1500
|
||||
|
||||
-- Chosen by ChatGPT fairly, PRs are welcome to adjust them
|
||||
local t = THEME.git or {}
|
||||
local styles = {
|
||||
[6] = t.modified and ui.Style(t.modified) or ui.Style():fg("#ffa500"),
|
||||
[5] = t.added and ui.Style(t.added) or ui.Style():fg("#32cd32"),
|
||||
[4] = t.untracked and ui.Style(t.untracked) or ui.Style():fg("#a9a9a9"),
|
||||
[3] = t.ignored and ui.Style(t.ignored) or ui.Style():fg("#696969"),
|
||||
[2] = t.deleted and ui.Style(t.deleted) or ui.Style():fg("#ff4500"),
|
||||
[1] = t.updated and ui.Style(t.updated) or ui.Style():fg("#1e90ff"),
|
||||
}
|
||||
local signs = {
|
||||
[6] = t.modified_sign and t.modified_sign or "",
|
||||
[5] = t.added_sign and t.added_sign or "",
|
||||
[4] = t.untracked_sign and t.untracked_sign or "",
|
||||
[3] = t.ignored_sign and t.ignored_sign or "",
|
||||
[2] = t.deleted_sign and t.deleted_sign or "",
|
||||
[1] = t.updated_sign and t.updated_sign or "U",
|
||||
}
|
||||
|
||||
Linemode:children_add(function(self)
|
||||
local url = self._file.url
|
||||
local dir = st.dirs[tostring(url:parent())]
|
||||
local change
|
||||
if dir then
|
||||
change = dir == "" and 3 or st.repos[dir][tostring(url):sub(#dir + 2)]
|
||||
end
|
||||
|
||||
if not change or signs[change] == "" then
|
||||
return ""
|
||||
elseif self._file:is_hovered() then
|
||||
return ui.Line { " ", signs[change] }
|
||||
else
|
||||
return ui.Line { " ", ui.Span(signs[change]):style(styles[change]) }
|
||||
end
|
||||
end, opts.order)
|
||||
end
|
||||
|
||||
local function fetch(_, job)
|
||||
local cwd = job.files[1].url:parent()
|
||||
local repo = root(cwd)
|
||||
if not repo then
|
||||
remove(tostring(cwd))
|
||||
if not ya.__250127 then -- TODO: remove this
|
||||
return 1
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local paths = {}
|
||||
for _, f in ipairs(job.files) do
|
||||
paths[#paths + 1] = tostring(f.url)
|
||||
end
|
||||
|
||||
-- stylua: ignore
|
||||
local output, err = Command("git")
|
||||
:cwd(tostring(cwd))
|
||||
:args({ "--no-optional-locks", "-c", "core.quotePath=", "status", "--porcelain", "-unormal", "--no-renames", "--ignored=matching" })
|
||||
:args(paths)
|
||||
:stdout(Command.PIPED)
|
||||
:output()
|
||||
if not output then
|
||||
if not ya.__250127 then -- TODO: remove this
|
||||
ya.err("Cannot spawn git command, error: " .. err)
|
||||
return 0
|
||||
end
|
||||
return true, Err("Cannot spawn `git` command, error: %s", err)
|
||||
end
|
||||
|
||||
local changed, ignored = {}, {}
|
||||
for line in output.stdout:gmatch("[^\r\n]+") do
|
||||
local sign, path = match(line)
|
||||
if sign == 30 then
|
||||
ignored[path] = sign
|
||||
else
|
||||
changed[path] = sign
|
||||
end
|
||||
end
|
||||
|
||||
if job.files[1].cha.is_dir then
|
||||
ya.dict_merge(changed, bubble_up(changed))
|
||||
ya.dict_merge(changed, propagate_down(ignored, cwd, Url(repo)))
|
||||
else
|
||||
ya.dict_merge(changed, propagate_down(ignored, cwd, Url(repo)))
|
||||
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)
|
||||
|
||||
if not ya.__250127 then -- TODO: remove this
|
||||
return 3
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
return { setup = setup, fetch = fetch }
|
|
@ -1,21 +0,0 @@
|
|||
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.
|
|
@ -1,51 +0,0 @@
|
|||
# mount.yazi
|
||||
|
||||
> [!NOTE]
|
||||
> The plugin is currently very experimental, and the newest Yazi nightly is required for it to work.
|
||||
|
||||
A mount manager for Yazi, providing disk mount, unmount, and eject functionality.
|
||||
|
||||
Supported platforms:
|
||||
|
||||
- Linux with [`udisksctl`](https://github.com/storaged-project/udisks) and [`lsblk`](https://github.com/util-linux/util-linux)
|
||||
- macOS with `diskutil`
|
||||
|
||||
https://github.com/user-attachments/assets/c6f780ab-458b-420f-85cf-2fc45fcfe3a2
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
ya pack -a yazi-rs/plugins:mount
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Add this to your `~/.config/yazi/keymap.toml`:
|
||||
|
||||
```toml
|
||||
[[manager.prepend_keymap]]
|
||||
on = "M"
|
||||
run = "plugin mount"
|
||||
```
|
||||
|
||||
Available keybindings:
|
||||
|
||||
| Key binding | Alternate key | Action |
|
||||
| ------------ | ------------- | --------------------- |
|
||||
| <kbd>q</kbd> | - | Quit the plugin |
|
||||
| <kbd>k</kbd> | <kbd>↑</kbd> | Move up |
|
||||
| <kbd>j</kbd> | <kbd>↓</kbd> | Move down |
|
||||
| <kbd>l</kbd> | <kbd>→</kbd> | Enter the mount point |
|
||||
| <kbd>m</kbd> | - | Mount the partition |
|
||||
| <kbd>u</kbd> | - | Unmount the partition |
|
||||
| <kbd>e</kbd> | - | Eject the disk |
|
||||
|
||||
## TODO
|
||||
|
||||
- Custom keybindings
|
||||
- Windows support (I don't have an Windows machine for testing, PRs welcome!)
|
||||
- Support mount, unmount, and eject the entire disk
|
||||
|
||||
## License
|
||||
|
||||
This plugin is MIT-licensed. For more information check the [LICENSE](LICENSE) file.
|
|
@ -1,266 +0,0 @@
|
|||
local toggle_ui = ya.sync(function(self)
|
||||
if self.children then
|
||||
Modal:children_remove(self.children)
|
||||
self.children = nil
|
||||
else
|
||||
self.children = Modal:children_add(self, 10)
|
||||
end
|
||||
ya.render()
|
||||
end)
|
||||
|
||||
local subscribe = ya.sync(function(self)
|
||||
ps.unsub("mount")
|
||||
ps.sub("mount", function() ya.manager_emit("plugin", { self._id, args = "refresh" }) end)
|
||||
end)
|
||||
|
||||
local update_partitions = ya.sync(function(self, partitions)
|
||||
self.partitions = partitions
|
||||
self.cursor = math.max(0, math.min(self.cursor or 0, #self.partitions - 1))
|
||||
ya.render()
|
||||
end)
|
||||
|
||||
local active_partition = ya.sync(function(self) return self.partitions[self.cursor + 1] end)
|
||||
|
||||
local update_cursor = ya.sync(function(self, cursor)
|
||||
if #self.partitions == 0 then
|
||||
self.cursor = 0
|
||||
else
|
||||
self.cursor = ya.clamp(0, self.cursor + cursor, #self.partitions - 1)
|
||||
end
|
||||
ya.render()
|
||||
end)
|
||||
|
||||
local M = {
|
||||
keys = {
|
||||
{ on = "q", run = "quit" },
|
||||
|
||||
{ on = "k", run = "up" },
|
||||
{ on = "j", run = "down" },
|
||||
{ on = "l", run = { "enter", "quit" } },
|
||||
|
||||
{ on = "<Up>", run = "up" },
|
||||
{ on = "<Down>", run = "down" },
|
||||
{ on = "<Right>", run = { "enter", "quit" } },
|
||||
|
||||
{ on = "m", run = "mount" },
|
||||
{ on = "u", run = "unmount" },
|
||||
{ on = "e", run = "eject" },
|
||||
},
|
||||
}
|
||||
|
||||
function M:new(area)
|
||||
self:layout(area)
|
||||
return self
|
||||
end
|
||||
|
||||
function M:layout(area)
|
||||
local chunks = ui.Layout()
|
||||
:constraints({
|
||||
ui.Constraint.Percentage(10),
|
||||
ui.Constraint.Percentage(80),
|
||||
ui.Constraint.Percentage(10),
|
||||
})
|
||||
:split(area)
|
||||
|
||||
local chunks = ui.Layout()
|
||||
:direction(ui.Layout.HORIZONTAL)
|
||||
:constraints({
|
||||
ui.Constraint.Percentage(10),
|
||||
ui.Constraint.Percentage(80),
|
||||
ui.Constraint.Percentage(10),
|
||||
})
|
||||
:split(chunks[2])
|
||||
|
||||
self._area = chunks[2]
|
||||
end
|
||||
|
||||
function M:entry(job)
|
||||
if job.args[1] == "refresh" then
|
||||
return update_partitions(self.obtain())
|
||||
end
|
||||
|
||||
toggle_ui()
|
||||
update_partitions(self.obtain())
|
||||
subscribe()
|
||||
|
||||
local tx1, rx1 = ya.chan("mpsc")
|
||||
local tx2, rx2 = ya.chan("mpsc")
|
||||
function producer()
|
||||
while true do
|
||||
local cand = self.keys[ya.which { cands = self.keys, silent = true }] or { run = {} }
|
||||
for _, r in ipairs(type(cand.run) == "table" and cand.run or { cand.run }) do
|
||||
tx1:send(r)
|
||||
if r == "quit" then
|
||||
toggle_ui()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function consumer1()
|
||||
repeat
|
||||
local run = rx1:recv()
|
||||
if run == "quit" then
|
||||
tx2:send(run)
|
||||
break
|
||||
elseif run == "up" then
|
||||
update_cursor(-1)
|
||||
elseif run == "down" then
|
||||
update_cursor(1)
|
||||
elseif run == "enter" then
|
||||
local active = active_partition()
|
||||
if active and active.dist then
|
||||
ya.manager_emit("cd", { active.dist })
|
||||
end
|
||||
else
|
||||
tx2:send(run)
|
||||
end
|
||||
until not run
|
||||
end
|
||||
|
||||
function consumer2()
|
||||
repeat
|
||||
local run = rx2:recv()
|
||||
if run == "quit" then
|
||||
break
|
||||
elseif run == "mount" then
|
||||
self.operate("mount")
|
||||
elseif run == "unmount" then
|
||||
self.operate("unmount")
|
||||
elseif run == "eject" then
|
||||
self.operate("eject")
|
||||
end
|
||||
until not run
|
||||
end
|
||||
|
||||
ya.join(producer, consumer1, consumer2)
|
||||
end
|
||||
|
||||
function M:reflow() return { self } end
|
||||
|
||||
function M:redraw()
|
||||
local rows = {}
|
||||
for _, p in ipairs(self.partitions or {}) do
|
||||
if p.sub == "" then
|
||||
rows[#rows + 1] = ui.Row { p.main }
|
||||
else
|
||||
rows[#rows + 1] = ui.Row { p.sub, p.label or "", p.dist or "", p.fstype or "" }
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
ui.Clear(self._area),
|
||||
ui.Border(ui.Border.ALL)
|
||||
:area(self._area)
|
||||
:type(ui.Border.ROUNDED)
|
||||
:style(ui.Style():fg("blue"))
|
||||
:title(ui.Line("Mount"):align(ui.Line.CENTER)),
|
||||
ui.Table(rows)
|
||||
:area(self._area:pad(ui.Pad(1, 2, 1, 2)))
|
||||
:header(ui.Row({ "Src", "Label", "Dist", "FSType" }):style(ui.Style():bold()))
|
||||
:row(self.cursor)
|
||||
:row_style(ui.Style():fg("blue"):underline())
|
||||
:widths {
|
||||
ui.Constraint.Length(20),
|
||||
ui.Constraint.Length(20),
|
||||
ui.Constraint.Percentage(70),
|
||||
ui.Constraint.Length(10),
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
function M.obtain()
|
||||
local tbl = {}
|
||||
local last
|
||||
for _, p in ipairs(fs.partitions()) do
|
||||
local main, sub
|
||||
if ya.target_os() == "macos" then
|
||||
main, sub = p.src:match("^(/dev/disk%d+)(.+)$")
|
||||
elseif p.src:find("/dev/nvme", 1, true) == 1 then -- /dev/nvme0n1p1
|
||||
main, sub = p.src:match("^(/dev/nvme%d+n%d+)(p%d+)$")
|
||||
elseif p.src:find("/dev/sd", 1, true) == 1 then -- /dev/sda1
|
||||
main, sub = p.src:match("^(/dev/sd[a-z])(%d+)$")
|
||||
end
|
||||
if sub then
|
||||
if last ~= main then
|
||||
last, tbl[#tbl + 1] = main, { src = main, main = main, sub = "" }
|
||||
end
|
||||
p.main, p.sub, tbl[#tbl + 1] = main, " " .. sub, p
|
||||
end
|
||||
end
|
||||
table.sort(M.fillin(tbl), function(a, b)
|
||||
if a.main == b.main then
|
||||
return a.sub < b.sub
|
||||
else
|
||||
return a.main > b.main
|
||||
end
|
||||
end)
|
||||
return tbl
|
||||
end
|
||||
|
||||
function M.fillin(tbl)
|
||||
if ya.target_os() ~= "linux" then
|
||||
return tbl
|
||||
end
|
||||
|
||||
local sources, indices = {}, {}
|
||||
for i, p in ipairs(tbl) do
|
||||
if p.sub ~= "" and not p.fstype then
|
||||
sources[#sources + 1], indices[p.src] = p.src, i
|
||||
end
|
||||
end
|
||||
if #sources == 0 then
|
||||
return tbl
|
||||
end
|
||||
|
||||
local output, err = Command("lsblk"):args({ "-p", "-o", "name,fstype", "-J" }):args(sources):output()
|
||||
if err then
|
||||
ya.dbg("Failed to fetch filesystem types for unmounted partitions: " .. err)
|
||||
return tbl
|
||||
end
|
||||
|
||||
local t = ya.json_decode(output and output.stdout or "")
|
||||
for _, p in ipairs(t and t.blockdevices or {}) do
|
||||
tbl[indices[p.name]].fstype = p.fstype
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
function M.operate(type)
|
||||
local active = active_partition()
|
||||
if not active then
|
||||
return
|
||||
elseif active.sub == "" then
|
||||
return -- TODO: mount/unmount main disk
|
||||
end
|
||||
|
||||
local output, err
|
||||
if ya.target_os() == "macos" then
|
||||
output, err = Command("diskutil"):args({ type, active.src }):output()
|
||||
end
|
||||
if ya.target_os() == "linux" then
|
||||
if type == "eject" then
|
||||
Command("udisksctl"):args({ "unmount", "-b", active.src }):status()
|
||||
output, err = Command("udisksctl"):args({ "power-off", "-b", active.src }):output()
|
||||
else
|
||||
output, err = Command("udisksctl"):args({ type, "-b", active.src }):output()
|
||||
end
|
||||
end
|
||||
|
||||
if not output then
|
||||
M.fail("Failed to %s `%s`: %s", type, active.src, err)
|
||||
elseif not output.status.success then
|
||||
M.fail("Failed to %s `%s`: %s", type, active.src, output.stderr)
|
||||
end
|
||||
end
|
||||
|
||||
function M.fail(s, ...) ya.notify { title = "Mount", content = string.format(s, ...), timeout = 10, level = "error" } end
|
||||
|
||||
function M:click() end
|
||||
|
||||
function M:scroll() end
|
||||
|
||||
function M:touch() end
|
||||
|
||||
return M
|
|
@ -1,11 +0,0 @@
|
|||
--- @since 25.2.7
|
||||
--- @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 }
|
1
modules/home/yazi/plugins/yazi-plugins
Submodule
1
modules/home/yazi/plugins/yazi-plugins
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 9a095057d698aaaedc4dd23d638285bd3fd647e9
|
Loading…
Add table
Add a link
Reference in a new issue