From b6fc6f4a0e3a8a83a2499ab8c6a86920be0e5f4d Mon Sep 17 00:00:00 2001 From: Xerxes-2 Date: Sun, 23 Jun 2024 05:39:04 +1000 Subject: [PATCH] fix issues when rename symlink itself --- Cargo.lock | 7 ++++--- cspell.json | 2 +- yazi-shared/Cargo.toml | 1 + yazi-shared/src/fs/fns.rs | 23 ++++++++++++++++++++--- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5d0debff..ed81e616 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2492,11 +2492,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -2964,6 +2964,7 @@ dependencies = [ "serde", "shell-words", "tokio", + "winapi-util", ] [[package]] diff --git a/cspell.json b/cspell.json index aed43d6c..4a57706c 100644 --- a/cspell.json +++ b/cspell.json @@ -1 +1 @@ -{"version":"0.2","flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname"],"language":"en"} \ No newline at end of file +{"version":"0.2","flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","winapi"],"language":"en"} \ No newline at end of file diff --git a/yazi-shared/Cargo.toml b/yazi-shared/Cargo.toml index 414bba0d..369275d0 100644 --- a/yazi-shared/Cargo.toml +++ b/yazi-shared/Cargo.toml @@ -22,6 +22,7 @@ regex = "1.10.5" serde = { version = "1.0.203", features = [ "derive" ] } shell-words = "1.1.0" tokio = { version = "1.38.0", features = [ "full" ] } +winapi-util = "0.1.8" [target."cfg(unix)".dependencies] libc = "0.2.155" diff --git a/yazi-shared/src/fs/fns.rs b/yazi-shared/src/fs/fns.rs index b8bd205f..c5d757bf 100644 --- a/yazi-shared/src/fs/fns.rs +++ b/yazi-shared/src/fs/fns.rs @@ -2,6 +2,7 @@ use std::{borrow::Cow, collections::{HashMap, VecDeque}, ffi::{OsStr, OsString}, use anyhow::{bail, Result}; use tokio::{fs, io, select, sync::{mpsc, oneshot}, time}; +use winapi_util::{file::information, Handle}; #[inline] pub async fn must_exists(p: impl AsRef) -> bool { fs::symlink_metadata(p).await.is_ok() } @@ -25,9 +26,25 @@ pub fn ok_or_not_found(result: io::Result<()>) -> io::Result<()> { #[inline] pub async fn are_paths_equal(old: impl AsRef, new: impl AsRef) -> bool { - match (fs::canonicalize(old).await, fs::canonicalize(new).await) { - (Ok(old), Ok(new)) => old == new, - _ => false, + #[cfg(unix)] + { + match (fs::metadata(old).await, fs::metadata(new).await) { + (Ok(old), Ok(new)) => old.dev() == new.dev() && old.ino() == new.ino(), + _ => false, + } + } + #[cfg(windows)] + { + match (Handle::from_path_any(old), Handle::from_path_any(new)) { + (Ok(old), Ok(new)) => match (information(old), information(new)) { + (Ok(old), Ok(new)) => { + old.volume_serial_number() == new.volume_serial_number() + && old.file_index() == new.file_index() + } + _ => false, + }, + _ => false, + } } }