summaryrefslogtreecommitdiff
path: root/yazi/plugins/rsync.yazi
diff options
context:
space:
mode:
authorsubh <subh@subh.space>2026-04-03 14:47:03 +0530
committersubh <subh@subh.space>2026-04-03 14:47:03 +0530
commit314d760de1922128124f2a9be0494fd4f6f7effb (patch)
tree3f4bb374fc89be2b1cd4e2a0a21ae17d4bf83452 /yazi/plugins/rsync.yazi
parent0203dd4b8d45c663356f797c11be17fdec6f22f2 (diff)
new music bar, auto usb mounting and more
Diffstat (limited to 'yazi/plugins/rsync.yazi')
-rw-r--r--yazi/plugins/rsync.yazi/LICENSE21
-rw-r--r--yazi/plugins/rsync.yazi/README.md66
-rw-r--r--yazi/plugins/rsync.yazi/assets/demo.gifbin0 -> 9593417 bytes
-rw-r--r--yazi/plugins/rsync.yazi/assets/demo.webmbin0 -> 1121014 bytes
-rw-r--r--yazi/plugins/rsync.yazi/main.lua137
5 files changed, 224 insertions, 0 deletions
diff --git a/yazi/plugins/rsync.yazi/LICENSE b/yazi/plugins/rsync.yazi/LICENSE
new file mode 100644
index 0000000..fb5b1d6
--- /dev/null
+++ b/yazi/plugins/rsync.yazi/LICENSE
@@ -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.
diff --git a/yazi/plugins/rsync.yazi/README.md b/yazi/plugins/rsync.yazi/README.md
new file mode 100644
index 0000000..afbdd68
--- /dev/null
+++ b/yazi/plugins/rsync.yazi/README.md
@@ -0,0 +1,66 @@
+# Rsync.yazi
+
+A [yazi](https://yazi-rs.github.io/) plugin for simple rsync copying locally and up to remote servers.
+
+![Demo](assets/demo.gif)
+Thanks to [chrissabug](https://x.com/chrissabug) for creating lovely art!
+
+## Pre-Reqs
+
+1. yazi latest version preferred
+2. rsync
+3. passwordless authentication if copying to a remote server
+
+## Installation
+
+```sh
+ya pkg add GianniBYoung/rsync
+```
+
+## Usage
+
+Add the binds to your `~/.config/yazi/keymap.toml`
+
+**WARNING:** Make sure the chosen binding isn't already in use!!
+
+```toml
+[[mgr.prepend_keymap]]
+on = [ "R" ]
+run = "plugin rsync"
+desc = "Copy files using rsync"
+```
+
+### Specify Default Remote Server
+
+```toml
+[[mgr.prepend_keymap]]
+on = [ "R" ]
+run = "plugin rsync 'user@server.com'"
+desc = "Copy files using rsync to default location"
+```
+
+### Remember Last Target
+
+Use `--remember` to cache the last used target. On next invocation, the input field will be pre-filled with the cached target.
+
+```toml
+[[mgr.prepend_keymap]]
+on = [ "R" ]
+run = "plugin rsync -- --remember"
+desc = "Copy files using rsync (remember target)"
+```
+
+**Note:** The target is stored in `~/.config/yazi/plugins/rsync.yazi/.last_target`
+
+## Troubleshooting
+
+Basic logging information is sent to `~/.local/state/yazi/yazi.log`
+
+*Note: This plugin has only been tested on Linux
+
+## Contributing
+
+Run into a bug or want a certain feature added? Submit an issue!
+
+- Give it a star if you like it ⭐!
+- PRs welcome :)
diff --git a/yazi/plugins/rsync.yazi/assets/demo.gif b/yazi/plugins/rsync.yazi/assets/demo.gif
new file mode 100644
index 0000000..e51aa96
--- /dev/null
+++ b/yazi/plugins/rsync.yazi/assets/demo.gif
Binary files differ
diff --git a/yazi/plugins/rsync.yazi/assets/demo.webm b/yazi/plugins/rsync.yazi/assets/demo.webm
new file mode 100644
index 0000000..ab7d3d1
--- /dev/null
+++ b/yazi/plugins/rsync.yazi/assets/demo.webm
Binary files differ
diff --git a/yazi/plugins/rsync.yazi/main.lua b/yazi/plugins/rsync.yazi/main.lua
new file mode 100644
index 0000000..ad2957e
--- /dev/null
+++ b/yazi/plugins/rsync.yazi/main.lua
@@ -0,0 +1,137 @@
+-- function borrowed from chmod.yazi plugin
+local selected_or_hovered = ya.sync(function()
+ local tab = cx.active
+ local paths = {}
+
+ -- count up selected files
+ for _, url in pairs(tab.selected) do
+ paths[#paths + 1] = tostring(url)
+ end
+
+ -- if no files are selected use the hovered file
+ -- a tab has folders which have files which have urls
+ if #paths == 0 and tab.current.hovered then
+ -- lua so we are 1 indexed
+ paths[1] = tostring(tab.current.hovered.url)
+ end
+ return paths
+end)
+
+-- Helper function to expand tilde (~) in a path
+local function expand_tilde(path)
+ if not path then
+ return nil
+ end
+
+ if path:sub(1, 1) == "~" then
+ local home = os.getenv("HOME") -- Get HOME environment variable
+ if not home then
+ -- Fallback for Windows-specific environment variables
+ home = os.getenv("USERPROFILE") -- Primary user profile directory on Windows
+ end
+ if home then
+ return home .. path:sub(2) -- Concatenate home path with the rest of the path
+ else
+ -- Fallback if HOME is not set
+ ya.notify({
+ title = "Rsync Plugin",
+ content = "Could not expand '~': HOME environment variable not set.",
+ level = "warn",
+ timeout = 5,
+ })
+ return path -- Return original path if home cannot be determined
+ end
+ end
+ return path -- Return original path if no tilde
+end
+
+return {
+ entry = function(_, job)
+ ya.mgr_emit("escape", { visual = true })
+ local remote_target = job.args and #job.args >= 1 and job.args[1] or nil
+ local remember = job.args and job.args.remember
+
+ local cache_file = os.getenv("HOME") .. "/.config/yazi/plugins/rsync.yazi/.last_target"
+
+ local cached_target = ""
+ if remember then
+ local f = io.open(cache_file, "r")
+ if f then
+ cached_target = f:read("*a"):match("^%s*(.-)%s*$")
+ f:close()
+ end
+ end
+
+ local files = selected_or_hovered()
+ if #files == 0 then
+ return ya.notify({ title = "Rsync", content = "No files selected", level = "warn", timeout = 3 })
+ end
+
+ local default_dest = remote_target or cached_target
+ if #files == 1 and remote_target ~= nil then
+ local base_name = files[1]:match("([^/]+)$")
+ default_dest = remote_target .. ":" .. base_name
+ ya.err({ default_dest = default_dest })
+ end
+
+ local dest, ok = ya.input({
+ title = "Rsync - [user]@[remote]:<destination>",
+ value = default_dest or nil,
+ pos = { "top-center", y = 3, w = 45 },
+ })
+ if ok ~= 1 then
+ return
+ end
+
+ -- Only expand tilde if it's a local path (doesn't contain ':')
+ if not dest:match(":") then
+ dest = expand_tilde(dest)
+ if not dest then
+ return
+ end -- If expand_tilde failed and returned nil
+ end
+
+ -- local cmd, err = Command("rsync"):args(files):arg(dest):stderr(Command.PIPED):output()
+ local cmd, err = Command("rsync")
+ :arg({ "-ahP", "--no-motd" })
+ :arg(files)
+ :arg(dest)
+ :stdout(Command.PIPED)
+ :stderr(Command.PIPED)
+ :output()
+ local stderr = cmd.stderr
+ local stdout = cmd.stdout
+ local return_code = cmd.status.code
+ ya.err({
+ stderr = stderr,
+ stdout = stdout,
+ err = err,
+ res = cmd.status.success,
+ return_code = return_code,
+ default_dest = default_dest,
+ })
+
+ if return_code ~= 0 then
+ ya.notify({
+ title = "Rsync Plugin",
+ content = string.format("stderr below, exit code %s\n\n%s", cmd.status.code, stderr),
+ level = "error",
+ timeout = 10,
+ })
+ else
+ ya.notify({
+ title = "Rsync Plugin",
+ content = "Rsync Completed!",
+ timeout = 3,
+ })
+
+ if remember and dest and dest ~= "" then
+ local f = io.open(cache_file, "w")
+ if f then
+ f:write(dest)
+ f:close()
+ end
+ end
+ end
+ end,
+}