diff --git a/.github/workflows/draft.yml b/.github/workflows/draft.yml index 4987245c..9272ef9d 100644 --- a/.github/workflows/draft.yml +++ b/.github/workflows/draft.yml @@ -59,7 +59,7 @@ jobs: run: ./scripts/build.sh ${{ matrix.target }} - name: Upload artifact - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: ${{ matrix.target }} path: | @@ -105,7 +105,7 @@ jobs: Compress-Archive -Path ${env:TARGET_NAME} -DestinationPath "${env:TARGET_NAME}.zip" - name: Upload artifact - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: ${{ matrix.target }} path: yazi-${{ matrix.target }}.zip @@ -133,7 +133,7 @@ jobs: run: ./scripts/build.sh ${{ matrix.target }} - name: Upload artifact - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: ${{ matrix.target }} path: | @@ -155,7 +155,7 @@ jobs: fetch-depth: 0 - name: Setup LXD - uses: canonical/setup-lxd@v0.1.3 + uses: canonical/setup-lxd@v1 - name: Setup snapcraft run: sudo snap install --classic snapcraft @@ -167,7 +167,7 @@ jobs: run: mv yazi_*.snap yazi-${{ matrix.arch }}.snap - name: Upload artifact - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: snap-${{ matrix.arch }} path: yazi-${{ matrix.arch }}.snap @@ -176,7 +176,7 @@ jobs: runs-on: ubuntu-latest needs: [build-snap] steps: - - uses: actions/download-artifact@v6 + - uses: actions/download-artifact@v7 with: pattern: snap-* merge-multiple: true @@ -205,7 +205,7 @@ jobs: runs-on: ubuntu-latest needs: [build-unix, build-windows, build-musl, build-snap] steps: - - uses: actions/download-artifact@v6 + - uses: actions/download-artifact@v7 with: merge-multiple: true @@ -234,7 +234,7 @@ jobs: - uses: actions/checkout@v6 - - uses: actions/download-artifact@v6 + - uses: actions/download-artifact@v7 with: merge-multiple: true diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml index 9d0819fe..a5a69e25 100644 --- a/.github/workflows/lock.yml +++ b/.github/workflows/lock.yml @@ -16,7 +16,7 @@ jobs: pull-requests: write discussions: write steps: - - uses: dessant/lock-threads@v5 + - uses: dessant/lock-threads@v6 with: issue-inactive-days: "30" issue-comment: > diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 61fe3938..a18e6849 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -11,7 +11,7 @@ jobs: winget: runs-on: ubuntu-latest steps: - - uses: actions/download-artifact@v6 + - uses: actions/download-artifact@v7 with: merge-multiple: true diff --git a/Cargo.lock b/Cargo.lock index d29fac16..6e341b84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "aligned" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "377e4c0ba83e4431b10df45c1d4666f178ea9c552cac93e60c3a88bf32785923" +checksum = "ee4508988c62edf04abd8d92897fca0c2995d907ce1dfeaf369dac3716a40685" dependencies = [ "as-slice", ] @@ -431,9 +431,9 @@ checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64" [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "by_address" @@ -2002,9 +2002,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +checksum = "df15f6eac291ed1cf25865b1ee60399f57e7c227e7f51bdbd4c5270396a9ed50" dependencies = [ "bitflags 2.10.0", "libc", @@ -2081,9 +2081,9 @@ dependencies = [ [[package]] name = "luajit-src" -version = "210.6.4+e17ee83" +version = "210.6.5+7152e15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35a0ceb2a395ffa403a863adcf365e82cc8d8338ac7f5f949b9df5ca3de251e1" +checksum = "29e64ac463f01a02ee793423f9b351369cf244c5ee8bb9e2729a75b2eb404181" dependencies = [ "cc", "which", @@ -2199,9 +2199,9 @@ dependencies = [ [[package]] name = "moxcms" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80986bbbcf925ebd3be54c26613d861255284584501595cf418320c078945608" +checksum = "ac9557c559cd6fc9867e122e20d2cbefc9ca29d80d027a8e39310920ed2f0a97" dependencies = [ "num-traits", "pxfm", @@ -4105,9 +4105,9 @@ dependencies = [ [[package]] name = "uzers" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df81ff504e7d82ad53e95ed1ad5b72103c11253f39238bcc0235b90768a97dd" +checksum = "0b8275fb1afee25b4111d2dc8b5c505dbbc4afd0b990cb96deb2d88bff8be18d" dependencies = [ "libc", "log", @@ -5008,6 +5008,7 @@ dependencies = [ "yazi-fs", "yazi-macro", "yazi-shared", + "yazi-vfs", ] [[package]] @@ -5272,9 +5273,9 @@ dependencies = [ [[package]] name = "zune-jpeg" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6fb7703e32e9a07fb3f757360338b3a567a5054f21b5f52a666752e333d58e" +checksum = "51d915729b0e7d5fe35c2f294c5dc10b30207cc637920e5b59077bfa3da63f28" dependencies = [ "zune-core", ] diff --git a/Cargo.toml b/Cargo.toml index 02b57583..7b9f7f0a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,7 +64,7 @@ tracing = { version = "0.1.43", features = [ "max_level_debug", "rel twox-hash = { version = "2.1.2", default-features = false, features = [ "std", "random", "xxhash3_128" ] } typed-path = "0.12.0" unicode-width = { version = "0.2.0", default-features = false } -uzers = "0.12.1" +uzers = "0.12.2" [workspace.lints.clippy] format_push_string = "warn" diff --git a/scripts/validate-form/package-lock.json b/scripts/validate-form/package-lock.json index 4b3846c7..77bf7f59 100644 --- a/scripts/validate-form/package-lock.json +++ b/scripts/validate-form/package-lock.json @@ -8,27 +8,37 @@ "name": "validate-form", "version": "1.0.0", "dependencies": { - "@actions/core": "^1.10.1", + "@actions/core": "^2.0.1", "@actions/github": "^6.0.0" } }, "node_modules/@actions/core": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz", - "integrity": "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-2.0.1.tgz", + "integrity": "sha512-oBfqT3GwkvLlo1fjvhQLQxuwZCGTarTE5OuZ2Wg10hvhBj7LRIlF611WT4aZS6fDhO5ZKlY7lCAZTlpmyaHaeg==", "license": "MIT", "dependencies": { - "@actions/exec": "^1.1.1", - "@actions/http-client": "^2.0.1" + "@actions/exec": "^2.0.0", + "@actions/http-client": "^3.0.0" + } + }, + "node_modules/@actions/core/node_modules/@actions/http-client": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-3.0.0.tgz", + "integrity": "sha512-1s3tXAfVMSz9a4ZEBkXXRQD4QhY3+GAsWSbaYpeknPOKEeyRiU3lH+bHiLMZdo2x/fIeQ/hscL1wCkDLVM2DZQ==", + "license": "MIT", + "dependencies": { + "tunnel": "^0.0.6", + "undici": "^5.28.5" } }, "node_modules/@actions/exec": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz", - "integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-2.0.0.tgz", + "integrity": "sha512-k8ngrX2voJ/RIN6r9xB82NVqKpnMRtxDoiO+g3olkIUpQNqjArXrCQceduQZCQj3P3xm32pChRLqRrtXTlqhIw==", "license": "MIT", "dependencies": { - "@actions/io": "^1.0.1" + "@actions/io": "^2.0.0" } }, "node_modules/@actions/github": { @@ -57,9 +67,9 @@ } }, "node_modules/@actions/io": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz", - "integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@actions/io/-/io-2.0.0.tgz", + "integrity": "sha512-Jv33IN09XLO+0HS79aaODsvIRyduiF7NY/F6LYeK5oeUmrsz7aFdRphQjFoESF4jS7lMauDOttKALcpapVDIAg==", "license": "MIT" }, "node_modules/@fastify/busboy": { @@ -85,6 +95,7 @@ "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.1.tgz", "integrity": "sha512-dKYCMuPO1bmrpuogcjQ8z7ICCH3FP6WmxpwC03yjzGfZhj9fTJg6+bS1+UAplekbN2C+M61UNllGOOoAfGCrdQ==", "license": "MIT", + "peer": true, "dependencies": { "@octokit/auth-token": "^4.0.0", "@octokit/graphql": "^7.1.0", diff --git a/scripts/validate-form/package.json b/scripts/validate-form/package.json index 18ee8bec..aee804a4 100644 --- a/scripts/validate-form/package.json +++ b/scripts/validate-form/package.json @@ -6,7 +6,7 @@ }, "private": true, "dependencies": { - "@actions/core": "^1.10.1", + "@actions/core": "^2.0.1", "@actions/github": "^6.0.0" } } diff --git a/yazi-actor/src/cmp/trigger.rs b/yazi-actor/src/cmp/trigger.rs index 91e18739..e9c20672 100644 --- a/yazi-actor/src/cmp/trigger.rs +++ b/yazi-actor/src/cmp/trigger.rs @@ -1,11 +1,11 @@ use std::mem; use anyhow::Result; -use yazi_fs::{CWD, path::clean_url, provider::{DirReader, FileHolder}}; +use yazi_fs::{path::clean_url, provider::{DirReader, FileHolder}}; use yazi_macro::{act, render, succ}; use yazi_parser::cmp::{CmpItem, ShowOpt, TriggerOpt}; use yazi_proxy::CmpProxy; -use yazi_shared::{AnyAsciiChar, data::Data, natsort, path::{AsPath, PathBufDyn, PathCow, PathDyn, PathLike}, scheme::{SchemeCow, SchemeLike}, strand::{AsStrand, StrandLike}, url::{UrlBuf, UrlCow, UrlLike}}; +use yazi_shared::{AnyAsciiChar, data::Data, natsort, path::{AsPath, PathBufDyn, PathLike}, scheme::{SchemeCow, SchemeLike}, strand::{AsStrand, StrandLike}, url::{UrlBuf, UrlCow, UrlLike}}; use yazi_vfs::provider; use crate::{Actor, Ctx}; @@ -67,37 +67,35 @@ impl Actor for Trigger { impl Trigger { fn split_url(s: &str) -> Option<(UrlBuf, PathBufDyn)> { - let (scheme, path) = SchemeCow::parse(s.as_bytes()).ok()?; - let scheme = scheme.zeroed(); - - if scheme.is_local() && path.as_strand() == "~" { - return None; // We don't autocomplete a `~`, but `~/` - } - - let cwd = CWD.load(); - let abs = if !path.is_absolute() && cwd.scheme().covariant(&scheme) { - cwd.loc().try_join(&path).ok()?.into() - } else { - PathCow::from(&path) - }; - let sep = if cfg!(windows) { AnyAsciiChar::new(b"/\\").unwrap() } else { AnyAsciiChar::new(b"/").unwrap() }; - let child = path.rsplit_pred(sep).map_or(path.as_path(), |(_, c)| c); - let parent = - PathDyn::with(scheme.kind(), abs.encoded_bytes().strip_suffix(child.encoded_bytes())?) - .ok()?; + let (scheme, path) = SchemeCow::parse(s.as_bytes()).ok()?; + let scheme = scheme.zeroed(); - Some((clean_url(UrlCow::try_from((scheme, parent)).ok()?), child.into())) + // We don't complete a `~`, but `~/` + if scheme.is_local() && path.as_strand() == "~" { + return None; + } + + // Child + let child = path.rsplit_pred(sep).map_or(path.as_path(), |(_, c)| c).to_owned(); + + // Parent + let url = UrlCow::try_from((scheme.clone().zeroed(), path)).ok()?; + let abs = if let Some(u) = provider::try_absolute(&url) { u } else { url }; + let parent = abs.loc().try_strip_suffix(&child).ok()?; + + Some((clean_url(UrlCow::try_from((scheme, parent)).ok()?), child)) } } #[cfg(test)] mod tests { + use yazi_fs::CWD; use yazi_shared::url::UrlLike; use super::*; diff --git a/yazi-actor/src/lives/file.rs b/yazi-actor/src/lives/file.rs index df4f2e46..12b57fe6 100644 --- a/yazi-actor/src/lives/file.rs +++ b/yazi-actor/src/lives/file.rs @@ -1,4 +1,4 @@ -use std::ops::Deref; +use std::{ops::Deref, ptr}; use mlua::{AnyUserData, IntoLua, UserData, UserDataFields, UserDataMethods, Value}; use yazi_binding::{Style, cached_field}; @@ -73,9 +73,7 @@ impl UserData for File { fields.add_field_method_get("idx", |_, me| Ok(me.idx + 1)); fields.add_field_method_get("is_hovered", |_, me| Ok(me.idx == me.folder.cursor)); - fields.add_field_method_get("in_current", |_, me| { - Ok(&*me.folder as *const _ == &me.tab.current as *const _) - }); + fields.add_field_method_get("in_current", |_, me| Ok(ptr::eq(&*me.folder, &me.tab.current))); fields.add_field_method_get("in_preview", |_, me| { Ok(me.idx == me.folder.cursor && me.tab.hovered().is_some_and(|f| f.url == me.folder.url)) }); diff --git a/yazi-actor/src/mgr/tab_create.rs b/yazi-actor/src/mgr/tab_create.rs index bc9263e3..835baf46 100644 --- a/yazi-actor/src/mgr/tab_create.rs +++ b/yazi-actor/src/mgr/tab_create.rs @@ -25,7 +25,7 @@ impl Actor for TabCreate { } let mut tab = Tab::default(); - let (cd, url) = if let Some(wd) = opt.wd { + let (cd, url) = if let Some(wd) = opt.url { (true, wd.into_owned()) } else if let Some(h) = cx.hovered() { tab.pref = cx.tab().pref.clone(); diff --git a/yazi-boot/src/boot.rs b/yazi-boot/src/boot.rs index 2be24d9e..a9b48bb7 100644 --- a/yazi-boot/src/boot.rs +++ b/yazi-boot/src/boot.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; use futures::executor::block_on; use hashbrown::HashSet; -use yazi_fs::{CWD, Xdg, path::expand_url}; +use yazi_fs::{CWD, Xdg, path::clean_url}; use yazi_shared::{strand::StrandBuf, url::{UrlBuf, UrlLike}}; use yazi_vfs::provider; @@ -27,7 +27,7 @@ impl Boot { } async fn go(entry: &UrlBuf) -> (UrlBuf, StrandBuf) { - let mut entry = expand_url(entry); + let mut entry = clean_url(entry); if let Ok(u) = provider::absolute(&entry).await && u.is_owned() diff --git a/yazi-config/src/lib.rs b/yazi-config/src/lib.rs index f08dd301..7668fd29 100644 --- a/yazi-config/src/lib.rs +++ b/yazi-config/src/lib.rs @@ -1,6 +1,6 @@ yazi_macro::mod_pub!(keymap mgr open opener plugin popup preview tasks theme which vfs); -yazi_macro::mod_flat!(icon layout pattern platform preset priority style yazi); +yazi_macro::mod_flat!(icon layout pattern platform preset priority style utils yazi); use std::io::{Read, Write}; diff --git a/yazi-config/src/preview/preview.rs b/yazi-config/src/preview/preview.rs index 85a1e6c4..02e6da83 100644 --- a/yazi-config/src/preview/preview.rs +++ b/yazi-config/src/preview/preview.rs @@ -3,10 +3,11 @@ use std::{borrow::Cow, path::PathBuf}; use anyhow::{Context, Result, bail}; use serde::{Deserialize, Serialize}; use yazi_codegen::DeserializeOver2; -use yazi_fs::{Xdg, path::expand_url}; +use yazi_fs::Xdg; use yazi_shared::{SStr, timestamp_us}; use super::PreviewWrap; +use crate::normalize_path; #[rustfmt::skip] const TABS: &[&str] = &["", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "]; @@ -50,10 +51,10 @@ impl Preview { self.cache_dir = if self.cache_dir.as_os_str().is_empty() { Xdg::cache_dir().to_owned() - } else if let Some(p) = expand_url(self.cache_dir).into_local() { + } else if let Some(p) = normalize_path(self.cache_dir) { p } else { - bail!("[preview].cache_dir must be a path within local filesystem."); + bail!("[preview].cache_dir must be either empty or an absolute path."); }; std::fs::create_dir_all(&self.cache_dir) diff --git a/yazi-config/src/style.rs b/yazi-config/src/style.rs index d9d326fd..5c2dd34a 100644 --- a/yazi-config/src/style.rs +++ b/yazi-config/src/style.rs @@ -25,8 +25,8 @@ impl From for Style { let all = value.add_modifier - sub; Self { - fg: value.fg.map(Into::into), - bg: value.bg.map(Into::into), + fg: value.fg, + bg: value.bg, bold: if all.contains(M::BOLD) { Some(true) } else if sub.contains(M::BOLD) { Some(false) } else { None }, dim: if all.contains(M::DIM) { Some(true) } else if sub.contains(M::DIM) { Some(false) } else { None }, italic: if all.contains(M::ITALIC) { Some(true) } else if sub.contains(M::ITALIC) { Some(false) } else { None }, @@ -75,8 +75,8 @@ impl From