diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 00000000..df06aa5e --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,16 @@ +[env] +MACOSX_DEPLOYMENT_TARGET = "10.12" +JEMALLOC_SYS_WITH_LG_PAGE = "16" + +# environment variable for tikv-jemalloc-sys +# +# https://jemalloc.net/jemalloc.3.html#opt.narenas +# narenas is the maximum number of arenas to use for automatic multiplexing +# of threads and arenas. The default is four times the number of CPUs, +# or one if there is a single CPU. +# +# Improve memory efficiency by reducing fragmentation and ensuring all threads allocate from the same pool +JEMALLOC_SYS_WITH_MALLOC_CONF = "narenas:1" + +[target.aarch64-apple-darwin] +rustflags = [ "-Ctarget-cpu=apple-m1" ] diff --git a/Cargo.lock b/Cargo.lock index 5b7794d8..3a582eab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -391,9 +391,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.44" +version = "4.5.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c1f056bae57e3e54c3375c41ff79619ddd13460a17d7438712bd0d83fda4ff8" +checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318" dependencies = [ "clap_builder", "clap_derive", @@ -442,9 +442,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.41" +version = "4.5.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" +checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" dependencies = [ "heck", "proc-macro2", @@ -2145,9 +2145,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -2514,9 +2514,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.104" +version = "2.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "7bc3fcb250e53458e712715cf74285c1f889686520d79294a9ef3bd7aa1fc619" dependencies = [ "proc-macro2", "quote", @@ -3567,6 +3567,13 @@ dependencies = [ "yazi-shared", ] +[[package]] +name = "yazi-build" +version = "0.1.8" +dependencies = [ + "yazi-term", +] + [[package]] name = "yazi-cli" version = "25.6.11" diff --git a/Cargo.toml b/Cargo.toml index 91ba220d..8952cd0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ ansi-to-tui = "7.0.0" anyhow = "1.0.99" base64 = "0.22.1" bitflags = { version = "2.9.1", features = [ "serde" ] } -clap = { version = "4.5.44", features = [ "derive" ] } +clap = { version = "4.5.45", features = [ "derive" ] } core-foundation-sys = "0.8.7" crossterm = { version = "0.29.0", features = [ "event-stream" ] } dirs = "6.0.0" diff --git a/cspell.json b/cspell.json index 175105ee..d3ef44a8 100644 --- a/cspell.json +++ b/cspell.json @@ -1 +1 @@ -{"language":"en","flagWords":[],"version":"0.2","words":["Punct","KEYMAP","splitn","crossterm","YAZI","peekable","ratatui","syntect","pbpaste","pbcopy","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","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","Konsole","Überzug","pkgs","pdftoppm","poppler","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","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","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK","btime","nsec","codegen","gethostname","fchmod","fdfind","Rustc","rustc","ffprobe","vframes","luma","obase","outln","errln","tmtheme","twox","cfgs","fstype","objc","rdev","runloop","exfat","rclone","DECRQSS","DECSCUSR","libvterm","Uninit","lockin","rposition","resvg","foldhash","tilded","futs"]} \ No newline at end of file +{"words":["Punct","KEYMAP","splitn","crossterm","YAZI","peekable","ratatui","syntect","pbpaste","pbcopy","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","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","Konsole","Überzug","pkgs","pdftoppm","poppler","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","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","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK","btime","nsec","codegen","gethostname","fchmod","fdfind","Rustc","rustc","ffprobe","vframes","luma","obase","outln","errln","tmtheme","twox","cfgs","fstype","objc","rdev","runloop","exfat","rclone","DECRQSS","DECSCUSR","libvterm","Uninit","lockin","rposition","resvg","foldhash","tilded","futs","chdir"],"language":"en","flagWords":[],"version":"0.2"} \ No newline at end of file diff --git a/yazi-actor/src/mgr/update_files.rs b/yazi-actor/src/mgr/update_files.rs index a1abf60a..2914e515 100644 --- a/yazi-actor/src/mgr/update_files.rs +++ b/yazi-actor/src/mgr/update_files.rs @@ -16,7 +16,7 @@ impl Actor for UpdateFiles { fn act(cx: &mut Ctx, opt: Self::Options) -> Result { let revision = cx.current().files.revision; - let linked: Vec<_> = LINKED.read().from_dir(opt.op.cwd()).map(|u| opt.op.rebase(u)).collect(); + let linked: Vec<_> = LINKED.read().from_dir(opt.op.cwd()).map(|u| opt.op.chdir(u)).collect(); for op in [opt.op].into_iter().chain(linked) { cx.mgr.yanked.apply_op(&op); Self::update_tab(cx, op).ok(); diff --git a/yazi-build/Cargo.toml b/yazi-build/Cargo.toml new file mode 100644 index 00000000..bd7f7f7f --- /dev/null +++ b/yazi-build/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "yazi-build" +version = "0.1.8" +edition = "2024" +license = "MIT" +authors = [ "sxyazi " ] +description = "Yazi build system" +homepage = "https://yazi-rs.github.io" +repository = "https://github.com/sxyazi/yazi" + +[profile.release] +codegen-units = 1 +lto = true +panic = "abort" +strip = true + +[build-dependencies] +yazi-term = { path = "../yazi-term", version = "25.5.31" } + +[[bin]] +name = "yazi-build" +path = "src/main.rs" diff --git a/yazi-build/build.rs b/yazi-build/build.rs new file mode 100644 index 00000000..cda92066 --- /dev/null +++ b/yazi-build/build.rs @@ -0,0 +1,69 @@ +use std::{env, error::Error, io::{BufRead, BufReader, Read, Write}, process::{Command, Stdio}, thread}; + +use yazi_term::tty::TTY; + +fn main() -> Result<(), Box> { + yazi_term::init(); + + let manifest = env::var_os("CARGO_MANIFEST_DIR").unwrap().to_string_lossy().replace(r"\", "/"); + let crates = if manifest.contains("/git/checkouts/yazi-") { + &["--git", "https://github.com/sxyazi/yazi.git", "yazi-fm", "yazi-cli"] + } else if manifest.contains("/registry/src/index.crates.io-") { + &["yazi-fm", "yazi-cli"][..] + } else { + return Ok(()); + }; + + let target = env::var("TARGET").unwrap(); + let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); + unsafe { + env::set_var("VERGEN_GIT_SHA", "Crates.io"); + env::set_var("YAZI_CRATE_BUILD", "1"); + + env::set_var("JEMALLOC_SYS_WITH_LG_PAGE", "16"); + env::set_var("JEMALLOC_SYS_WITH_MALLOC_CONF", "narenas:1"); + + env::set_var( + "MACOSX_DEPLOYMENT_TARGET", + if target == "aarch64-apple-darwin" { "11.0" } else { "10.12" }, + ); + if target == "aarch64-apple-darwin" { + env::set_var("RUSTFLAGS", "-Ctarget-cpu=apple-m1"); + } + }; + + let profile = if target_os == "windows" { &["--profile", "release-windows"][..] } else { &[] }; + let mut child = Command::new(env::var_os("CARGO").unwrap()) + .args(&["install", "--force", "--locked"]) + .args(profile) + .args(crates) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn()?; + + let out = flash(child.stdout.take().unwrap()); + let err = flash(child.stderr.take().unwrap()); + + child.wait()?; + out.join().ok(); + err.join().ok(); + + Ok(()) +} + +fn flash(src: R) -> thread::JoinHandle<()> { + thread::spawn(move || { + let reader = BufReader::new(src); + for part in reader.split(b'\n') { + match part { + Ok(mut bytes) => { + bytes.push(b'\n'); + let mut out = TTY.lockout(); + out.write_all(&bytes).ok(); + out.flush().ok(); + } + Err(_) => break, + } + } + }) +} diff --git a/yazi-build/src/main.rs b/yazi-build/src/main.rs new file mode 100644 index 00000000..b278d210 --- /dev/null +++ b/yazi-build/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("See https://yazi-rs.github.io/docs/installation#crates on how to install Yazi."); +} diff --git a/yazi-cli/Cargo.toml b/yazi-cli/Cargo.toml index 3bb9f46d..91f08576 100644 --- a/yazi-cli/Cargo.toml +++ b/yazi-cli/Cargo.toml @@ -47,15 +47,9 @@ clap_complete_nushell = "4.5.8" serde_json = { workspace = true } vergen-gitcl = { version = "1.0.8", features = [ "build" ] } -[target.aarch64-apple-darwin] -rustflags = [ "-Ctarget-cpu=apple-m1" ] - [target.'cfg(target_os = "macos")'.dependencies] crossterm = { workspace = true, features = [ "use-dev-tty", "libc" ] } -[env] -MACOSX_DEPLOYMENT_TARGET = "10.11" - [[bin]] name = "ya" path = "src/main.rs" diff --git a/yazi-cli/build.rs b/yazi-cli/build.rs index 0ae2f659..8c65f534 100644 --- a/yazi-cli/build.rs +++ b/yazi-cli/build.rs @@ -8,6 +8,20 @@ use clap_complete::{Shell, generate_to}; use vergen_gitcl::{BuildBuilder, Emitter, GitclBuilder}; fn main() -> Result<(), Box> { + let manifest = env::var_os("CARGO_MANIFEST_DIR").unwrap().to_string_lossy().replace(r"\", "/"); + if env::var_os("YAZI_CRATE_BUILD").is_none() + && (manifest.contains("/git/checkouts/yazi-") + || manifest.contains("/registry/src/index.crates.io-")) + { + panic!( + "Due to Cargo's limitations, the `yazi-fm` and `yazi-cli` crates on crates.io must be built with `cargo install --force yazi-build`" + ); + } + + generate() +} + +fn generate() -> Result<(), Box> { Emitter::default() .add_instructions(&BuildBuilder::default().build_date(true).build()?)? .add_instructions(&GitclBuilder::default().commit_date(true).sha(true).build()?)? @@ -28,6 +42,5 @@ fn main() -> Result<(), Box> { generate_to(clap_complete_nushell::Nushell, cmd, bin, out)?; generate_to(clap_complete_fig::Fig, cmd, bin, out)?; - Ok(()) } diff --git a/yazi-codegen/Cargo.toml b/yazi-codegen/Cargo.toml index aca13243..3159f6e4 100644 --- a/yazi-codegen/Cargo.toml +++ b/yazi-codegen/Cargo.toml @@ -13,5 +13,5 @@ proc-macro = true [dependencies] # External dependencies -syn = { version = "2.0.104", features = [ "full" ] } +syn = { version = "2.0.105", features = [ "full" ] } quote = "1.0.40" diff --git a/yazi-core/src/mgr/linked.rs b/yazi-core/src/mgr/linked.rs index 88fb4e51..6cb2685b 100644 --- a/yazi-core/src/mgr/linked.rs +++ b/yazi-core/src/mgr/linked.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, ops::{Deref, DerefMut}}; +use std::{collections::HashMap, iter, ops::{Deref, DerefMut}}; use yazi_shared::url::Url; @@ -20,7 +20,9 @@ impl Linked { where 'a: 'b, { - if let Some(to) = self.get(url) { + if url.scheme.is_virtual() { + Box::new(iter::empty()) + } else if let Some(to) = self.get(url) { Box::new(self.iter().filter(move |(k, v)| *v == to && *k != url).map(|(k, _)| k)) } else { Box::new(self.iter().filter(move |(_, v)| *v == url).map(|(k, _)| k)) @@ -28,15 +30,12 @@ impl Linked { } pub fn from_file(&self, url: &Url) -> Vec { - if self.is_empty() { - return vec![]; + if url.scheme.is_virtual() { + vec![] + } else if let Some((parent, urn)) = url.pair() { + self.from_dir(&parent).map(|u| u.join(&urn)).collect() + } else { + vec![] } - - let Some(p) = url.parent_url() else { - return vec![]; - }; - - let name = url.file_name().unwrap(); - self.from_dir(&p).map(|u| u.join(name)).collect() } } diff --git a/yazi-core/src/mgr/watcher.rs b/yazi-core/src/mgr/watcher.rs index 90155356..d2da0af8 100644 --- a/yazi-core/src/mgr/watcher.rs +++ b/yazi-core/src/mgr/watcher.rs @@ -88,7 +88,7 @@ impl Watcher { let futs: Vec<_> = folders .iter() - .filter(|&f| f.url.scheme.is_builtin()) + .filter(|&f| f.url.is_internal()) .map(|&f| go(f.url.to_owned(), f.cha)) .collect(); diff --git a/yazi-core/src/tab/preview.rs b/yazi-core/src/tab/preview.rs index 0b60ebf8..6f67fabf 100644 --- a/yazi-core/src/tab/preview.rs +++ b/yazi-core/src/tab/preview.rs @@ -38,10 +38,10 @@ impl Preview { pub fn go_folder(&mut self, file: File, dir: Option, force: bool) { let same = self.same_file(&file, MIME_DIR); - let (wd, cha, builtin) = (file.url_owned(), file.cha, file.url.scheme.is_builtin()); + let (wd, cha, internal) = (file.url_owned(), file.cha, file.url.is_internal()); self.go(file, Cow::Borrowed(MIME_DIR), force); - if same || !builtin { + if same || !internal { return; } diff --git a/yazi-fm/Cargo.toml b/yazi-fm/Cargo.toml index e8d23203..f1badf77 100644 --- a/yazi-fm/Cargo.toml +++ b/yazi-fm/Cargo.toml @@ -4,7 +4,7 @@ version = "25.6.11" edition = "2024" license = "MIT" authors = [ "sxyazi " ] -description = "Yazi File Manager" +description = "Yazi file manager" homepage = "https://yazi-rs.github.io" repository = "https://github.com/sxyazi/yazi" @@ -58,9 +58,6 @@ tracing = { workspace = true } tracing-appender = "0.2.3" tracing-subscriber = { version = "0.3.19", features = [ "env-filter" ] } -[target.aarch64-apple-darwin] -rustflags = [ "-Ctarget-cpu=apple-m1" ] - [target."cfg(unix)".dependencies] libc = { workspace = true } signal-hook-tokio = { version = "0.3.1", features = [ "futures-v0_3" ] } @@ -71,11 +68,6 @@ crossterm = { workspace = true, features = [ "use-dev-tty", "libc" ] } [target.'cfg(all(not(target_os = "macos"), not(target_os = "windows")))'.dependencies] tikv-jemallocator = "0.6.0" -[env] -MACOSX_DEPLOYMENT_TARGET = "10.11" -JEMALLOC_SYS_WITH_LG_PAGE = "16" -JEMALLOC_SYS_WITH_MALLOC_CONF = "narenas:1" - [[bin]] name = "yazi" path = "src/main.rs" diff --git a/yazi-fm/build.rs b/yazi-fm/build.rs index 2bb340da..96e55461 100644 --- a/yazi-fm/build.rs +++ b/yazi-fm/build.rs @@ -15,5 +15,15 @@ fn main() -> Result<(), Box> { ); } + let manifest = env::var_os("CARGO_MANIFEST_DIR").unwrap().to_string_lossy().replace(r"\", "/"); + if env::var_os("YAZI_CRATE_BUILD").is_none() + && (manifest.contains("/git/checkouts/yazi-") + || manifest.contains("/registry/src/index.crates.io-")) + { + panic!( + "Due to Cargo's limitations, the `yazi-fm` and `yazi-cli` crates on crates.io must be built with `cargo install --force yazi-build`" + ); + } + Ok(()) } diff --git a/yazi-fs/src/file.rs b/yazi-fs/src/file.rs index d11decc7..2b5407d5 100644 --- a/yazi-fs/src/file.rs +++ b/yazi-fs/src/file.rs @@ -45,8 +45,8 @@ impl File { pub fn hash_u64(&self) -> u64 { foldhash::fast::FixedState::default().hash_one(self) } #[inline] - pub fn rebase(&self, parent: &Url) -> Self { - Self { url: self.url.rebase(parent), cha: self.cha, link_to: self.link_to.clone() } + pub fn chdir(&self, wd: &Url) -> Self { + Self { url: self.url.rebase(wd), cha: self.cha, link_to: self.link_to.clone() } } } diff --git a/yazi-fs/src/op.rs b/yazi-fs/src/op.rs index 6377ecdb..86d837ec 100644 --- a/yazi-fs/src/op.rs +++ b/yazi-fs/src/op.rs @@ -95,26 +95,26 @@ impl FilesOp { } } - pub fn rebase(&self, new: &Url) -> Self { + pub fn chdir(&self, wd: &Url) -> Self { macro_rules! files { - ($files:expr) => {{ $files.iter().map(|f| f.rebase(new)).collect() }}; + ($files:expr) => {{ $files.iter().map(|file| file.chdir(wd)).collect() }}; } macro_rules! map { - ($map:expr) => {{ $map.iter().map(|(u, f)| (u.clone(), f.rebase(new))).collect() }}; + ($map:expr) => {{ $map.iter().map(|(urn, file)| (urn.clone(), file.chdir(wd))).collect() }}; } - let n = new.clone(); + let w = wd.clone(); match self { - Self::Full(_, files, cha) => Self::Full(n, files!(files), *cha), - Self::Part(_, files, ticket) => Self::Part(n, files!(files), *ticket), - Self::Done(_, cha, ticket) => Self::Done(n, *cha, *ticket), - Self::Size(_, map) => Self::Size(n, map.iter().map(|(u, &s)| (u.clone(), s)).collect()), - Self::IOErr(_, err) => Self::IOErr(n, *err), + Self::Full(_, files, cha) => Self::Full(w, files!(files), *cha), + Self::Part(_, files, ticket) => Self::Part(w, files!(files), *ticket), + Self::Done(_, cha, ticket) => Self::Done(w, *cha, *ticket), + Self::Size(_, map) => Self::Size(w, map.iter().map(|(urn, &s)| (urn.clone(), s)).collect()), + Self::IOErr(_, err) => Self::IOErr(w, *err), - Self::Creating(_, files) => Self::Creating(n, files!(files)), - Self::Deleting(_, urns) => Self::Deleting(n, urns.clone()), - Self::Updating(_, map) => Self::Updating(n, map!(map)), - Self::Upserting(_, map) => Self::Upserting(n, map!(map)), + Self::Creating(_, files) => Self::Creating(w, files!(files)), + Self::Deleting(_, urns) => Self::Deleting(w, urns.clone()), + Self::Updating(_, map) => Self::Updating(w, map!(map)), + Self::Upserting(_, map) => Self::Upserting(w, map!(map)), } } diff --git a/yazi-shared/src/url/loc.rs b/yazi-shared/src/url/loc.rs index c67e2d84..ff761e68 100644 --- a/yazi-shared/src/url/loc.rs +++ b/yazi-shared/src/url/loc.rs @@ -200,6 +200,13 @@ impl Loc { }) } + #[inline] + pub fn rebase(&self, base: &Path) -> Self { + let mut loc: Self = base.join(self.uri()).into(); + (loc.uri, loc.urn) = (self.uri, self.urn); + loc + } + #[inline] pub fn has_base(&self) -> bool { self.bytes().len() != self.uri } @@ -215,15 +222,6 @@ impl Loc { #[inline] pub fn has_trail(&self) -> bool { self.bytes().len() != self.urn } - #[inline] - pub fn rebase(&self, parent: &Path) -> Self { - debug_assert!(self.uri == self.name().len()); - let path = parent.join(self.name()); - - debug_assert!(path.file_name().is_some_and(|s| s.len() == self.name().len())); - Self { inner: path, uri: self.uri, urn: self.uri } - } - #[inline] pub fn to_path(&self) -> PathBuf { self.inner.clone() } diff --git a/yazi-shared/src/url/scheme.rs b/yazi-shared/src/url/scheme.rs index 9b5bba8f..dfc4421f 100644 --- a/yazi-shared/src/url/scheme.rs +++ b/yazi-shared/src/url/scheme.rs @@ -89,14 +89,6 @@ impl Scheme { if self.is_virtual() || other.is_virtual() { self == other } else { true } } - #[inline] - pub fn is_builtin(&self) -> bool { - match self { - Self::Regular | Self::Search(_) | Self::Sftp(_) => true, - Self::Archive(_) => false, - } - } - #[inline] pub fn is_virtual(&self) -> bool { match self { diff --git a/yazi-shared/src/url/uri.rs b/yazi-shared/src/url/uri.rs index efe786c5..3b6d59a8 100644 --- a/yazi-shared/src/url/uri.rs +++ b/yazi-shared/src/url/uri.rs @@ -25,3 +25,7 @@ impl Deref for Uri { fn deref(&self) -> &Self::Target { &self.0 } } + +impl AsRef for Uri { + fn as_ref(&self) -> &Path { &self.0 } +} diff --git a/yazi-shared/src/url/url.rs b/yazi-shared/src/url/url.rs index da383700..6d163e1e 100644 --- a/yazi-shared/src/url/url.rs +++ b/yazi-shared/src/url/url.rs @@ -205,18 +205,17 @@ impl Url { #[inline] pub fn set_name(&mut self, name: impl AsRef) { self.loc.set_name(name); } + #[inline] + pub fn rebase(&self, base: &Path) -> Self { + Self { loc: self.loc.rebase(base), scheme: self.scheme.clone() } + } + #[inline] pub fn pair(&self) -> Option<(Self, UrnBuf)> { Some((self.parent_url()?, self.loc.urn_owned())) } #[inline] pub fn hash_u64(&self) -> u64 { foldhash::fast::FixedState::default().hash_one(self) } - #[inline] - pub fn rebase(&self, parent: &Path) -> Self { - debug_assert!(self.is_regular()); - self.loc.rebase(parent).into() - } - pub fn parse(bytes: &[u8]) -> Result<(Scheme, PathBuf, Option<(usize, usize)>)> { let mut skip = 0; let (scheme, tilde, uri, urn) = Scheme::parse(bytes, &mut skip)?; @@ -278,6 +277,16 @@ impl Url { #[inline] pub fn is_archive(&self) -> bool { matches!(self.scheme, Scheme::Archive(_)) } + // --- Internal + #[inline] + pub fn is_internal(&self) -> bool { + match self.scheme { + Scheme::Regular | Scheme::Sftp(_) => true, + Scheme::Search(_) => !self.loc.uri().is_empty(), + Scheme::Archive(_) => false, + } + } + // FIXME: remove #[inline] pub fn into_path2(self) -> PathBuf { self.loc.into_path() } diff --git a/yazi-widgets/src/clipboard.rs b/yazi-widgets/src/clipboard.rs index cdb5bbe9..3554d052 100644 --- a/yazi-widgets/src/clipboard.rs +++ b/yazi-widgets/src/clipboard.rs @@ -25,7 +25,7 @@ impl Clipboard { let all = [ ("pbpaste", &[][..]), ("termux-clipboard-get", &[]), - ("wl-paste", &[]), + ("wl-paste", &["-n"]), ("xclip", &["-o", "-selection", "clipboard"]), ("xsel", &["-ob"]), ];