Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@sxyazi
Copy link
Owner

@sxyazi sxyazi commented Dec 27, 2025

An implementation of the feature request: #3408

fs.copy(from, to) - copy a file

  • from: source file URL
  • to: destination URL
  • Returns (len, err)
    • len: length of the copied content, which is an integer, or nil if the operation fails
    • err: Error of the failure

Notes:

  • This API will overwrite the destination file.
  • If from and to are the same file, the file will likely get truncated by this operation.
  • This API follows symlinks for both from and to if they exist.

fs.rename(from, to) - rename a file

  • from: source file URL
  • to: destination URL
  • Returns (ok, err)
    • ok: whether this operation succeeds, which is a boolean
    • err: Error of the failure

Notes:

  • This API will overwrite the destination file.
  • This API does not work if from and to are on different filesystems.

If you want to move files across filesystems, use the combination fs.copy() and fs.remove():

local from = Url("/mnt/dev1/a")
local to = Url("/mnt/dev2/b")

local ok, err = fs.rename(from, to)
if not ok and err.kind == "CrossesDevices" then
  local len, err = fs.copy(from, to)
  if len and not err then
    fs.remove("file", from)
  end
end

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds new fs.copy() and fs.rename() Lua APIs to Yazi's plugin system, enabling scripts to programmatically copy and rename files. The implementation includes support for both local and SFTP filesystems, with appropriate error handling for cross-device operations.

