mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: size calculator for remote file systems (#3170)
This commit is contained in:
parent
a3fc9a0ec7
commit
7deeaa4356
53 changed files with 721 additions and 567 deletions
84
Cargo.lock
generated
84
Cargo.lock
generated
|
|
@ -1117,11 +1117,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
|||
|
||||
[[package]]
|
||||
name = "erased-serde"
|
||||
version = "0.4.6"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7"
|
||||
checksum = "259d404d09818dec19332e31d94558aeb442fea04c817006456c24b5460bbd4b"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_core",
|
||||
"typeid",
|
||||
]
|
||||
|
||||
|
|
@ -1817,9 +1818,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
|
|||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.9"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3"
|
||||
checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"libc",
|
||||
|
|
@ -3158,16 +3159,17 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.26"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
|
||||
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
version = "1.0.223"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||
checksum = "a505d71960adde88e293da5cb5eda57093379f64e61cf77bf0e6a63af07a7bac"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
|
|
@ -3182,10 +3184,19 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.219"
|
||||
name = "serde_core"
|
||||
version = "1.0.223"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
checksum = "20f57cbd357666aa7b3ac84a90b4ea328f1d4ddb6772b430caa5d9e1309bb9e9"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.223"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d428d07faf17e306e699ec1e91996e5a165ba5d6bce5b5155173e91a8a01a56"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -3194,14 +3205,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.143"
|
||||
version = "1.0.145"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
|
||||
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4532,7 +4544,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-actor"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"crossterm 0.29.0",
|
||||
|
|
@ -4564,7 +4576,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-adapter"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"ansi-to-tui",
|
||||
"anyhow",
|
||||
|
|
@ -4586,7 +4598,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-binding"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"ansi-to-tui",
|
||||
"hashbrown 0.16.0",
|
||||
|
|
@ -4606,7 +4618,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-boot"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"clap_complete",
|
||||
|
|
@ -4626,14 +4638,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-build"
|
||||
version = "0.1.8"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"yazi-term",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yazi-cli"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
|
|
@ -4656,7 +4668,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-codegen"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
|
|
@ -4664,7 +4676,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-config"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.9.4",
|
||||
|
|
@ -4687,7 +4699,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-core"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"crossterm 0.29.0",
|
||||
|
|
@ -4716,7 +4728,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-dds"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"hashbrown 0.16.0",
|
||||
|
|
@ -4742,7 +4754,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-ffi"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"core-foundation-sys",
|
||||
|
|
@ -4753,7 +4765,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-fm"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"better-panic",
|
||||
|
|
@ -4792,7 +4804,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-fs"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arc-swap",
|
||||
|
|
@ -4820,15 +4832,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-macro"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
|
||||
[[package]]
|
||||
name = "yazi-packing"
|
||||
version = "25.5.28"
|
||||
version = "25.9.15"
|
||||
|
||||
[[package]]
|
||||
name = "yazi-parser"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.9.4",
|
||||
|
|
@ -4848,7 +4860,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-plugin"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"crossterm 0.29.0",
|
||||
|
|
@ -4891,7 +4903,7 @@ checksum = "33232d9116df6415ddfcdf72701b1b7439ce87f240a14723e8dd5d17e7ed5f98"
|
|||
|
||||
[[package]]
|
||||
name = "yazi-proxy"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"tokio",
|
||||
|
|
@ -4903,7 +4915,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-scheduler"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-priority-channel",
|
||||
|
|
@ -4943,7 +4955,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-shared"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"crossterm 0.29.0",
|
||||
|
|
@ -4964,7 +4976,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-term"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"crossterm 0.29.0",
|
||||
"libc",
|
||||
|
|
@ -4977,7 +4989,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-watcher"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"hashbrown 0.16.0",
|
||||
|
|
@ -4995,7 +5007,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-widgets"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ ratatui = { version = "0.29.0", features = [ "unstable-rendered-line
|
|||
regex = "1.11.2"
|
||||
russh = { version = "0.54.3", default-features = false, features = [ "ring", "rsa" ] }
|
||||
scopeguard = "1.2.0"
|
||||
serde = { version = "1.0.219", features = [ "derive" ] }
|
||||
serde_json = "1.0.143"
|
||||
serde = { version = "1.0.223", features = [ "derive" ] }
|
||||
serde_json = "1.0.145"
|
||||
syntect = { version = "5.2.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] }
|
||||
tokio = { version = "1.47.1", features = [ "full" ] }
|
||||
tokio-stream = "0.1.17"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-actor"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -13,21 +13,21 @@ default = [ "vendored-lua" ]
|
|||
vendored-lua = [ "mlua/vendored" ]
|
||||
|
||||
[dependencies]
|
||||
yazi-binding = { path = "../yazi-binding", version = "25.6.11" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.6.11" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.6.11" }
|
||||
yazi-core = { path = "../yazi-core", version = "25.6.11" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.6.11" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.6.11" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "25.6.11" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.6.11" }
|
||||
yazi-scheduler = { path = "../yazi-scheduler", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-term = { path = "../yazi-term", version = "25.6.11" }
|
||||
yazi-watcher = { path = "../yazi-watcher", version = "25.6.11" }
|
||||
yazi-widgets = { path = "../yazi-widgets", version = "25.6.11" }
|
||||
yazi-binding = { path = "../yazi-binding", version = "25.9.15" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.9.15" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.9.15" }
|
||||
yazi-core = { path = "../yazi-core", version = "25.9.15" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.9.15" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.9.15" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.9.15" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "25.9.15" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.9.15" }
|
||||
yazi-scheduler = { path = "../yazi-scheduler", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
yazi-term = { path = "../yazi-term", version = "25.9.15" }
|
||||
yazi-watcher = { path = "../yazi-watcher", version = "25.9.15" }
|
||||
yazi-widgets = { path = "../yazi-widgets", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-adapter"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,11 +9,11 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-config = { path = "../yazi-config", version = "25.6.11" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-term = { path = "../yazi-term", version = "25.6.11" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.9.15" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.9.15" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
yazi-term = { path = "../yazi-term", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
ansi-to-tui = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-binding"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -13,11 +13,11 @@ default = [ "vendored-lua" ]
|
|||
vendored-lua = [ "mlua/vendored" ]
|
||||
|
||||
[dependencies]
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.6.11" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.6.11" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.9.15" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.9.15" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.9.15" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
ansi-to-tui = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::{ops::Deref, time::{Duration, SystemTime, UNIX_EPOCH}};
|
||||
|
||||
use mlua::{ExternalError, FromLua, IntoLua, Lua, Table, UserData, UserDataFields, UserDataMethods};
|
||||
use yazi_fs::cha::ChaKind;
|
||||
use yazi_fs::cha::{ChaKind, ChaMode};
|
||||
|
||||
#[derive(Clone, Copy, FromLua)]
|
||||
pub struct Cha(pub yazi_fs::cha::Cha);
|
||||
|
|
@ -25,11 +25,15 @@ impl Cha {
|
|||
lua.globals().raw_set(
|
||||
"Cha",
|
||||
lua.create_function(|lua, t: Table| {
|
||||
let kind =
|
||||
ChaKind::from_bits(t.raw_get("kind")?).ok_or_else(|| "Invalid kind".into_lua_err())?;
|
||||
let kind = ChaKind::from_bits(t.raw_get("kind").unwrap_or_default())
|
||||
.ok_or_else(|| "Invalid kind".into_lua_err())?;
|
||||
|
||||
let mode =
|
||||
ChaMode::from_bits(t.raw_get("mode")?).ok_or_else(|| "Invalid mode".into_lua_err())?;
|
||||
|
||||
Self(yazi_fs::cha::Cha {
|
||||
kind,
|
||||
mode,
|
||||
len: t.raw_get("len").unwrap_or_default(),
|
||||
atime: parse_time(t.raw_get("atime").ok())?,
|
||||
btime: parse_time(t.raw_get("btime").ok())?,
|
||||
|
|
@ -37,8 +41,6 @@ impl Cha {
|
|||
ctime: parse_time(t.raw_get("ctime").ok())?,
|
||||
mtime: parse_time(t.raw_get("mtime").ok())?,
|
||||
#[cfg(unix)]
|
||||
mode: t.raw_get("mode").unwrap_or_default(),
|
||||
#[cfg(unix)]
|
||||
dev: t.raw_get("dev").unwrap_or_default(),
|
||||
#[cfg(unix)]
|
||||
uid: t.raw_get("uid").unwrap_or_default(),
|
||||
|
|
@ -55,6 +57,7 @@ impl Cha {
|
|||
|
||||
impl UserData for Cha {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("mode", |_, me| Ok(me.mode.bits()));
|
||||
fields.add_field_method_get("is_dir", |_, me| Ok(me.is_dir()));
|
||||
fields.add_field_method_get("is_hidden", |_, me| Ok(me.is_hidden()));
|
||||
fields.add_field_method_get("is_link", |_, me| Ok(me.is_link()));
|
||||
|
|
@ -70,7 +73,6 @@ impl UserData for Cha {
|
|||
#[cfg(unix)]
|
||||
{
|
||||
use std::ops::Not;
|
||||
fields.add_field_method_get("mode", |_, me| Ok(me.is_dummy().not().then_some(me.mode)));
|
||||
fields.add_field_method_get("dev", |_, me| Ok(me.is_dummy().not().then_some(me.dev)));
|
||||
fields.add_field_method_get("uid", |_, me| Ok(me.is_dummy().not().then_some(me.uid)));
|
||||
fields.add_field_method_get("gid", |_, me| Ok(me.is_dummy().not().then_some(me.gid)));
|
||||
|
|
@ -94,12 +96,12 @@ impl UserData for Cha {
|
|||
}
|
||||
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_method("perm", |_, _me, ()| {
|
||||
methods.add_method("perm", |lua, _me, ()| {
|
||||
Ok(
|
||||
#[cfg(unix)]
|
||||
Some(yazi_fs::permissions(_me.mode, _me.is_dummy())),
|
||||
lua.create_string(_me.mode.permissions(_me.is_dummy())),
|
||||
#[cfg(windows)]
|
||||
None::<String>,
|
||||
Ok::<_, mlua::Error>(mlua::Value::Nil),
|
||||
)
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-boot"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,11 +9,11 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.6.11" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.6.11" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.9.15" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.9.15" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.9.15" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
clap = { workspace = true }
|
||||
|
|
@ -23,7 +23,7 @@ regex = { workspace = true }
|
|||
serde = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
clap = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-build"
|
||||
version = "0.1.8"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -15,7 +15,7 @@ panic = "abort"
|
|||
strip = true
|
||||
|
||||
[build-dependencies]
|
||||
yazi-term = { path = "../yazi-term", version = "25.5.31" }
|
||||
yazi-term = { path = "../yazi-term", version = "25.9.15" }
|
||||
|
||||
[[bin]]
|
||||
name = "yazi-build"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-cli"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -19,11 +19,11 @@ inherits = "release"
|
|||
panic = "unwind"
|
||||
|
||||
[dependencies]
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.6.11" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.6.11" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.9.15" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.9.15" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.9.15" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
@ -36,7 +36,7 @@ toml = { workspace = true }
|
|||
twox-hash = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
|
||||
# External build dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-codegen"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-config"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,11 +9,11 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-codegen = { path = "../yazi-codegen", version = "25.6.11" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-term = { path = "../yazi-term", version = "25.6.11" }
|
||||
yazi-codegen = { path = "../yazi-codegen", version = "25.9.15" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.9.15" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
yazi-term = { path = "../yazi-term", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-core"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,18 +9,18 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.6.11" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.6.11" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.6.11" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.6.11" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "25.6.11" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.6.11" }
|
||||
yazi-scheduler = { path = "../yazi-scheduler", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-watcher = { path = "../yazi-watcher", version = "25.6.11" }
|
||||
yazi-widgets = { path = "../yazi-widgets", version = "25.6.11" }
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.9.15" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.9.15" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.9.15" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.9.15" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.9.15" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "25.9.15" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.9.15" }
|
||||
yazi-scheduler = { path = "../yazi-scheduler", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
yazi-watcher = { path = "../yazi-watcher", version = "25.9.15" }
|
||||
yazi-widgets = { path = "../yazi-widgets", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-dds"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -13,12 +13,12 @@ default = [ "vendored-lua" ]
|
|||
vendored-lua = [ "mlua/vendored" ]
|
||||
|
||||
[dependencies]
|
||||
yazi-binding = { path = "../yazi-binding", version = "25.6.11" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.6.11" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-binding = { path = "../yazi-binding", version = "25.9.15" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.9.15" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.9.15" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::{mem, ops::Deref, sync::atomic::{AtomicU64, Ordering}, time::UNIX_EPOCH
|
|||
use anyhow::Result;
|
||||
use hashbrown::HashMap;
|
||||
use parking_lot::RwLock;
|
||||
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufWriter};
|
||||
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader, BufWriter};
|
||||
use yazi_boot::BOOT;
|
||||
use yazi_fs::provider::local::{Gate, Local};
|
||||
use yazi_shared::{RoCell, timestamp_us};
|
||||
|
|
@ -79,7 +79,7 @@ impl State {
|
|||
}
|
||||
|
||||
async fn load(&self) -> Result<()> {
|
||||
let mut file = Local::open(BOOT.state_dir.join(".dds")).await?.reader();
|
||||
let mut file = BufReader::new(Local::open(BOOT.state_dir.join(".dds")).await?);
|
||||
let mut buf = String::new();
|
||||
|
||||
let mut inner = HashMap::new();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-ffi"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,7 +9,7 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-fm"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -23,22 +23,22 @@ default = [ "vendored-lua" ]
|
|||
vendored-lua = [ "mlua/vendored" ]
|
||||
|
||||
[dependencies]
|
||||
yazi-actor = { path = "../yazi-actor", version = "25.6.11" }
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.6.11" }
|
||||
yazi-binding = { path = "../yazi-binding", version = "25.6.11" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.6.11" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.6.11" }
|
||||
yazi-core = { path = "../yazi-core", version = "25.6.11" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.6.11" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.6.11" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "25.6.11" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-term = { path = "../yazi-term", version = "25.6.11" }
|
||||
yazi-watcher = { path = "../yazi-watcher", version = "25.6.11" }
|
||||
yazi-widgets = { path = "../yazi-widgets", version = "25.6.11" }
|
||||
yazi-actor = { path = "../yazi-actor", version = "25.9.15" }
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.9.15" }
|
||||
yazi-binding = { path = "../yazi-binding", version = "25.9.15" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.9.15" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.9.15" }
|
||||
yazi-core = { path = "../yazi-core", version = "25.9.15" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.9.15" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.9.15" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.9.15" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "25.9.15" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
yazi-term = { path = "../yazi-term", version = "25.9.15" }
|
||||
yazi-watcher = { path = "../yazi-watcher", version = "25.9.15" }
|
||||
yazi-widgets = { path = "../yazi-widgets", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-fs"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,9 +9,9 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-ffi = { path = "../yazi-ffi", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-ffi = { path = "../yazi-ffi", version = "25.9.15" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
use std::{fs::{FileType, Metadata}, time::SystemTime};
|
||||
use std::{fs::{FileType, Metadata}, ops::Deref, time::SystemTime};
|
||||
|
||||
use yazi_macro::{unix_either, win_either};
|
||||
use yazi_shared::url::{Url, UrlBuf};
|
||||
use yazi_shared::url::Url;
|
||||
|
||||
use super::ChaKind;
|
||||
use crate::provider;
|
||||
use crate::{cha::ChaMode, provider};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct Cha {
|
||||
pub kind: ChaKind,
|
||||
pub mode: ChaMode,
|
||||
pub len: u64,
|
||||
pub atime: Option<SystemTime>,
|
||||
pub btime: Option<SystemTime>,
|
||||
|
|
@ -16,21 +17,26 @@ pub struct Cha {
|
|||
pub ctime: Option<SystemTime>,
|
||||
pub mtime: Option<SystemTime>,
|
||||
#[cfg(unix)]
|
||||
pub mode: libc::mode_t,
|
||||
#[cfg(unix)]
|
||||
pub dev: libc::dev_t,
|
||||
#[cfg(unix)]
|
||||
pub uid: libc::uid_t,
|
||||
pub uid: u32,
|
||||
#[cfg(unix)]
|
||||
pub gid: libc::gid_t,
|
||||
pub gid: u32,
|
||||
#[cfg(unix)]
|
||||
pub nlink: libc::nlink_t,
|
||||
pub nlink: u64,
|
||||
}
|
||||
|
||||
impl Deref for Cha {
|
||||
type Target = ChaMode;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.mode }
|
||||
}
|
||||
|
||||
impl Default for Cha {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
kind: ChaKind::DUMMY,
|
||||
mode: ChaMode::empty(),
|
||||
len: 0,
|
||||
atime: None,
|
||||
btime: None,
|
||||
|
|
@ -38,8 +44,6 @@ impl Default for Cha {
|
|||
ctime: None,
|
||||
mtime: None,
|
||||
#[cfg(unix)]
|
||||
mode: 0,
|
||||
#[cfg(unix)]
|
||||
dev: 0,
|
||||
#[cfg(unix)]
|
||||
uid: 0,
|
||||
|
|
@ -53,8 +57,11 @@ impl Default for Cha {
|
|||
|
||||
impl Cha {
|
||||
#[inline]
|
||||
pub fn new<'a>(url: impl Into<Url<'a>>, meta: Metadata) -> Self {
|
||||
Self::from_just_meta(&meta).attach(ChaKind::hidden(url, &meta))
|
||||
pub fn new<'a, U>(url: U, meta: Metadata) -> Self
|
||||
where
|
||||
U: Into<Url<'a>>,
|
||||
{
|
||||
Self::from_bare(&meta).attach(ChaKind::hidden(url, &meta))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -63,7 +70,10 @@ impl Cha {
|
|||
Ok(Self::from_follow(url, provider::symlink_metadata(url).await?).await)
|
||||
}
|
||||
|
||||
pub async fn from_follow<'a>(url: impl Into<Url<'a>>, mut meta: Metadata) -> Self {
|
||||
pub async fn from_follow<'a, U>(url: U, mut meta: Metadata) -> Self
|
||||
where
|
||||
U: Into<Url<'a>>,
|
||||
{
|
||||
let url = url.into();
|
||||
let mut attached = ChaKind::hidden(url, &meta);
|
||||
|
||||
|
|
@ -75,74 +85,54 @@ impl Cha {
|
|||
attached |= ChaKind::ORPHAN;
|
||||
}
|
||||
|
||||
Self::from_just_meta(&meta).attach(attached)
|
||||
Self::from_bare(&meta).attach(attached)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_dummy(_url: &UrlBuf, ft: Option<FileType>) -> Self {
|
||||
let mut me = ft.map(Self::from_half_ft).unwrap_or_default();
|
||||
#[cfg(unix)]
|
||||
if _url.urn().is_hidden() {
|
||||
me.kind |= ChaKind::HIDDEN;
|
||||
}
|
||||
me
|
||||
}
|
||||
pub fn from_dummy<'a, U>(_url: U, ft: Option<FileType>) -> Self
|
||||
where
|
||||
U: Into<Url<'a>>,
|
||||
{
|
||||
let mode = ft.map(ChaMode::from_bare).unwrap_or_default();
|
||||
|
||||
fn from_half_ft(ft: FileType) -> Self {
|
||||
let mut kind = ChaKind::DUMMY;
|
||||
|
||||
#[cfg(unix)]
|
||||
let mode = {
|
||||
use std::os::unix::fs::FileTypeExt;
|
||||
if ft.is_dir() {
|
||||
kind |= ChaKind::DIR;
|
||||
libc::S_IFDIR
|
||||
} else if ft.is_symlink() {
|
||||
kind |= ChaKind::LINK;
|
||||
libc::S_IFLNK
|
||||
} else if ft.is_block_device() {
|
||||
libc::S_IFBLK
|
||||
} else if ft.is_char_device() {
|
||||
libc::S_IFCHR
|
||||
} else if ft.is_fifo() {
|
||||
libc::S_IFIFO
|
||||
} else if ft.is_socket() {
|
||||
libc::S_IFSOCK
|
||||
} else {
|
||||
0
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if ft.is_dir() {
|
||||
kind |= ChaKind::DIR;
|
||||
} else if ft.is_symlink() {
|
||||
kind |= ChaKind::LINK;
|
||||
}
|
||||
}
|
||||
|
||||
Self {
|
||||
kind,
|
||||
#[cfg(unix)]
|
||||
mode,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn from_just_meta(m: &Metadata) -> Self {
|
||||
#[cfg(unix)]
|
||||
use std::{os::unix::{fs::MetadataExt, prelude::PermissionsExt}, time::{Duration, UNIX_EPOCH}};
|
||||
|
||||
let mut kind = ChaKind::empty();
|
||||
if m.is_dir() {
|
||||
kind |= ChaKind::DIR;
|
||||
} else if m.is_symlink() {
|
||||
if mode.is_link() {
|
||||
kind |= ChaKind::LINK;
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
if _url.into().urn().is_hidden() {
|
||||
kind |= ChaKind::HIDDEN;
|
||||
}
|
||||
|
||||
Self { kind, mode, ..Default::default() }
|
||||
}
|
||||
|
||||
fn from_bare(m: &Metadata) -> Self {
|
||||
#[cfg(unix)]
|
||||
use std::{os::unix::fs::MetadataExt, time::{Duration, UNIX_EPOCH}};
|
||||
|
||||
#[cfg(unix)]
|
||||
let mode = {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
ChaMode::from_bits_retain(m.permissions().mode() as u16)
|
||||
};
|
||||
|
||||
#[cfg(windows)]
|
||||
let mode = {
|
||||
if m.is_file() {
|
||||
ChaMode::T_FILE
|
||||
} else if m.is_dir() {
|
||||
ChaMode::T_DIR
|
||||
} else if m.is_symlink() {
|
||||
ChaMode::T_LINK
|
||||
} else {
|
||||
ChaMode::empty()
|
||||
}
|
||||
};
|
||||
|
||||
Self {
|
||||
kind,
|
||||
kind: ChaKind::empty(),
|
||||
mode,
|
||||
len: m.len(),
|
||||
atime: m.accessed().ok(),
|
||||
btime: m.created().ok(),
|
||||
|
|
@ -150,8 +140,6 @@ impl Cha {
|
|||
ctime: UNIX_EPOCH.checked_add(Duration::new(m.ctime() as u64, m.ctime_nsec() as u32)),
|
||||
mtime: m.modified().ok(),
|
||||
#[cfg(unix)]
|
||||
mode: m.permissions().mode() as _,
|
||||
#[cfg(unix)]
|
||||
dev: m.dev() as _,
|
||||
#[cfg(unix)]
|
||||
uid: m.uid() as _,
|
||||
|
|
@ -180,9 +168,6 @@ impl Cha {
|
|||
}
|
||||
|
||||
impl Cha {
|
||||
#[inline]
|
||||
pub const fn is_dir(&self) -> bool { self.kind.contains(ChaKind::DIR) }
|
||||
|
||||
#[inline]
|
||||
pub const fn is_hidden(&self) -> bool {
|
||||
win_either!(
|
||||
|
|
@ -191,38 +176,9 @@ impl Cha {
|
|||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn is_link(&self) -> bool { self.kind.contains(ChaKind::LINK) }
|
||||
|
||||
#[inline]
|
||||
pub const fn is_orphan(&self) -> bool { self.kind.contains(ChaKind::ORPHAN) }
|
||||
|
||||
#[inline]
|
||||
pub const fn is_dummy(&self) -> bool { self.kind.contains(ChaKind::DUMMY) }
|
||||
|
||||
#[inline]
|
||||
pub const fn is_block(&self) -> bool {
|
||||
unix_either!(self.mode & libc::S_IFMT == libc::S_IFBLK, false)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn is_char(&self) -> bool {
|
||||
unix_either!(self.mode & libc::S_IFMT == libc::S_IFCHR, false)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn is_fifo(&self) -> bool {
|
||||
unix_either!(self.mode & libc::S_IFMT == libc::S_IFIFO, false)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn is_sock(&self) -> bool {
|
||||
unix_either!(self.mode & libc::S_IFMT == libc::S_IFSOCK, false)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn is_exec(&self) -> bool { unix_either!(self.mode & libc::S_IXUSR != 0, false) }
|
||||
|
||||
#[inline]
|
||||
pub const fn is_sticky(&self) -> bool { unix_either!(self.mode & libc::S_ISVTX != 0, false) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,21 +6,22 @@ use yazi_shared::url::Url;
|
|||
bitflags! {
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||
pub struct ChaKind: u8 {
|
||||
const DIR = 0b00000001;
|
||||
const HIDDEN = 0b0000_0001;
|
||||
const SYSTEM = 0b0000_0010;
|
||||
|
||||
const HIDDEN = 0b00000010;
|
||||
const LINK = 0b00000100;
|
||||
const ORPHAN = 0b00001000;
|
||||
const LINK = 0b0000_0100;
|
||||
const ORPHAN = 0b0000_1000;
|
||||
|
||||
const DUMMY = 0b00010000;
|
||||
#[cfg(windows)]
|
||||
const SYSTEM = 0b00100000;
|
||||
const DUMMY = 0b0001_0000;
|
||||
}
|
||||
}
|
||||
|
||||
impl ChaKind {
|
||||
#[inline]
|
||||
pub(super) fn hidden<'a>(_url: impl Into<Url<'a>>, _meta: &Metadata) -> Self {
|
||||
pub(super) fn hidden<'a, U>(_url: U, _meta: &Metadata) -> Self
|
||||
where
|
||||
U: Into<Url<'a>>,
|
||||
{
|
||||
let mut me = Self::empty();
|
||||
|
||||
#[cfg(unix)]
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
yazi_macro::mod_flat!(cha kind);
|
||||
yazi_macro::mod_flat!(cha kind mode);
|
||||
|
|
|
|||
158
yazi-fs/src/cha/mode.rs
Normal file
158
yazi-fs/src/cha/mode.rs
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
use std::fs::FileType;
|
||||
|
||||
use bitflags::bitflags;
|
||||
|
||||
bitflags! {
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||
pub struct ChaMode: u16 {
|
||||
// File type
|
||||
const T_MASK = 0b1111_0000_0000_0000;
|
||||
const T_SOCK = 0b1100_0000_0000_0000;
|
||||
const T_LINK = 0b1010_0000_0000_0000;
|
||||
const T_FILE = 0b1000_0000_0000_0000;
|
||||
const T_BLOCK = 0b0110_0000_0000_0000;
|
||||
const T_DIR = 0b0100_0000_0000_0000;
|
||||
const T_CHAR = 0b0010_0000_0000_0000;
|
||||
const T_FIFO = 0b0001_0000_0000_0000;
|
||||
// Special
|
||||
const S_SUID = 0b0000_1000_0000_0000;
|
||||
const S_SGID = 0b0000_0100_0000_0000;
|
||||
const S_STICKY = 0b0000_0010_0000_0000;
|
||||
// User
|
||||
const U_MASK = 0b0000_0001_1100_0000;
|
||||
const U_READ = 0b0000_0001_0000_0000;
|
||||
const U_WRITE = 0b0000_0000_1000_0000;
|
||||
const U_EXEC = 0b0000_0000_0100_0000;
|
||||
// Group
|
||||
const G_MASK = 0b0000_0000_0011_1000;
|
||||
const G_READ = 0b0000_0000_0010_0000;
|
||||
const G_WRITE = 0b0000_0000_0001_0000;
|
||||
const G_EXEC = 0b0000_0000_0000_1000;
|
||||
// Others
|
||||
const O_MASK = 0b0000_0000_0000_0111;
|
||||
const O_READ = 0b0000_0000_0000_0100;
|
||||
const O_WRITE = 0b0000_0000_0000_0010;
|
||||
const O_EXEC = 0b0000_0000_0000_0001;
|
||||
}
|
||||
}
|
||||
|
||||
impl ChaMode {
|
||||
#[inline]
|
||||
pub fn r#type(self) -> Self { self & Self::T_MASK }
|
||||
|
||||
// Convert a file mode to a string representation
|
||||
#[cfg(unix)]
|
||||
#[allow(clippy::collapsible_else_if)]
|
||||
pub fn permissions(self, dummy: bool) -> [u8; 10] {
|
||||
let mut s = *b"-?????????";
|
||||
|
||||
// File type
|
||||
s[0] = match self.r#type() {
|
||||
Self::T_DIR => b'd',
|
||||
Self::T_LINK => b'l',
|
||||
Self::T_BLOCK => b'b',
|
||||
Self::T_CHAR => b'c',
|
||||
Self::T_SOCK => b's',
|
||||
Self::T_FIFO => b'p',
|
||||
_ => b'-',
|
||||
};
|
||||
if dummy {
|
||||
return s;
|
||||
}
|
||||
|
||||
// User
|
||||
s[1] = if self.contains(Self::U_READ) { b'r' } else { b'-' };
|
||||
s[2] = if self.contains(Self::U_WRITE) { b'w' } else { b'-' };
|
||||
s[3] = if self.contains(Self::U_EXEC) {
|
||||
if self.contains(Self::S_SUID) { b's' } else { b'x' }
|
||||
} else {
|
||||
if self.contains(Self::S_SUID) { b'S' } else { b'-' }
|
||||
};
|
||||
|
||||
// Group
|
||||
s[4] = if self.contains(Self::G_READ) { b'r' } else { b'-' };
|
||||
s[5] = if self.contains(Self::G_WRITE) { b'w' } else { b'-' };
|
||||
s[6] = if self.contains(Self::G_EXEC) {
|
||||
if self.contains(Self::S_SGID) { b's' } else { b'x' }
|
||||
} else {
|
||||
if self.contains(Self::S_SGID) { b'S' } else { b'-' }
|
||||
};
|
||||
|
||||
// Others
|
||||
s[7] = if self.contains(Self::O_READ) { b'r' } else { b'-' };
|
||||
s[8] = if self.contains(Self::O_WRITE) { b'w' } else { b'-' };
|
||||
s[9] = if self.contains(Self::O_EXEC) {
|
||||
if self.contains(Self::S_STICKY) { b't' } else { b'x' }
|
||||
} else {
|
||||
if self.contains(Self::S_STICKY) { b'T' } else { b'-' }
|
||||
};
|
||||
|
||||
s
|
||||
}
|
||||
|
||||
pub(super) fn from_bare(ft: FileType) -> Self {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::fs::FileTypeExt;
|
||||
if ft.is_file() {
|
||||
Self::T_FILE
|
||||
} else if ft.is_dir() {
|
||||
Self::T_DIR
|
||||
} else if ft.is_symlink() {
|
||||
Self::T_LINK
|
||||
} else if ft.is_block_device() {
|
||||
Self::T_BLOCK
|
||||
} else if ft.is_char_device() {
|
||||
Self::T_CHAR
|
||||
} else if ft.is_socket() {
|
||||
Self::T_SOCK
|
||||
} else if ft.is_fifo() {
|
||||
Self::T_FIFO
|
||||
} else {
|
||||
Self::empty()
|
||||
}
|
||||
}
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if ft.is_file() {
|
||||
Self::T_FILE
|
||||
} else if ft.is_dir() {
|
||||
Self::T_DIR
|
||||
} else if ft.is_symlink() {
|
||||
Self::T_LINK
|
||||
} else {
|
||||
Self::empty()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ChaMode {
|
||||
#[inline]
|
||||
pub const fn is_file(self) -> bool { self.contains(Self::T_FILE) }
|
||||
|
||||
#[inline]
|
||||
pub const fn is_dir(self) -> bool { self.contains(Self::T_DIR) }
|
||||
|
||||
#[inline]
|
||||
pub const fn is_link(&self) -> bool { self.contains(Self::T_LINK) }
|
||||
|
||||
#[inline]
|
||||
pub const fn is_block(&self) -> bool { self.contains(Self::T_BLOCK) }
|
||||
|
||||
#[inline]
|
||||
pub const fn is_char(&self) -> bool { self.contains(Self::T_CHAR) }
|
||||
|
||||
#[inline]
|
||||
pub const fn is_sock(&self) -> bool { self.contains(Self::T_SOCK) }
|
||||
|
||||
#[inline]
|
||||
pub const fn is_fifo(&self) -> bool { self.contains(Self::T_FIFO) }
|
||||
|
||||
// TODO: deprecate
|
||||
#[inline]
|
||||
pub const fn is_exec(&self) -> bool { self.contains(Self::U_EXEC) }
|
||||
|
||||
#[inline]
|
||||
pub const fn is_sticky(&self) -> bool { self.contains(Self::S_STICKY) }
|
||||
}
|
||||
|
|
@ -94,59 +94,6 @@ pub async fn remove_dir_clean(dir: &UrlBuf) {
|
|||
provider::remove_dir(dir).await.ok();
|
||||
}
|
||||
|
||||
// Convert a file mode to a string representation
|
||||
#[cfg(unix)]
|
||||
#[allow(clippy::collapsible_else_if)]
|
||||
pub fn permissions(m: libc::mode_t, dummy: bool) -> String {
|
||||
use libc::{S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFSOCK, S_IRGRP, S_IROTH, S_IRUSR, S_ISGID, S_ISUID, S_ISVTX, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR};
|
||||
let mut s = String::with_capacity(10);
|
||||
|
||||
// Filetype
|
||||
s.push(match m & S_IFMT {
|
||||
S_IFBLK => 'b',
|
||||
S_IFCHR => 'c',
|
||||
S_IFDIR => 'd',
|
||||
S_IFIFO => 'p',
|
||||
S_IFLNK => 'l',
|
||||
S_IFSOCK => 's',
|
||||
_ => '-',
|
||||
});
|
||||
|
||||
if dummy {
|
||||
s.push_str("?????????");
|
||||
return s;
|
||||
}
|
||||
|
||||
// Owner
|
||||
s.push(if m & S_IRUSR != 0 { 'r' } else { '-' });
|
||||
s.push(if m & S_IWUSR != 0 { 'w' } else { '-' });
|
||||
s.push(if m & S_IXUSR != 0 {
|
||||
if m & S_ISUID != 0 { 's' } else { 'x' }
|
||||
} else {
|
||||
if m & S_ISUID != 0 { 'S' } else { '-' }
|
||||
});
|
||||
|
||||
// Group
|
||||
s.push(if m & S_IRGRP != 0 { 'r' } else { '-' });
|
||||
s.push(if m & S_IWGRP != 0 { 'w' } else { '-' });
|
||||
s.push(if m & S_IXGRP != 0 {
|
||||
if m & S_ISGID != 0 { 's' } else { 'x' }
|
||||
} else {
|
||||
if m & S_ISGID != 0 { 'S' } else { '-' }
|
||||
});
|
||||
|
||||
// Other
|
||||
s.push(if m & S_IROTH != 0 { 'r' } else { '-' });
|
||||
s.push(if m & S_IWOTH != 0 { 'w' } else { '-' });
|
||||
s.push(if m & S_IXOTH != 0 {
|
||||
if m & S_ISVTX != 0 { 't' } else { 'x' }
|
||||
} else {
|
||||
if m & S_ISVTX != 0 { 'T' } else { '-' }
|
||||
});
|
||||
|
||||
s
|
||||
}
|
||||
|
||||
// Find the max common root in a list of urls
|
||||
// e.g. /a/b/c, /a/b/d -> /a/b
|
||||
// /aa/bb/cc, /aa/dd/ee -> /aa
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
yazi_macro::mod_pub!(cha mounts provider path);
|
||||
|
||||
yazi_macro::mod_flat!(calculator cwd file files filter fns op sorter sorting stage xdg);
|
||||
yazi_macro::mod_flat!(cwd file files filter fns op sorter sorting stage xdg);
|
||||
|
||||
pub fn init() {
|
||||
CWD.init(<_>::default());
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
// --- BufRead
|
||||
pub trait BufRead: tokio::io::AsyncRead + Send {}
|
||||
|
||||
impl<T: tokio::io::AsyncRead + Send> BufRead for T {}
|
||||
|
||||
// --- BufReadSync
|
||||
pub trait BufReadSync: std::io::BufRead + std::io::Seek + Send {}
|
||||
|
||||
impl<T: std::io::BufRead + std::io::Seek + Send> BufReadSync for T {}
|
||||
81
yazi-fs/src/provider/calculator.rs
Normal file
81
yazi-fs/src/provider/calculator.rs
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
use std::{collections::VecDeque, io, time::{Duration, Instant}};
|
||||
|
||||
use yazi_shared::{Either, url::{Url, UrlBuf}};
|
||||
|
||||
use crate::provider::{self, ReadDir};
|
||||
|
||||
pub enum SizeCalculator {
|
||||
File(Option<u64>),
|
||||
Dir(VecDeque<Either<UrlBuf, ReadDir>>),
|
||||
}
|
||||
|
||||
impl SizeCalculator {
|
||||
pub async fn new<'a, U>(url: U) -> io::Result<Self>
|
||||
where
|
||||
U: Into<Url<'a>>,
|
||||
{
|
||||
let url: Url = url.into();
|
||||
let meta = provider::symlink_metadata(url).await?;
|
||||
Ok(if meta.is_dir() {
|
||||
Self::Dir(VecDeque::from([Either::Left(url.to_owned())]))
|
||||
} else {
|
||||
Self::File(Some(meta.len()))
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn total<'a, U>(url: U) -> io::Result<u64>
|
||||
where
|
||||
U: Into<Url<'a>>,
|
||||
{
|
||||
let mut it = Self::new(url).await?;
|
||||
let mut total = 0;
|
||||
while let Some(n) = it.next().await? {
|
||||
total += n;
|
||||
}
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
pub async fn next(&mut self) -> io::Result<Option<u64>> {
|
||||
Ok(match self {
|
||||
Self::File(size) => size.take(),
|
||||
Self::Dir(buf) => Self::next_chunk(buf).await,
|
||||
})
|
||||
}
|
||||
|
||||
async fn next_chunk(buf: &mut VecDeque<Either<UrlBuf, ReadDir>>) -> Option<u64> {
|
||||
let (mut i, mut size, now) = (0, 0, Instant::now());
|
||||
macro_rules! pop_and_continue {
|
||||
() => {{
|
||||
buf.pop_front();
|
||||
if buf.is_empty() {
|
||||
return Some(size);
|
||||
}
|
||||
continue;
|
||||
}};
|
||||
}
|
||||
|
||||
while i < 2000 && now.elapsed() < Duration::from_millis(100) {
|
||||
i += 1;
|
||||
let front = buf.front_mut()?;
|
||||
|
||||
if let Either::Left(p) = front {
|
||||
*front = match provider::read_dir(p).await {
|
||||
Ok(it) => Either::Right(it),
|
||||
Err(_) => pop_and_continue!(),
|
||||
};
|
||||
}
|
||||
|
||||
let Ok(Some(ent)) = front.right_mut()?.next_entry().await else {
|
||||
pop_and_continue!();
|
||||
};
|
||||
|
||||
let Ok(ft) = ent.file_type().await else { continue };
|
||||
if ft.is_dir() {
|
||||
buf.push_back(Either::Left(ent.url()));
|
||||
} else if let Ok(meta) = ent.metadata().await {
|
||||
size += meta.len();
|
||||
}
|
||||
}
|
||||
Some(size)
|
||||
}
|
||||
}
|
||||
|
|
@ -33,36 +33,3 @@ impl DirEntry {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- DirEntrySync
|
||||
pub enum DirEntrySync {
|
||||
Local(super::local::DirEntrySync),
|
||||
}
|
||||
|
||||
impl DirEntrySync {
|
||||
#[must_use]
|
||||
pub fn url(&self) -> UrlBuf {
|
||||
match self {
|
||||
Self::Local(local) => local.url(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn file_name(&self) -> OsString {
|
||||
match self {
|
||||
Self::Local(local) => local.file_name(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn metadata(&self) -> io::Result<std::fs::Metadata> {
|
||||
match self {
|
||||
Self::Local(local) => local.metadata(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn file_type(&self) -> io::Result<std::fs::FileType> {
|
||||
match self {
|
||||
Self::Local(local) => local.file_type(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
use std::{collections::VecDeque, future::poll_fn, io, mem, pin::Pin, task::{Poll, ready}, time::{Duration, Instant}};
|
||||
use std::{collections::VecDeque, future::poll_fn, io, mem, path::{Path, PathBuf}, pin::Pin, task::{Poll, ready}, time::{Duration, Instant}};
|
||||
|
||||
use tokio::task::JoinHandle;
|
||||
use yazi_shared::{Either, url::UrlBuf};
|
||||
use yazi_shared::Either;
|
||||
|
||||
use crate::provider::{self, ReadDirSync};
|
||||
|
||||
type Task = Either<UrlBuf, ReadDirSync>;
|
||||
type Task = Either<PathBuf, std::fs::ReadDir>;
|
||||
|
||||
pub enum SizeCalculator {
|
||||
Idle((VecDeque<Task>, Option<u64>)),
|
||||
|
|
@ -13,23 +11,23 @@ pub enum SizeCalculator {
|
|||
}
|
||||
|
||||
impl SizeCalculator {
|
||||
pub async fn new(url: &UrlBuf) -> io::Result<Self> {
|
||||
let u = url.to_owned();
|
||||
pub async fn new(path: &Path) -> io::Result<Self> {
|
||||
let p = path.to_owned();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let meta = provider::symlink_metadata_sync(&u)?;
|
||||
let meta = std::fs::symlink_metadata(&p)?;
|
||||
if !meta.is_dir() {
|
||||
return Ok(Self::Idle((VecDeque::new(), Some(meta.len()))));
|
||||
}
|
||||
|
||||
let mut buf = VecDeque::from([Either::Right(provider::read_dir_sync(&u)?)]);
|
||||
let mut buf = VecDeque::from([Either::Right(std::fs::read_dir(&p)?)]);
|
||||
let size = Self::next_chunk(&mut buf);
|
||||
Ok(Self::Idle((buf, size)))
|
||||
})
|
||||
.await?
|
||||
}
|
||||
|
||||
pub async fn total(url: &UrlBuf) -> io::Result<u64> {
|
||||
let mut it = Self::new(url).await?;
|
||||
pub async fn total(path: &Path) -> io::Result<u64> {
|
||||
let mut it = Self::new(path).await?;
|
||||
let mut total = 0;
|
||||
while let Some(n) = it.next().await? {
|
||||
total += n;
|
||||
|
|
@ -63,7 +61,7 @@ impl SizeCalculator {
|
|||
.await
|
||||
}
|
||||
|
||||
fn next_chunk(buf: &mut VecDeque<Either<UrlBuf, ReadDirSync>>) -> Option<u64> {
|
||||
fn next_chunk(buf: &mut VecDeque<Either<PathBuf, std::fs::ReadDir>>) -> Option<u64> {
|
||||
let (mut i, mut size, now) = (0, 0, Instant::now());
|
||||
macro_rules! pop_and_continue {
|
||||
() => {{
|
||||
|
|
@ -79,8 +77,8 @@ impl SizeCalculator {
|
|||
i += 1;
|
||||
let front = buf.front_mut()?;
|
||||
|
||||
if let Either::Left(u) = front {
|
||||
*front = match provider::read_dir_sync(u) {
|
||||
if let Either::Left(p) = front {
|
||||
*front = match std::fs::read_dir(p) {
|
||||
Ok(it) => Either::Right(it),
|
||||
Err(_) => pop_and_continue!(),
|
||||
};
|
||||
|
|
@ -93,7 +91,7 @@ impl SizeCalculator {
|
|||
let Ok(ent) = next else { continue };
|
||||
let Ok(ft) = ent.file_type() else { continue };
|
||||
if ft.is_dir() {
|
||||
buf.push_back(Either::Left(ent.url()));
|
||||
buf.push_back(Either::Left(ent.path()));
|
||||
} else if let Ok(meta) = ent.metadata() {
|
||||
size += meta.len();
|
||||
}
|
||||
|
|
@ -22,25 +22,3 @@ impl DirEntry {
|
|||
#[must_use]
|
||||
pub fn url(&self) -> UrlBuf { self.0.path().into() }
|
||||
}
|
||||
|
||||
// --- DirEntrySync
|
||||
pub struct DirEntrySync(std::fs::DirEntry);
|
||||
|
||||
impl Deref for DirEntrySync {
|
||||
type Target = std::fs::DirEntry;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.0 }
|
||||
}
|
||||
|
||||
impl From<std::fs::DirEntry> for DirEntrySync {
|
||||
fn from(value: std::fs::DirEntry) -> Self { Self(value) }
|
||||
}
|
||||
|
||||
impl From<DirEntrySync> for crate::provider::DirEntrySync {
|
||||
fn from(value: DirEntrySync) -> Self { Self::Local(value) }
|
||||
}
|
||||
|
||||
impl DirEntrySync {
|
||||
#[must_use]
|
||||
pub fn url(&self) -> UrlBuf { self.0.path().into() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::{io, path::{Path, PathBuf}};
|
||||
|
||||
use crate::{cha::Cha, provider::local::{Gate, ReadDir, ReadDirSync, RwFile}};
|
||||
use crate::{cha::Cha, provider::local::{Gate, ReadDir, RwFile}};
|
||||
|
||||
pub struct Local;
|
||||
|
||||
|
|
@ -54,14 +54,14 @@ impl Local {
|
|||
tokio::task::spawn_blocking(move || {
|
||||
let mut reader = std::fs::File::open(from)?;
|
||||
let mut writer = std::fs::OpenOptions::new()
|
||||
.mode(cha.mode as u32) // Do not remove `as u32`, https://github.com/termux/termux-packages/pull/22481
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.open(to)?;
|
||||
.mode(cha.mode.bits() as _)
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.open(to)?;
|
||||
|
||||
let written = std::io::copy(&mut reader, &mut writer)?;
|
||||
unsafe { libc::fchmod(writer.as_raw_fd(), cha.mode) };
|
||||
unsafe { libc::fchmod(writer.as_raw_fd(), cha.mode.bits() as _) };
|
||||
writer.set_times(ft).ok();
|
||||
|
||||
Ok(written)
|
||||
|
|
@ -145,14 +145,6 @@ impl Local {
|
|||
tokio::fs::read_dir(path).await.map(Into::into)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_dir_sync<P>(path: P) -> io::Result<ReadDirSync>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
std::fs::read_dir(path).map(Into::into)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn read_link<P>(path: P) -> io::Result<PathBuf>
|
||||
where
|
||||
|
|
@ -261,14 +253,6 @@ impl Local {
|
|||
tokio::fs::symlink_metadata(path).await
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn symlink_metadata_sync<P>(path: P) -> io::Result<std::fs::Metadata>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
std::fs::symlink_metadata(path)
|
||||
}
|
||||
|
||||
pub async fn trash<P>(path: P) -> io::Result<()>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
yazi_macro::mod_flat!(casefold dir_entry gate identical local read_dir rw_file);
|
||||
yazi_macro::mod_flat!(calculator casefold dir_entry gate identical local read_dir rw_file);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::io;
|
||||
|
||||
use super::{DirEntry, DirEntrySync};
|
||||
use super::DirEntry;
|
||||
|
||||
pub struct ReadDir(tokio::fs::ReadDir);
|
||||
|
||||
|
|
@ -17,22 +17,3 @@ impl ReadDir {
|
|||
self.0.next_entry().await.map(|entry| entry.map(Into::into))
|
||||
}
|
||||
}
|
||||
|
||||
// --- ReadDirSync
|
||||
pub struct ReadDirSync(std::fs::ReadDir);
|
||||
|
||||
impl From<std::fs::ReadDir> for ReadDirSync {
|
||||
fn from(value: std::fs::ReadDir) -> Self { Self(value) }
|
||||
}
|
||||
|
||||
impl From<ReadDirSync> for crate::provider::ReadDirSync {
|
||||
fn from(value: ReadDirSync) -> Self { Self::Local(value) }
|
||||
}
|
||||
|
||||
impl Iterator for ReadDirSync {
|
||||
type Item = io::Result<DirEntrySync>;
|
||||
|
||||
fn next(&mut self) -> Option<io::Result<DirEntrySync>> {
|
||||
self.0.next().map(|result| result.map(Into::into))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
use std::{pin::Pin, task::Poll};
|
||||
|
||||
use tokio::io::{AsyncRead, AsyncSeek, AsyncWrite};
|
||||
|
||||
pub struct RwFile(tokio::fs::File);
|
||||
|
||||
impl From<tokio::fs::File> for RwFile {
|
||||
|
|
@ -8,11 +12,67 @@ impl From<RwFile> for crate::provider::RwFile {
|
|||
fn from(value: RwFile) -> Self { Self::Local(value) }
|
||||
}
|
||||
|
||||
impl From<tokio::fs::File> for crate::provider::RwFile {
|
||||
fn from(value: tokio::fs::File) -> Self { RwFile(value).into() }
|
||||
impl AsyncRead for RwFile {
|
||||
#[inline]
|
||||
fn poll_read(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
buf: &mut tokio::io::ReadBuf<'_>,
|
||||
) -> Poll<std::io::Result<()>> {
|
||||
Pin::new(&mut self.0).poll_read(cx, buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl RwFile {
|
||||
impl AsyncSeek for RwFile {
|
||||
#[inline]
|
||||
pub fn reader(self) -> tokio::io::BufReader<tokio::fs::File> { tokio::io::BufReader::new(self.0) }
|
||||
fn start_seek(mut self: Pin<&mut Self>, position: std::io::SeekFrom) -> std::io::Result<()> {
|
||||
Pin::new(&mut self.0).start_seek(position)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn poll_complete(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
) -> Poll<std::io::Result<u64>> {
|
||||
Pin::new(&mut self.0).poll_complete(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncWrite for RwFile {
|
||||
#[inline]
|
||||
fn poll_write(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
buf: &[u8],
|
||||
) -> Poll<Result<usize, std::io::Error>> {
|
||||
Pin::new(&mut self.0).poll_write(cx, buf)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn poll_flush(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
) -> Poll<Result<(), std::io::Error>> {
|
||||
Pin::new(&mut self.0).poll_flush(cx)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn poll_shutdown(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
) -> Poll<Result<(), std::io::Error>> {
|
||||
Pin::new(&mut self.0).poll_shutdown(cx)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn poll_write_vectored(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
bufs: &[std::io::IoSlice<'_>],
|
||||
) -> Poll<Result<usize, std::io::Error>> {
|
||||
Pin::new(&mut self.0).poll_write_vectored(cx, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool { self.0.is_write_vectored() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
yazi_macro::mod_pub!(local sftp);
|
||||
|
||||
yazi_macro::mod_flat!(buffer dir_entry provider read_dir rw_file);
|
||||
yazi_macro::mod_flat!(calculator dir_entry provider read_dir rw_file);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::{io, path::{Path, PathBuf}};
|
|||
|
||||
use yazi_shared::url::{Url, UrlBuf};
|
||||
|
||||
use crate::{cha::Cha, provider::{ReadDir, ReadDirSync, RwFile, local::{self, Local}}};
|
||||
use crate::{cha::Cha, provider::{ReadDir, RwFile, local::{self, Local}}};
|
||||
|
||||
#[inline]
|
||||
pub fn cache<'a, U>(url: U) -> Option<PathBuf>
|
||||
|
|
@ -12,6 +12,19 @@ where
|
|||
if let Some(path) = url.into().as_path() { Local::cache(path) } else { None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn calculate<'a, U>(url: U) -> io::Result<u64>
|
||||
where
|
||||
U: Into<Url<'a>>,
|
||||
{
|
||||
let url: Url = url.into();
|
||||
if let Some(path) = url.as_path() {
|
||||
local::SizeCalculator::total(path).await
|
||||
} else {
|
||||
super::SizeCalculator::total(url).await
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn canonicalize<'a, U>(url: U) -> io::Result<UrlBuf>
|
||||
where
|
||||
|
|
@ -156,18 +169,6 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_dir_sync<'a, U>(url: U) -> io::Result<ReadDirSync>
|
||||
where
|
||||
U: Into<Url<'a>>,
|
||||
{
|
||||
if let Some(path) = url.into().as_path() {
|
||||
Local::read_dir_sync(path).map(Into::into)
|
||||
} else {
|
||||
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn read_link<'a, U>(url: U) -> io::Result<PathBuf>
|
||||
where
|
||||
|
|
@ -278,18 +279,6 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn symlink_metadata_sync<'a, U>(url: U) -> io::Result<std::fs::Metadata>
|
||||
where
|
||||
U: Into<Url<'a>>,
|
||||
{
|
||||
if let Some(path) = url.into().as_path() {
|
||||
Local::symlink_metadata_sync(path)
|
||||
} else {
|
||||
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem"))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn trash<'a, U>(url: U) -> io::Result<()>
|
||||
where
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::io;
|
||||
|
||||
use super::{DirEntry, DirEntrySync};
|
||||
use super::DirEntry;
|
||||
|
||||
pub enum ReadDir {
|
||||
Local(super::local::ReadDir),
|
||||
|
|
@ -13,18 +13,3 @@ impl ReadDir {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- ReadDirSync
|
||||
pub enum ReadDirSync {
|
||||
Local(super::local::ReadDirSync),
|
||||
}
|
||||
|
||||
impl Iterator for ReadDirSync {
|
||||
type Item = io::Result<DirEntrySync>;
|
||||
|
||||
fn next(&mut self) -> Option<io::Result<DirEntrySync>> {
|
||||
match self {
|
||||
Self::Local(local) => local.next().map(|result| result.map(Into::into)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,71 @@
|
|||
use crate::provider::BufRead;
|
||||
use std::pin::Pin;
|
||||
|
||||
use tokio::io::{AsyncRead, AsyncWrite};
|
||||
|
||||
pub enum RwFile {
|
||||
Local(super::local::RwFile),
|
||||
}
|
||||
|
||||
impl RwFile {
|
||||
pub fn reader(self) -> Box<dyn BufRead> {
|
||||
match self {
|
||||
Self::Local(local) => Box::new(local.reader()),
|
||||
impl AsyncRead for RwFile {
|
||||
#[inline]
|
||||
fn poll_read(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
buf: &mut tokio::io::ReadBuf<'_>,
|
||||
) -> std::task::Poll<std::io::Result<()>> {
|
||||
match &mut *self {
|
||||
Self::Local(f) => Pin::new(f).poll_read(cx, buf),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncWrite for RwFile {
|
||||
#[inline]
|
||||
fn poll_write(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
buf: &[u8],
|
||||
) -> std::task::Poll<Result<usize, std::io::Error>> {
|
||||
match &mut *self {
|
||||
Self::Local(f) => Pin::new(f).poll_write(cx, buf),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn poll_flush(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
) -> std::task::Poll<Result<(), std::io::Error>> {
|
||||
match &mut *self {
|
||||
Self::Local(f) => Pin::new(f).poll_flush(cx),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn poll_shutdown(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
) -> std::task::Poll<Result<(), std::io::Error>> {
|
||||
match &mut *self {
|
||||
Self::Local(f) => Pin::new(f).poll_shutdown(cx),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn poll_write_vectored(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
bufs: &[std::io::IoSlice<'_>],
|
||||
) -> std::task::Poll<Result<usize, std::io::Error>> {
|
||||
match &mut *self {
|
||||
Self::Local(f) => Pin::new(f).poll_write_vectored(cx, bufs),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
match self {
|
||||
Self::Local(f) => f.is_write_vectored(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,13 +84,6 @@ impl Sftp {
|
|||
todo!()
|
||||
}
|
||||
|
||||
pub fn read_dir_sync<P>(path: P) -> io::Result<()>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub async fn read_link<P>(path: P) -> io::Result<PathBuf>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
|
|
@ -166,13 +159,6 @@ impl Sftp {
|
|||
todo!()
|
||||
}
|
||||
|
||||
pub fn symlink_metadata_sync<P>(path: P) -> io::Result<std::fs::Metadata>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub async fn trash<P>(path: P) -> io::Result<()>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-macro"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-packing"
|
||||
version = "25.5.28"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-parser"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -13,12 +13,12 @@ default = [ "vendored-lua" ]
|
|||
vendored-lua = [ "mlua/vendored" ]
|
||||
|
||||
[dependencies]
|
||||
yazi-binding = { path = "../yazi-binding", version = "25.6.11" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.6.11" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.6.11" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-binding = { path = "../yazi-binding", version = "25.9.15" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.9.15" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.9.15" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.9.15" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-plugin"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -13,17 +13,17 @@ default = [ "vendored-lua" ]
|
|||
vendored-lua = [ "mlua/vendored" ]
|
||||
|
||||
[dependencies]
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.6.11" }
|
||||
yazi-binding = { path = "../yazi-binding", version = "25.6.11" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.6.11" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.6.11" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.6.11" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.6.11" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-widgets = { path = "../yazi-widgets", version = "25.6.11" }
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.9.15" }
|
||||
yazi-binding = { path = "../yazi-binding", version = "25.9.15" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.9.15" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.9.15" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.9.15" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.9.15" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.9.15" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
yazi-widgets = { path = "../yazi-widgets", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ function M:peek(job)
|
|||
for _, f in ipairs(files) do
|
||||
local icon = File({
|
||||
url = Url(f.path),
|
||||
cha = Cha { kind = f.attr:sub(1, 1) == "D" and 1 or 0 },
|
||||
cha = Cha { mode = tonumber(f.attr:sub(1, 1) == "D" and "40700" or "100644", 8) },
|
||||
}):icon()
|
||||
|
||||
if f.size > 0 then
|
||||
|
|
|
|||
|
|
@ -1,12 +1,20 @@
|
|||
use mlua::{IntoLuaMulti, UserData, UserDataMethods, Value};
|
||||
use yazi_binding::Error;
|
||||
|
||||
pub struct SizeCalculator(pub yazi_fs::SizeCalculator);
|
||||
pub enum SizeCalculator {
|
||||
Local(yazi_fs::provider::local::SizeCalculator),
|
||||
Remote(yazi_fs::provider::SizeCalculator),
|
||||
}
|
||||
|
||||
impl UserData for SizeCalculator {
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_async_method_mut("recv", |lua, mut me, ()| async move {
|
||||
match me.0.next().await {
|
||||
let next = match &mut *me {
|
||||
Self::Local(it) => it.next().await,
|
||||
Self::Remote(it) => it.next().await,
|
||||
};
|
||||
|
||||
match next {
|
||||
Ok(value) => value.into_lua_multi(&lua),
|
||||
Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua),
|
||||
}
|
||||
|
|
|
|||
15
yazi-plugin/src/external/highlighter.rs
vendored
15
yazi-plugin/src/external/highlighter.rs
vendored
|
|
@ -3,9 +3,9 @@ use std::{borrow::Cow, io::Cursor, mem, path::{Path, PathBuf}, sync::OnceLock};
|
|||
use anyhow::{Result, anyhow};
|
||||
use ratatui::{layout::Size, text::{Line, Span, Text}};
|
||||
use syntect::{LoadingError, dumps, easy::HighlightLines, highlighting::{self, Theme, ThemeSet}, parsing::{SyntaxReference, SyntaxSet}};
|
||||
use tokio::io::AsyncBufReadExt;
|
||||
use tokio::io::{AsyncBufReadExt, AsyncSeekExt, BufReader};
|
||||
use yazi_config::{THEME, YAZI, preview::PreviewWrap};
|
||||
use yazi_fs::provider::local::Local;
|
||||
use yazi_fs::provider::local::{self, Local};
|
||||
use yazi_shared::{Ids, errors::PeekError, replace_to_printable};
|
||||
|
||||
static INCR: Ids = Ids::new();
|
||||
|
|
@ -39,9 +39,9 @@ impl Highlighter {
|
|||
pub fn abort() { INCR.next(); }
|
||||
|
||||
pub async fn highlight(&self, skip: usize, size: Size) -> Result<Text<'static>, PeekError> {
|
||||
let mut reader = Local::open(&self.path).await?.reader();
|
||||
let mut reader = BufReader::new(Local::open(&self.path).await?);
|
||||
|
||||
let syntax = Self::find_syntax(&self.path).await;
|
||||
let syntax = Self::find_syntax(&self.path, &mut reader).await;
|
||||
let mut plain = syntax.is_err();
|
||||
|
||||
let mut before = Vec::with_capacity(if plain { 0 } else { skip });
|
||||
|
|
@ -130,7 +130,10 @@ impl Highlighter {
|
|||
.await?
|
||||
}
|
||||
|
||||
async fn find_syntax(path: &Path) -> Result<&'static SyntaxReference> {
|
||||
async fn find_syntax(
|
||||
path: &Path,
|
||||
reader: &mut BufReader<local::RwFile>,
|
||||
) -> Result<&'static SyntaxReference> {
|
||||
let (_, syntaxes) = Self::init();
|
||||
let name = path.file_name().map(|n| n.to_string_lossy()).unwrap_or_default();
|
||||
if let Some(s) = syntaxes.find_syntax_by_extension(&name) {
|
||||
|
|
@ -143,8 +146,8 @@ impl Highlighter {
|
|||
}
|
||||
|
||||
let mut line = String::new();
|
||||
let mut reader = Local::open(&path).await?.reader();
|
||||
reader.read_line(&mut line).await?;
|
||||
reader.rewind().await?;
|
||||
syntaxes.find_syntax_by_first_line(&line).ok_or_else(|| anyhow!("No syntax found"))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -147,8 +147,14 @@ fn read_dir(lua: &Lua) -> mlua::Result<Function> {
|
|||
|
||||
fn calc_size(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_async_function(|lua, url: UrlRef| async move {
|
||||
match yazi_fs::SizeCalculator::new(&url).await {
|
||||
Ok(it) => SizeCalculator(it).into_lua_multi(&lua),
|
||||
let it = if let Some(path) = url.as_path() {
|
||||
provider::local::SizeCalculator::new(path).await.map(SizeCalculator::Local)
|
||||
} else {
|
||||
provider::SizeCalculator::new(&*url).await.map(SizeCalculator::Remote)
|
||||
};
|
||||
|
||||
match it {
|
||||
Ok(it) => it.into_lua_multi(&lua),
|
||||
Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua),
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-proxy"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,10 +9,10 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-config = { path = "../yazi-config", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.9.15" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-scheduler"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,14 +9,14 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-config = { path = "../yazi-config", version = "25.6.11" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.6.11" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.6.11" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "25.6.11" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.9.15" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.9.15" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.9.15" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.9.15" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "25.9.15" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use tokio::sync::mpsc;
|
|||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::error;
|
||||
use yazi_config::Priority;
|
||||
use yazi_fs::{FilesOp, SizeCalculator};
|
||||
use yazi_fs::{FilesOp, provider};
|
||||
use yazi_plugin::isolate;
|
||||
use yazi_shared::{event::CmdCow, url::UrlBuf};
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ impl Prework {
|
|||
}
|
||||
|
||||
pub(crate) async fn size_do(&self, task: PreworkInSize) -> Result<(), PreworkOutSize> {
|
||||
let length = SizeCalculator::total(&task.target).await.unwrap_or(0);
|
||||
let length = provider::calculate(&task.target).await.unwrap_or(0);
|
||||
task.throttle.done((task.target, length), |buf| {
|
||||
{
|
||||
let mut loading = self.sizing.write();
|
||||
|
|
|
|||
|
|
@ -10,10 +10,13 @@ pub struct DirEntry<'a> {
|
|||
}
|
||||
|
||||
impl<'a> DirEntry<'a> {
|
||||
#[must_use]
|
||||
pub fn path(&self) -> PathBuf { self.dir.join(&self.name) }
|
||||
|
||||
#[must_use]
|
||||
pub fn name(&self) -> Cow<'_, OsStr> { self.name.to_os_str() }
|
||||
|
||||
#[must_use]
|
||||
pub fn long_name(&self) -> Cow<'_, OsStr> { self.long_name.to_os_str() }
|
||||
|
||||
pub fn attrs(&self) -> &Attrs { &self.attrs }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-shared"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -10,7 +10,7 @@ repository = "https://github.com/sxyazi/yazi"
|
|||
rust-version = "1.88.0"
|
||||
|
||||
[dependencies]
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-term"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,8 +9,8 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
|
||||
# Logging
|
||||
tracing = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-watcher"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,11 +9,11 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.6.11" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.6.11" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.9.15" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.9.15" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.9.15" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
|
||||
# Logging
|
||||
tracing = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-widgets"
|
||||
version = "25.6.11"
|
||||
version = "25.9.15"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,12 +9,12 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-binding = { path = "../yazi-binding", version = "25.6.11" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
yazi-term = { path = "../yazi-term", version = "25.6.11" }
|
||||
yazi-binding = { path = "../yazi-binding", version = "25.9.15" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.9.15" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.9.15" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||
yazi-term = { path = "../yazi-term", version = "25.9.15" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue