This commit is contained in:
sxyazi 2025-07-28 17:16:20 +08:00
parent 5f63cefd1e
commit f49a03c424
No known key found for this signature in database
6 changed files with 132 additions and 50 deletions

33
Cargo.lock generated
View file

@ -1357,9 +1357,9 @@ checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
[[package]] [[package]]
name = "litrs" name = "litrs"
version = "0.4.1" version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
@ -2155,9 +2155,9 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.5.15" version = "0.5.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e8af0dde094006011e6a740d4879319439489813bd0bcdc7d821beaeeff48ec" checksum = "7251471db004e509f4e75a62cca9435365b5ec7bcdff530d612ac7c87c44a792"
dependencies = [ dependencies = [
"bitflags 2.9.1", "bitflags 2.9.1",
] ]
@ -2225,9 +2225,9 @@ checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce"
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.25" version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
[[package]] [[package]]
name = "rustc-hash" name = "rustc-hash"
@ -2470,12 +2470,12 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.5.10" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys 0.52.0", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@ -2684,9 +2684,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.46.1" version = "1.47.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17" checksum = "43864ed400b6043a4757a25c7a64a8efde741aed79a056a2fb348a406701bb35"
dependencies = [ dependencies = [
"backtrace", "backtrace",
"bytes", "bytes",
@ -2699,7 +2699,7 @@ dependencies = [
"slab", "slab",
"socket2", "socket2",
"tokio-macros", "tokio-macros",
"windows-sys 0.52.0", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@ -3295,15 +3295,6 @@ dependencies = [
"windows-link", "windows-link",
] ]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.6",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.59.0" version = "0.59.0"

View file

@ -45,7 +45,7 @@ scopeguard = "1.2.0"
serde = { version = "1.0.219", features = [ "derive" ] } serde = { version = "1.0.219", features = [ "derive" ] }
serde_json = "1.0.141" serde_json = "1.0.141"
syntect = { version = "5.2.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] } syntect = { version = "5.2.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] }
tokio = { version = "1.46.1", features = [ "full" ] } tokio = { version = "1.47.0", features = [ "full" ] }
tokio-stream = "0.1.17" tokio-stream = "0.1.17"
tokio-util = "0.7.15" tokio-util = "0.7.15"
toml = { version = "0.9.2" } toml = { version = "0.9.2" }

View file

@ -6,94 +6,170 @@ use crate::services::Local;
#[inline] #[inline]
pub async fn canonicalize(url: impl AsRef<Url>) -> io::Result<Url> { pub async fn canonicalize(url: impl AsRef<Url>) -> io::Result<Url> {
Local::canonicalize(url.as_ref()).await.map(Into::into) if let Some(path) = url.as_ref().as_path() {
Local::canonicalize(path).await.map(Into::into)
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub async fn create(url: impl AsRef<Url>) -> io::Result<tokio::fs::File> { pub async fn create(url: impl AsRef<Url>) -> io::Result<tokio::fs::File> {
Local::create(url.as_ref()).await if let Some(path) = url.as_ref().as_path() {
Local::create(path).await
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub async fn create_dir(url: impl AsRef<Url>) -> io::Result<()> { pub async fn create_dir(url: impl AsRef<Url>) -> io::Result<()> {
Local::create_dir(url.as_ref()).await if let Some(path) = url.as_ref().as_path() {
Local::create_dir(path).await
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub async fn create_dir_all(url: impl AsRef<Url>) -> io::Result<()> { pub async fn create_dir_all(url: impl AsRef<Url>) -> io::Result<()> {
Local::create_dir_all(url.as_ref()).await if let Some(path) = url.as_ref().as_path() {
Local::create_dir_all(path).await
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub async fn hard_link(original: impl AsRef<Url>, link: impl AsRef<Url>) -> io::Result<()> { pub async fn hard_link(original: impl AsRef<Url>, link: impl AsRef<Url>) -> io::Result<()> {
Local::hard_link(original.as_ref(), link.as_ref()).await if let (Some(original), Some(link)) = (original.as_ref().as_path(), link.as_ref().as_path()) {
Local::hard_link(original, link).await
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub async fn metadata(url: impl AsRef<Url>) -> io::Result<std::fs::Metadata> { pub async fn metadata(url: impl AsRef<Url>) -> io::Result<std::fs::Metadata> {
Local::metadata(url.as_ref()).await if let Some(path) = url.as_ref().as_path() {
Local::metadata(path).await
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub async fn open(url: impl AsRef<Url>) -> io::Result<tokio::fs::File> { pub async fn open(url: impl AsRef<Url>) -> io::Result<tokio::fs::File> {
Local::open(url.as_ref()).await if let Some(path) = url.as_ref().as_path() {
Local::open(path).await
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub async fn read_dir(url: impl AsRef<Url>) -> io::Result<tokio::fs::ReadDir> { pub async fn read_dir(url: impl AsRef<Url>) -> io::Result<tokio::fs::ReadDir> {
Local::read_dir(url.as_ref()).await if let Some(path) = url.as_ref().as_path() {
Local::read_dir(path).await
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub fn read_dir_sync(url: impl AsRef<Url>) -> io::Result<std::fs::ReadDir> { pub fn read_dir_sync(url: impl AsRef<Url>) -> io::Result<std::fs::ReadDir> {
Local::read_dir_sync(url.as_ref()) if let Some(path) = url.as_ref().as_path() {
Local::read_dir_sync(path)
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub async fn read_link(url: impl AsRef<Url>) -> io::Result<Url> { pub async fn read_link(url: impl AsRef<Url>) -> io::Result<Url> {
Local::read_link(url.as_ref()).await.map(Into::into) if let Some(path) = url.as_ref().as_path() {
Local::read_link(path).await.map(Into::into)
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub async fn remove_dir(url: impl AsRef<Url>) -> io::Result<()> { pub async fn remove_dir(url: impl AsRef<Url>) -> io::Result<()> {
Local::remove_dir(url.as_ref()).await if let Some(path) = url.as_ref().as_path() {
Local::remove_dir(path).await
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub async fn remove_dir_all(url: impl AsRef<Url>) -> io::Result<()> { pub async fn remove_dir_all(url: impl AsRef<Url>) -> io::Result<()> {
Local::remove_dir_all(url.as_ref()).await if let Some(path) = url.as_ref().as_path() {
Local::remove_dir_all(path).await
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub async fn remove_file(url: impl AsRef<Url>) -> io::Result<()> { pub async fn remove_file(url: impl AsRef<Url>) -> io::Result<()> {
Local::remove_file(url.as_ref()).await if let Some(path) = url.as_ref().as_path() {
Local::remove_file(path).await
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub async fn rename(from: impl AsRef<Url>, to: impl AsRef<Url>) -> io::Result<()> { pub async fn rename(from: impl AsRef<Url>, to: impl AsRef<Url>) -> io::Result<()> {
Local::rename(from.as_ref(), to.as_ref()).await if let (Some(from), Some(to)) = (from.as_ref().as_path(), to.as_ref().as_path()) {
Local::rename(from, to).await
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub async fn symlink_dir(original: impl AsRef<Url>, link: impl AsRef<Url>) -> io::Result<()> { pub async fn symlink_dir(original: impl AsRef<Url>, link: impl AsRef<Url>) -> io::Result<()> {
Local::symlink_dir(original.as_ref(), link.as_ref()).await if let (Some(original), Some(link)) = (original.as_ref().as_path(), link.as_ref().as_path()) {
Local::symlink_dir(original, link).await
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub async fn symlink_file(original: impl AsRef<Url>, link: impl AsRef<Url>) -> io::Result<()> { pub async fn symlink_file(original: impl AsRef<Url>, link: impl AsRef<Url>) -> io::Result<()> {
Local::symlink_file(original.as_ref(), link.as_ref()).await if let (Some(original), Some(link)) = (original.as_ref().as_path(), link.as_ref().as_path()) {
Local::symlink_file(original, link).await
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub async fn symlink_metadata(url: impl AsRef<Url>) -> io::Result<std::fs::Metadata> { pub async fn symlink_metadata(url: impl AsRef<Url>) -> io::Result<std::fs::Metadata> {
Local::symlink_metadata(url.as_ref()).await if let Some(path) = url.as_ref().as_path() {
Local::symlink_metadata(path).await
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
pub fn symlink_metadata_sync(url: impl AsRef<Url>) -> io::Result<std::fs::Metadata> { pub fn symlink_metadata_sync(url: impl AsRef<Url>) -> io::Result<std::fs::Metadata> {
Local::symlink_metadata_sync(url.as_ref()) if let Some(path) = url.as_ref().as_path() {
Local::symlink_metadata_sync(path)
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }
#[inline] #[inline]
pub async fn write(url: impl AsRef<Url>, contents: impl AsRef<[u8]>) -> io::Result<()> { pub async fn write(url: impl AsRef<Url>, contents: impl AsRef<[u8]>) -> io::Result<()> {
Local::write(url.as_ref(), contents).await if let Some(path) = url.as_ref().as_path() {
Local::write(path, contents).await
} else {
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
}
} }

View file

@ -1,5 +1,7 @@
use std::borrow::Cow;
use mlua::{ExternalError, IntoLua, Lua, Value}; use mlua::{ExternalError, IntoLua, Lua, Value};
use yazi_fs::expand_path; use yazi_fs::expand_url;
use yazi_shared::{event::CmdCow, url::Url}; use yazi_shared::{event::CmdCow, url::Url};
#[derive(Debug)] #[derive(Debug)]
@ -12,9 +14,13 @@ pub struct CdOpt {
impl From<CmdCow> for CdOpt { impl From<CmdCow> for CdOpt {
fn from(mut c: CmdCow) -> Self { fn from(mut c: CmdCow) -> Self {
let mut target = c.take_first_url().unwrap_or_default(); let mut target = c.take_first_url().unwrap_or_default();
if target.is_regular() && !c.bool("raw") {
target = Url::from(expand_path(target)); if !c.bool("raw")
&& let Cow::Owned(u) = expand_url(&target)
{
target = u;
} }
Self { target, interactive: c.bool("interactive"), source: CdSource::Cd } Self { target, interactive: c.bool("interactive"), source: CdSource::Cd }
} }
} }

View file

@ -1,5 +1,7 @@
use std::borrow::Cow;
use mlua::{ExternalError, IntoLua, Lua, Value}; use mlua::{ExternalError, IntoLua, Lua, Value};
use yazi_fs::expand_path; use yazi_fs::expand_url;
use yazi_shared::{event::CmdCow, url::Url}; use yazi_shared::{event::CmdCow, url::Url};
use crate::mgr::CdSource; use crate::mgr::CdSource;
@ -14,8 +16,11 @@ pub struct RevealOpt {
impl From<CmdCow> for RevealOpt { impl From<CmdCow> for RevealOpt {
fn from(mut c: CmdCow) -> Self { fn from(mut c: CmdCow) -> Self {
let mut target = c.take_first_url().unwrap_or_default(); let mut target = c.take_first_url().unwrap_or_default();
if target.is_regular() && !c.bool("raw") {
target = Url::from(expand_path(target)); if !c.bool("raw")
&& let Cow::Owned(u) = expand_url(&target)
{
target = u;
} }
Self { target, source: CdSource::Reveal, no_dummy: c.bool("no-dummy") } Self { target, source: CdSource::Reveal, no_dummy: c.bool("no-dummy") }

View file

@ -1,6 +1,8 @@
use std::borrow::Cow;
use mlua::{ExternalError, IntoLua, Lua, Value}; use mlua::{ExternalError, IntoLua, Lua, Value};
use yazi_boot::BOOT; use yazi_boot::BOOT;
use yazi_fs::expand_path; use yazi_fs::expand_url;
use yazi_shared::{event::CmdCow, url::Url}; use yazi_shared::{event::CmdCow, url::Url};
#[derive(Debug)] #[derive(Debug)]
@ -16,8 +18,10 @@ impl From<CmdCow> for TabCreateOpt {
let Some(mut wd) = c.take_first_url() else { let Some(mut wd) = c.take_first_url() else {
return Self { wd: Some(Url::from(&BOOT.cwds[0])) }; return Self { wd: Some(Url::from(&BOOT.cwds[0])) };
}; };
if wd.is_regular() && !c.bool("raw") { if !c.bool("raw")
wd = Url::from(expand_path(wd)); && let Cow::Owned(u) = expand_url(&wd)
{
wd = u;
} }
Self { wd: Some(wd) } Self { wd: Some(wd) }
} }