Key changes include:

  • New fs.copy(from, to) and fs.rename(from, to) Lua APIs with proper error handling
  • Refactored Attrs conversion logic from From to TryFrom to handle cases where attributes are empty or invalid
  • Updated dependencies (ratatui 0.29.0 → 0.30.0, with corresponding API updates)

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
yazi-plugin/src/fs/fs.rs Adds Lua bindings for copy and rename operations, returning appropriate success/error values
yazi-fs/src/provider/attrs.rs Converts From implementations to TryFrom for FileTimes and Permissions, adds helper methods
yazi-fs/src/provider/local/copier.rs Updates attribute setting logic to use TryFrom pattern instead of unconditional conversion
yazi-vfs/src/provider/rw_file.rs Refactors set_attrs to check for empty attributes and handle conversion failures gracefully
yazi-vfs/src/provider/sftp/*.rs Updates SFTP provider to use TryFrom for attribute conversion with fallback to defaults
yazi-sftp/src/fs/attrs.rs Adds is_empty() method and Eq/PartialEq derives to support empty attribute detection
yazi-binding/src/elements/border.rs Updates ratatui API usage from deprecated Position to TitlePosition
yazi-plugin/src/utils/spot.rs Updates ratatui API usage from deprecated Position to TitlePosition
yazi-fm/src/tasks/tasks.rs Updates ratatui widget rendering API from render_ref to reference-based render
Cargo.toml Upgrades ratatui (0.29.0 → 0.30.0), ansi-to-tui (7.0.0 → 8.0.0), and other dependencies
Cargo.lock Reflects updated dependency versions and transitive dependencies
CHANGELOG.md Documents the new fs.copy() and fs.rename() APIs

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

pub async fn set_attrs(&self, attrs: Attrs) -> io::Result<()> {
match self {
Self::Tokio(f) => {
let (perm, times) = (attrs.try_into(), attrs.try_into());
Copy link

Copilot AI Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type inference for these try_into() calls relies on the compiler determining which TryFrom implementation to use based on context. Consider adding explicit type annotations to improve code clarity and make the conversions more self-documenting.

Suggested change
let (perm, times) = (attrs.try_into(), attrs.try_into());
let (perm, times): (Result<std::fs::Permissions, _>, Result<std::fs::FileTimes, _>) =
(attrs.try_into(), attrs.try_into());

Copilot uses AI. Check for mistakes.
@sxyazi sxyazi merged commit 77d36ff into main Dec 27, 2025
16 checks passed
@sxyazi sxyazi deleted the pr-a6c58011 branch December 27, 2025 09:52
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Jan 5, 2026
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [sxyazi/yazi](https://github.com/sxyazi/yazi) | minor | `v25.5.31` → `v25.12.29` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>sxyazi/yazi (sxyazi/yazi)</summary>

### [`v25.12.29`](https://github.com/sxyazi/yazi/blob/HEAD/CHANGELOG.md#v251229)

[Compare Source](sxyazi/yazi@v25.5.31...v25.12.29)

##### Added

- Remote file management (\[[#&#8203;3396](sxyazi/yazi#3396)])
- Virtual file system (\[[#&#8203;3034](sxyazi/yazi#3034)], \[[#&#8203;3035](sxyazi/yazi#3035)], \[[#&#8203;3094](sxyazi/yazi#3094)], \[[#&#8203;3108](sxyazi/yazi#3108)], \[[#&#8203;3187](sxyazi/yazi#3187)], \[[#&#8203;3203](sxyazi/yazi#3203)])
- Shell formatting (\[[#&#8203;3232](sxyazi/yazi#3232)])
- Multi-entry support for plugin system (\[[#&#8203;3154](sxyazi/yazi#3154)])
- Zoom in or out of the preview image (\[[#&#8203;2864](sxyazi/yazi#2864)])
- Improve the UX of the pick and input components (\[[#&#8203;2906](sxyazi/yazi#2906)], \[[#&#8203;2935](sxyazi/yazi#2935)])
- Show progress of each task in task manager (\[[#&#8203;3121](sxyazi/yazi#3121)], \[[#&#8203;3131](sxyazi/yazi#3131)], \[[#&#8203;3134](sxyazi/yazi#3134)])
- New `fs.copy()` and `fs.rename()` APIs (\[[#&#8203;3467](sxyazi/yazi#3467)])
- New experimental `ya.async()` API (\[[#&#8203;3422](sxyazi/yazi#3422)])
- New `overall` option to set the overall background color (\[[#&#8203;3317](sxyazi/yazi#3317)])
- Rounded corners for indicator bar (\[[#&#8203;3419](sxyazi/yazi#3419)])
- New `bulk_rename` command always renames files with the editor (\[[#&#8203;2984](sxyazi/yazi#2984)])
- `key-*` DDS events to allow changing or canceling user key events (\[[#&#8203;3005](sxyazi/yazi#3005)], \[[#&#8203;3037](sxyazi/yazi#3037)])
- New `--bg` specifying image background color in the preset SVG and ImageMagick previewers (\[[#&#8203;3189](sxyazi/yazi#3189)])
- `filter` by full path (prefix + filename) in search view instead of just filename (\[[#&#8203;2915](sxyazi/yazi#2915)])
- New `casefy` command for case conversion of the input content (\[[#&#8203;3235](sxyazi/yazi#3235)])
- Allow dynamic adjustment of layout ratio via `rt.mgr.ratio` (\[[#&#8203;2964](sxyazi/yazi#2964)])
- Support `.deb` packages (\[[#&#8203;2807](sxyazi/yazi#2807)], \[[#&#8203;3128](sxyazi/yazi#3128)], \[[#&#8203;3209](sxyazi/yazi#3209)])
- Port several widespread GUI keys to the input component (\[[#&#8203;2849](sxyazi/yazi#2849)])
- Support invalid UTF-8 paths throughout the codebase (\[[#&#8203;2884](sxyazi/yazi#2884)], \[[#&#8203;2889](sxyazi/yazi#2889)], \[[#&#8203;2890](sxyazi/yazi#2890)], \[[#&#8203;2895](sxyazi/yazi#2895)], \[[#&#8203;3023](sxyazi/yazi#3023)], \[[#&#8203;3290](sxyazi/yazi#3290)], \[[#&#8203;3369](sxyazi/yazi#3369)])
- Allow upgrading only specific packages with `ya pkg` (\[[#&#8203;2841](sxyazi/yazi#2841)])
- Respect the user's `image_filter` setting in the preset ImageMagick previewer (\[[#&#8203;3286](sxyazi/yazi#3286)])
- New `duplicate` DDS event for copying files (\[[#&#8203;3456](sxyazi/yazi#3456)])
- New `ind-sort` and `key-sort` DDS events to change sorting in Lua (\[[#&#8203;3391](sxyazi/yazi#3391)])
- Allow custom mouse click behavior for individual files (\[[#&#8203;2925](sxyazi/yazi#2925)])
- Display newlines in input as spaces to improve readability (\[[#&#8203;2932](sxyazi/yazi#2932)])
- Fill in error messages if preview fails (\[[#&#8203;2917](sxyazi/yazi#2917)], \[[#&#8203;3383](sxyazi/yazi#3383)], \[[#&#8203;3387](sxyazi/yazi#3387)])
- Search view shares file selection and yank state (\[[#&#8203;2855](sxyazi/yazi#2855)])
- Offload mimetype fetching on opening files to the task scheduler (\[[#&#8203;3141](sxyazi/yazi#3141)])
- Increase terminal response timeout to better tolerate slow SSH network environments (\[[#&#8203;2843](sxyazi/yazi#2843)])

##### Changed

- Rename `name` to `url` for open, fetchers, spotters, preloaders, previewers, filetype, and `globs` icon rules to support virtual file system (\[[#&#8203;3034](sxyazi/yazi#3034)])
- Rename `mime` fetcher to `mime.local`, and introduce `mime.dir` fetcher to support folder MIME types (\[[#&#8203;3222](sxyazi/yazi#3222)])
- Reclassify `hovered` and `preview_hovered` under `[mgr]` of `theme.toml` into `[indicator]` as `current` and `preview`, respectively (\[[#&#8203;3419](sxyazi/yazi#3419)])
- Remove `$0` parameter in opener rules to make the `open` command work under empty directories (\[[#&#8203;3226](sxyazi/yazi#3226)])
- Return `Path` instead of `Url` from `Url:strip_prefix()` and `File.link_to` to enforce type safety (\[[#&#8203;3361](sxyazi/yazi#3361)], \[[#&#8203;3385](sxyazi/yazi#3385)])
- Use `body` instead of the term `content` in confirmations (\[[#&#8203;2921](sxyazi/yazi#2921)])
- Use `u16` instead of `u32` as the type of `max_width` and `max_height` options to avoid memory exhaustion (\[[#&#8203;3313](sxyazi/yazi#3313)])
- Implement `__pairs` metamethod instead of `__index` for the callback argument of the `@yank` DDS event (\[[#&#8203;2997](sxyazi/yazi#2997)])

##### Deprecated

- Deprecate `$n`, `$@&#8203;` (\*nix) and `%n`, `%*` (Windows) in `shell` command and opener rules in favor of new shell formatting (\[[#&#8203;3232](sxyazi/yazi#3232)])
- Deprecate `ya.hide`, `ya.render`, and `ya.truncate` in favor of `ui.hide`, `ui.render`, and `ui.truncate` (\[[#&#8203;2939](sxyazi/yazi#2939)])
- Deprecate `position` property of `ya.input()` in favor of `pos` to align with `ya.confirm()` and its type `ui.Pos` (\[[#&#8203;2921](sxyazi/yazi#2921)])
- Deprecate `cx.tasks.progress` in favor of `cx.tasks.summary` (\[[#&#8203;3131](sxyazi/yazi#3131)])
- Deprecate `frag` properly of `Url` in favor of `domain` (\[[#&#8203;3034](sxyazi/yazi#3034)])
- Deprecate `ui.Rect.default` in favor of `ui.Rect {}` (\[[#&#8203;2927](sxyazi/yazi#2927)])

##### Fixed

- User-prepended open rules do not override presets (\[[#&#8203;3360](sxyazi/yazi#3360)])
- Respect user's system media opener instead of hardcoding `mpv` (\[[#&#8203;2959](sxyazi/yazi#2959)])
- Incorrect `$0` and `$@&#8203;` parameters in `shell` command under empty directories (\[[#&#8203;3225](sxyazi/yazi#3225)])
- Avoid appending a newline when reading clipboard contents (\[[#&#8203;3059](sxyazi/yazi#3059)])
- Renew package `rev` only when it's empty (\[[#&#8203;3200](sxyazi/yazi#3200)])
- Suspend only when there is a parent process (\[[#&#8203;3008](sxyazi/yazi#3008)])
- Preserve open order for files with post-resolved MIME types (\[[#&#8203;2931](sxyazi/yazi#2931)])
- A race condition in concurrent directory loading on a slow device (\[[#&#8203;3271](sxyazi/yazi#3271)])
- Erase overlapping image portions when previewing errors (\[[#&#8203;3067](sxyazi/yazi#3067)])
- Force Git checkout for plugin cache repositories (\[[#&#8203;3169](sxyazi/yazi#3169)])
- Check compatibility when reusing previewer bytecode cache (\[[#&#8203;3190](sxyazi/yazi#3190)])
- Disable kitty keyboard protocol on Windows due to `crossterm` inability to handle it (\[[#&#8203;3250](sxyazi/yazi#3250)])
- Prevent quotes in file(1) arguments from being stripped under MSYS2 (\[[#&#8203;3364](sxyazi/yazi#3364)])
- Expose `ya` CLI in the Snap build (\[[#&#8203;2904](sxyazi/yazi#2904)])
- Fallback to `PollWatcher` for file changes watching on NetBSD (\[[#&#8203;2941](sxyazi/yazi#2941)])
- Generate unique image IDs for Kgp to tolerate tmux (\[[#&#8203;3038](sxyazi/yazi#3038)])

##### Improved

- Make copy, cut, delete, link, hardlink, download, and upload tasks immediately cancellable (\[[#&#8203;3429](sxyazi/yazi#3429)])
- Make preload tasks discardable (\[[#&#8203;2875](sxyazi/yazi#2875)])
- Reduce file change event frequency (\[[#&#8203;2820](sxyazi/yazi#2820)])
- Upload and download of a single file over SFTP in chunks concurrently (\[[#&#8203;3393](sxyazi/yazi#3393)])
- Do not listen for file changes in inactive tabs (\[[#&#8203;2958](sxyazi/yazi#2958)])
- Switch to a higher-performance hash algorithm (\[[#&#8203;3083](sxyazi/yazi#3083)])
- Sequence-based rendering merge strategy (\[[#&#8203;2861](sxyazi/yazi#2861)])
- Store only `Urn` instead of full `Url` in find results (\[[#&#8203;2914](sxyazi/yazi#2914)])
- Zero-copy `UrlBuf` to `Url` conversion (\[[#&#8203;3117](sxyazi/yazi#3117)])
- String interning to reduce memory usage of mimetype and URL domain (\[[#&#8203;3084](sxyazi/yazi#3084)], \[[#&#8203;3091](sxyazi/yazi#3091)])
- Do not pre-allocate memory for Lua tables (\[[#&#8203;2879](sxyazi/yazi#2879)])
- Copy-on-write on command data, and avoid converting primitive types to strings thereby allocating memory (\[[#&#8203;2862](sxyazi/yazi#2862)])
- Use `AnyUserData::type_id()` to reduce stack pushes (\[[#&#8203;2834](sxyazi/yazi#2834)])
- App data instead of Lua registry to reduce stack pushes (\[[#&#8203;2880](sxyazi/yazi#2880)])

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi42Ni4xMSIsInVwZGF0ZWRJblZlciI6IjQyLjY2LjExIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiLCJhdXRvbWF0aW9uOmJvdC1hdXRob3JlZCIsImRlcGVuZGVuY3ktdHlwZTo6bWlub3IiXX0=-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants