mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: new download/upload commands to cache/sync remote or local files to the peer (#3243)
This commit is contained in:
parent
c68e2df8c0
commit
e067a705ac
36 changed files with 407 additions and 264 deletions
238
Cargo.lock
generated
238
Cargo.lock
generated
|
|
@ -254,7 +254,7 @@ dependencies = [
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
"object",
|
"object",
|
||||||
"rustc-demangle",
|
"rustc-demangle",
|
||||||
"windows-link 0.2.0",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -459,9 +459,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.40"
|
version = "1.2.41"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb"
|
checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"find-msvc-tools",
|
"find-msvc-tools",
|
||||||
"jobserver",
|
"jobserver",
|
||||||
|
|
@ -512,7 +512,7 @@ dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-link 0.2.0",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1008,7 +1008,7 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"option-ext",
|
"option-ext",
|
||||||
"redox_users",
|
"redox_users",
|
||||||
"windows-sys 0.61.1",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1154,7 +1154,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.61.1",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1243,15 +1243,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "find-msvc-tools"
|
name = "find-msvc-tools"
|
||||||
version = "0.1.3"
|
version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3"
|
checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.1.2"
|
version = "1.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d"
|
checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
|
|
@ -1381,9 +1381,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
version = "0.14.7"
|
version = "0.14.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
"version_check",
|
"version_check",
|
||||||
|
|
@ -1467,12 +1467,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "half"
|
name = "half"
|
||||||
version = "2.6.0"
|
version = "2.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9"
|
checksum = "e54c115d4f30f52c67202f079c5f9d8b49db4691f460fdb0b4c2e838261b2ba5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"crunchy",
|
"crunchy",
|
||||||
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1561,7 +1562,7 @@ dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-core 0.62.1",
|
"windows-core 0.62.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1824,9 +1825,9 @@ checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.176"
|
version = "0.2.177"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174"
|
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libfuzzer-sys"
|
name = "libfuzzer-sys"
|
||||||
|
|
@ -2051,9 +2052,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "moxcms"
|
name = "moxcms"
|
||||||
version = "0.7.5"
|
version = "0.7.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ddd32fa8935aeadb8a8a6b6b351e40225570a37c43de67690383d87ef170cd08"
|
checksum = "c588e11a3082784af229e23e8e4ecf5bcc6fbe4f69101e0421ce8d79da7f0b40"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"pxfm",
|
"pxfm",
|
||||||
|
|
@ -2119,11 +2120,11 @@ checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-ansi-term"
|
name = "nu-ansi-term"
|
||||||
version = "0.50.1"
|
version = "0.50.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399"
|
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2242,9 +2243,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc2"
|
name = "objc2"
|
||||||
version = "0.6.2"
|
version = "0.6.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "561f357ba7f3a2a61563a186a163d0a3a5247e1089524a3981d49adb775078bc"
|
checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"objc2-encode",
|
"objc2-encode",
|
||||||
]
|
]
|
||||||
|
|
@ -2257,9 +2258,9 @@ checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc2-foundation"
|
name = "objc2-foundation"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c"
|
checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"objc2",
|
"objc2",
|
||||||
|
|
@ -2453,7 +2454,7 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows-link 0.2.0",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2679,9 +2680,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pxfm"
|
name = "pxfm"
|
||||||
version = "0.1.24"
|
version = "0.1.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "83f9b339b02259ada5c0f4a389b7fb472f933aa17ce176fd2ad98f28bb401fde"
|
checksum = "a3cbdf373972bf78df4d3b518d07003938e2c7d1fb5891e55f9cb6df57009d84"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
@ -2887,9 +2888,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.5.17"
|
version = "0.5.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
|
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
]
|
]
|
||||||
|
|
@ -2907,9 +2908,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.11.3"
|
version = "1.12.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c"
|
checksum = "4a52d8d02cacdb176ef4678de6c052efb4b3da14b78e4db683a4252762be5433"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
|
@ -2919,9 +2920,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-automata"
|
name = "regex-automata"
|
||||||
version = "0.4.11"
|
version = "0.4.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad"
|
checksum = "722166aa0d7438abbaa4d5cc2c649dac844e8c56d82fb3d33e9c34b5cd268fc6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
|
@ -2930,9 +2931,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.8.6"
|
version = "0.8.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001"
|
checksum = "c3160422bbd54dd5ecfdca71e5fd59b7b8fe2b1697ab2baf64f6d05dcc66d298"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rfc6979"
|
name = "rfc6979"
|
||||||
|
|
@ -2987,9 +2988,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "russh"
|
name = "russh"
|
||||||
version = "0.54.4"
|
version = "0.54.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "54b1296a0e9d970321e59d77367b8d1511311445f3dd5d42f24e7d9a1706cf51"
|
checksum = "ca3ee9363fcf66d434d8015d9ae7d879681206981534c21bfdff8a7e34f52cca"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"base64ct",
|
"base64ct",
|
||||||
|
|
@ -3116,7 +3117,7 @@ dependencies = [
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys 0.11.0",
|
"linux-raw-sys 0.11.0",
|
||||||
"windows-sys 0.61.1",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3259,9 +3260,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_spanned"
|
name = "serde_spanned"
|
||||||
version = "1.0.2"
|
version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee"
|
checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
@ -3390,12 +3391,12 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
version = "0.6.0"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807"
|
checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.60.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3710,14 +3711,14 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.9.7"
|
version = "0.9.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0"
|
checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"serde_core",
|
"serde_core",
|
||||||
"serde_spanned 1.0.2",
|
"serde_spanned 1.0.3",
|
||||||
"toml_datetime 0.7.2",
|
"toml_datetime 0.7.3",
|
||||||
"toml_parser",
|
"toml_parser",
|
||||||
"toml_writer",
|
"toml_writer",
|
||||||
"winnow",
|
"winnow",
|
||||||
|
|
@ -3734,9 +3735,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_datetime"
|
name = "toml_datetime"
|
||||||
version = "0.7.2"
|
version = "0.7.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1"
|
checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
@ -3756,18 +3757,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_parser"
|
name = "toml_parser"
|
||||||
version = "1.0.3"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627"
|
checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winnow",
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_writer"
|
name = "toml_writer"
|
||||||
version = "1.0.3"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109"
|
checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
|
|
@ -4188,7 +4189,7 @@ version = "0.1.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.61.1",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -4214,7 +4215,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f919aee0a93304be7f62e8e5027811bbba96bcb1de84d6618be56e43f8a32a1"
|
checksum = "7f919aee0a93304be7f62e8e5027811bbba96bcb1de84d6618be56e43f8a32a1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-core 0.59.0",
|
"windows-core 0.59.0",
|
||||||
"windows-targets 0.53.4",
|
"windows-targets 0.53.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -4236,23 +4237,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "810ce18ed2112484b0d4e15d022e5f598113e220c53e373fb31e67e21670c1ce"
|
checksum = "810ce18ed2112484b0d4e15d022e5f598113e220c53e373fb31e67e21670c1ce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-implement 0.59.0",
|
"windows-implement 0.59.0",
|
||||||
"windows-interface 0.59.2",
|
"windows-interface 0.59.3",
|
||||||
"windows-result 0.3.4",
|
"windows-result 0.3.4",
|
||||||
"windows-strings 0.3.1",
|
"windows-strings 0.3.1",
|
||||||
"windows-targets 0.53.4",
|
"windows-targets 0.53.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-core"
|
name = "windows-core"
|
||||||
version = "0.62.1"
|
version = "0.62.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6844ee5416b285084d3d3fffd743b925a6c9385455f64f6d4fa3031c4c2749a9"
|
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-implement 0.60.1",
|
"windows-implement 0.60.2",
|
||||||
"windows-interface 0.59.2",
|
"windows-interface 0.59.3",
|
||||||
"windows-link 0.2.0",
|
"windows-link 0.2.1",
|
||||||
"windows-result 0.4.0",
|
"windows-result 0.4.1",
|
||||||
"windows-strings 0.5.0",
|
"windows-strings 0.5.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -4279,9 +4280,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-implement"
|
name = "windows-implement"
|
||||||
version = "0.60.1"
|
version = "0.60.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "edb307e42a74fb6de9bf3a02d9712678b22399c87e6fa869d6dfcd8c1b7754e0"
|
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -4301,9 +4302,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-interface"
|
name = "windows-interface"
|
||||||
version = "0.59.2"
|
version = "0.59.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0abd1ddbc6964ac14db11c7213d6532ef34bd9aa042c2e5935f59d7908b46a5"
|
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -4318,9 +4319,9 @@ checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-link"
|
name = "windows-link"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
|
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-result"
|
name = "windows-result"
|
||||||
|
|
@ -4342,11 +4343,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-result"
|
name = "windows-result"
|
||||||
version = "0.4.0"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f"
|
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link 0.2.0",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -4360,11 +4361,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-strings"
|
name = "windows-strings"
|
||||||
version = "0.5.0"
|
version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda"
|
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link 0.2.0",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -4391,16 +4392,16 @@ version = "0.60.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
|
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets 0.53.4",
|
"windows-targets 0.53.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.61.1"
|
version = "0.61.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f"
|
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link 0.2.0",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -4421,19 +4422,19 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-targets"
|
name = "windows-targets"
|
||||||
version = "0.53.4"
|
version = "0.53.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2d42b7b7f66d2a06854650af09cfdf8713e427a439c97ad65a6375318033ac4b"
|
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link 0.2.0",
|
"windows-link 0.2.1",
|
||||||
"windows_aarch64_gnullvm 0.53.0",
|
"windows_aarch64_gnullvm 0.53.1",
|
||||||
"windows_aarch64_msvc 0.53.0",
|
"windows_aarch64_msvc 0.53.1",
|
||||||
"windows_i686_gnu 0.53.0",
|
"windows_i686_gnu 0.53.1",
|
||||||
"windows_i686_gnullvm 0.53.0",
|
"windows_i686_gnullvm 0.53.1",
|
||||||
"windows_i686_msvc 0.53.0",
|
"windows_i686_msvc 0.53.1",
|
||||||
"windows_x86_64_gnu 0.53.0",
|
"windows_x86_64_gnu 0.53.1",
|
||||||
"windows_x86_64_gnullvm 0.53.0",
|
"windows_x86_64_gnullvm 0.53.1",
|
||||||
"windows_x86_64_msvc 0.53.0",
|
"windows_x86_64_msvc 0.53.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -4444,9 +4445,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_gnullvm"
|
name = "windows_aarch64_gnullvm"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
|
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
|
|
@ -4456,9 +4457,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
|
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
|
|
@ -4468,9 +4469,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
|
checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnullvm"
|
name = "windows_i686_gnullvm"
|
||||||
|
|
@ -4480,9 +4481,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnullvm"
|
name = "windows_i686_gnullvm"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
|
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
|
|
@ -4492,9 +4493,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
|
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
|
|
@ -4504,9 +4505,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
|
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
|
|
@ -4516,9 +4517,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
|
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
|
|
@ -4528,9 +4529,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
|
|
@ -4678,7 +4679,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
"toml 0.9.7",
|
"toml 0.9.8",
|
||||||
"twox-hash",
|
"twox-hash",
|
||||||
"vergen-gitcl",
|
"vergen-gitcl",
|
||||||
"yazi-boot",
|
"yazi-boot",
|
||||||
|
|
@ -4711,7 +4712,7 @@ dependencies = [
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
"tokio",
|
"tokio",
|
||||||
"toml 0.9.7",
|
"toml 0.9.8",
|
||||||
"tracing",
|
"tracing",
|
||||||
"yazi-codegen",
|
"yazi-codegen",
|
||||||
"yazi-fs",
|
"yazi-fs",
|
||||||
|
|
@ -4792,7 +4793,6 @@ name = "yazi-fm"
|
||||||
version = "25.9.15"
|
version = "25.9.15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
|
||||||
"better-panic",
|
"better-panic",
|
||||||
"crossterm 0.29.0",
|
"crossterm 0.29.0",
|
||||||
"fdlimit",
|
"fdlimit",
|
||||||
|
|
@ -4834,7 +4834,6 @@ version = "25.9.15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"base64",
|
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
"dirs",
|
"dirs",
|
||||||
|
|
@ -4850,9 +4849,8 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"trash",
|
"trash",
|
||||||
"twox-hash",
|
|
||||||
"uzers",
|
"uzers",
|
||||||
"windows-sys 0.61.1",
|
"windows-sys 0.61.2",
|
||||||
"yazi-ffi",
|
"yazi-ffi",
|
||||||
"yazi-macro",
|
"yazi-macro",
|
||||||
"yazi-shared",
|
"yazi-shared",
|
||||||
|
|
@ -4909,7 +4907,7 @@ dependencies = [
|
||||||
"twox-hash",
|
"twox-hash",
|
||||||
"unicode-width 0.2.0",
|
"unicode-width 0.2.0",
|
||||||
"uzers",
|
"uzers",
|
||||||
"windows-sys 0.61.1",
|
"windows-sys 0.61.2",
|
||||||
"yazi-adapter",
|
"yazi-adapter",
|
||||||
"yazi-binding",
|
"yazi-binding",
|
||||||
"yazi-boot",
|
"yazi-boot",
|
||||||
|
|
@ -5002,7 +5000,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"tokio",
|
"tokio",
|
||||||
"uzers",
|
"uzers",
|
||||||
"windows-sys 0.61.1",
|
"windows-sys 0.61.2",
|
||||||
"yazi-macro",
|
"yazi-macro",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -5022,7 +5020,7 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.61.1",
|
"windows-sys 0.61.2",
|
||||||
"yazi-macro",
|
"yazi-macro",
|
||||||
"yazi-shared",
|
"yazi-shared",
|
||||||
]
|
]
|
||||||
|
|
@ -5039,7 +5037,6 @@ dependencies = [
|
||||||
"russh",
|
"russh",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"uzers",
|
|
||||||
"yazi-config",
|
"yazi-config",
|
||||||
"yazi-fs",
|
"yazi-fs",
|
||||||
"yazi-macro",
|
"yazi-macro",
|
||||||
|
|
@ -5052,7 +5049,6 @@ name = "yazi-watcher"
|
||||||
version = "25.9.15"
|
version = "25.9.15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
|
||||||
"hashbrown 0.16.0",
|
"hashbrown 0.16.0",
|
||||||
"notify",
|
"notify",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
|
|
@ -5060,11 +5056,11 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"tracing",
|
"tracing",
|
||||||
"twox-hash",
|
|
||||||
"yazi-adapter",
|
"yazi-adapter",
|
||||||
"yazi-dds",
|
"yazi-dds",
|
||||||
"yazi-fs",
|
"yazi-fs",
|
||||||
"yazi-macro",
|
"yazi-macro",
|
||||||
|
"yazi-proxy",
|
||||||
"yazi-shared",
|
"yazi-shared",
|
||||||
"yazi-vfs",
|
"yazi-vfs",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ futures = "0.3.31"
|
||||||
globset = "0.4.16"
|
globset = "0.4.16"
|
||||||
hashbrown = { version = "0.16.0", features = [ "serde" ] }
|
hashbrown = { version = "0.16.0", features = [ "serde" ] }
|
||||||
indexmap = { version = "2.11.4", features = [ "serde" ] }
|
indexmap = { version = "2.11.4", features = [ "serde" ] }
|
||||||
libc = "0.2.176"
|
libc = "0.2.177"
|
||||||
lru = "0.16.1"
|
lru = "0.16.1"
|
||||||
mlua = { version = "0.11.4", features = [ "anyhow", "async", "error-send", "lua54", "macros", "serde" ] }
|
mlua = { version = "0.11.4", features = [ "anyhow", "async", "error-send", "lua54", "macros", "serde" ] }
|
||||||
objc = "0.2.7"
|
objc = "0.2.7"
|
||||||
|
|
@ -42,8 +42,8 @@ parking_lot = "0.12.5"
|
||||||
paste = "1.0.15"
|
paste = "1.0.15"
|
||||||
percent-encoding = "2.3.2"
|
percent-encoding = "2.3.2"
|
||||||
ratatui = { version = "0.29.0", features = [ "unstable-rendered-line-info", "unstable-widget-ref" ] }
|
ratatui = { version = "0.29.0", features = [ "unstable-rendered-line-info", "unstable-widget-ref" ] }
|
||||||
regex = "1.11.3"
|
regex = "1.12.1"
|
||||||
russh = { version = "0.54.4", default-features = false, features = [ "ring", "rsa" ] }
|
russh = { version = "0.54.5", default-features = false, features = [ "ring", "rsa" ] }
|
||||||
scopeguard = "1.2.0"
|
scopeguard = "1.2.0"
|
||||||
serde = { version = "1.0.228", features = [ "derive" ] }
|
serde = { version = "1.0.228", features = [ "derive" ] }
|
||||||
serde_json = "1.0.145"
|
serde_json = "1.0.145"
|
||||||
|
|
@ -51,7 +51,7 @@ syntect = { version = "5.3.0", default-features = false, features =
|
||||||
tokio = { version = "1.47.1", features = [ "full" ] }
|
tokio = { version = "1.47.1", features = [ "full" ] }
|
||||||
tokio-stream = "0.1.17"
|
tokio-stream = "0.1.17"
|
||||||
tokio-util = "0.7.16"
|
tokio-util = "0.7.16"
|
||||||
toml = { version = "0.9.7" }
|
toml = { version = "0.9.8" }
|
||||||
tracing = { version = "0.1.41", features = [ "max_level_debug", "release_max_level_debug" ] }
|
tracing = { version = "0.1.41", features = [ "max_level_debug", "release_max_level_debug" ] }
|
||||||
twox-hash = { version = "2.1.2", default-features = false, features = [ "std", "random", "xxhash3_128" ] }
|
twox-hash = { version = "2.1.2", default-features = false, features = [ "std", "random", "xxhash3_128" ] }
|
||||||
unicode-width = { version = "0.2.0", default-features = false }
|
unicode-width = { version = "0.2.0", default-features = false }
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{ffi::{OsStr, OsString}, hash::Hash, io::{Read, Write}, ops::Deref};
|
use std::{ffi::{OsStr, OsString}, hash::Hash, io::{Read, Write}, ops::Deref, path::Path};
|
||||||
|
|
||||||
use anyhow::{Result, anyhow};
|
use anyhow::{Result, anyhow};
|
||||||
use crossterm::{execute, style::Print};
|
use crossterm::{execute, style::Print};
|
||||||
|
|
@ -11,7 +11,7 @@ use yazi_fs::{File, FilesOp, Splatter, max_common_root, path::skip_url, provider
|
||||||
use yazi_macro::{err, succ};
|
use yazi_macro::{err, succ};
|
||||||
use yazi_parser::VoidOpt;
|
use yazi_parser::VoidOpt;
|
||||||
use yazi_proxy::{AppProxy, HIDER, TasksProxy};
|
use yazi_proxy::{AppProxy, HIDER, TasksProxy};
|
||||||
use yazi_shared::{OsStrJoin, data::Data, terminal_clear, url::{Component, Url, UrlBuf, UrlCow, UrlLike}};
|
use yazi_shared::{OsStrJoin, data::Data, terminal_clear, url::{AsUrl, Component, UrlBuf, UrlCow, UrlLike}};
|
||||||
use yazi_term::tty::TTY;
|
use yazi_term::tty::TTY;
|
||||||
use yazi_vfs::{VfsFile, maybe_exists, provider};
|
use yazi_vfs::{VfsFile, maybe_exists, provider};
|
||||||
use yazi_watcher::WATCHER;
|
use yazi_watcher::WATCHER;
|
||||||
|
|
@ -53,7 +53,7 @@ impl Actor for BulkRename {
|
||||||
defer! { tokio::spawn(Local.remove_file(tmp.clone())); }
|
defer! { tokio::spawn(Local.remove_file(tmp.clone())); }
|
||||||
TasksProxy::process_exec(
|
TasksProxy::process_exec(
|
||||||
cwd,
|
cwd,
|
||||||
Splatter::new(&[UrlCow::default(), Url::regular(&tmp).into()]).splat(&opener.run),
|
Splatter::new(&[UrlCow::default(), tmp.as_url().into()]).splat(&opener.run),
|
||||||
vec![UrlCow::default(), UrlBuf::from(&tmp).into()],
|
vec![UrlCow::default(), UrlBuf::from(&tmp).into()],
|
||||||
opener.block,
|
opener.block,
|
||||||
opener.orphan,
|
opener.orphan,
|
||||||
|
|
@ -150,7 +150,7 @@ impl BulkRename {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn opener() -> Option<&'static OpenerRule> {
|
fn opener() -> Option<&'static OpenerRule> {
|
||||||
YAZI.opener.block(YAZI.open.all(Url::regular("bulk-rename.txt"), "text/plain"))
|
YAZI.opener.block(YAZI.open.all(Path::new("bulk-rename.txt"), "text/plain"))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn output_failed(failed: Vec<(Tuple, Tuple, anyhow::Error)>) -> Result<()> {
|
async fn output_failed(failed: Vec<(Tuple, Tuple, anyhow::Error)>) -> Result<()> {
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ yazi_macro::mod_flat!(
|
||||||
update_peeked
|
update_peeked
|
||||||
update_spotted
|
update_spotted
|
||||||
update_yanked
|
update_yanked
|
||||||
|
upload
|
||||||
visual_mode
|
visual_mode
|
||||||
watch
|
watch
|
||||||
yank
|
yank
|
||||||
|
|
|
||||||
21
yazi-actor/src/mgr/upload.rs
Normal file
21
yazi-actor/src/mgr/upload.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
use anyhow::Result;
|
||||||
|
use yazi_macro::succ;
|
||||||
|
use yazi_parser::mgr::UploadOpt;
|
||||||
|
use yazi_shared::data::Data;
|
||||||
|
|
||||||
|
use crate::{Actor, Ctx};
|
||||||
|
|
||||||
|
pub struct Upload;
|
||||||
|
|
||||||
|
impl Actor for Upload {
|
||||||
|
type Options = UploadOpt;
|
||||||
|
|
||||||
|
const NAME: &str = "upload";
|
||||||
|
|
||||||
|
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
|
||||||
|
for url in opt.urls {
|
||||||
|
cx.tasks.scheduler.file_upload(url.into_owned());
|
||||||
|
}
|
||||||
|
succ!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -41,12 +41,6 @@ impl From<Url> for yazi_shared::url::UrlBuf {
|
||||||
fn from(value: Url) -> Self { value.inner }
|
fn from(value: Url) -> Self { value.inner }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a Url> for UrlCow<'a> {
|
|
||||||
fn from(value: &'a Url) -> Self {
|
|
||||||
UrlCow::Borrowed { loc: value.loc.as_loc(), scheme: value.scheme.as_ref().into() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Url> for yazi_shared::url::UrlBufCov {
|
impl From<Url> for yazi_shared::url::UrlBufCov {
|
||||||
fn from(value: Url) -> Self { Self(value.inner) }
|
fn from(value: Url) -> Self { Self(value.inner) }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
use std::{env, ffi::OsStr, fmt::Write};
|
use std::{env, ffi::OsStr, fmt::Write, path::Path};
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use yazi_adapter::Mux;
|
use yazi_adapter::Mux;
|
||||||
use yazi_config::YAZI;
|
use yazi_config::YAZI;
|
||||||
use yazi_shared::{timestamp_us, url::Url};
|
use yazi_shared::timestamp_us;
|
||||||
|
|
||||||
use super::Actions;
|
use super::Actions;
|
||||||
|
|
||||||
|
|
@ -59,17 +59,17 @@ impl Actions {
|
||||||
writeln!(
|
writeln!(
|
||||||
s,
|
s,
|
||||||
" default : {:?}",
|
" default : {:?}",
|
||||||
YAZI.opener.first(YAZI.open.all(Url::regular("f75a.txt"), "text/plain"))
|
YAZI.opener.first(YAZI.open.all(Path::new("f75a.txt"), "text/plain"))
|
||||||
)?;
|
)?;
|
||||||
writeln!(
|
writeln!(
|
||||||
s,
|
s,
|
||||||
" block-create: {:?}",
|
" block-create: {:?}",
|
||||||
YAZI.opener.block(YAZI.open.all(Url::regular("bulk-create.txt"), "text/plain"))
|
YAZI.opener.block(YAZI.open.all(Path::new("bulk-create.txt"), "text/plain"))
|
||||||
)?;
|
)?;
|
||||||
writeln!(
|
writeln!(
|
||||||
s,
|
s,
|
||||||
" block-rename: {:?}",
|
" block-rename: {:?}",
|
||||||
YAZI.opener.block(YAZI.open.all(Url::regular("bulk-rename.txt"), "text/plain"))
|
YAZI.opener.block(YAZI.open.all(Path::new("bulk-rename.txt"), "text/plain"))
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
writeln!(s, "\nMultiplexers")?;
|
writeln!(s, "\nMultiplexers")?;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use anyhow::{Context, Result, bail};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use yazi_codegen::DeserializeOver2;
|
use yazi_codegen::DeserializeOver2;
|
||||||
use yazi_fs::{Xdg, path::expand_url};
|
use yazi_fs::{Xdg, path::expand_url};
|
||||||
use yazi_shared::{SStr, timestamp_us, url::Url};
|
use yazi_shared::{SStr, timestamp_us};
|
||||||
|
|
||||||
use super::PreviewWrap;
|
use super::PreviewWrap;
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ impl Preview {
|
||||||
|
|
||||||
self.cache_dir = if self.cache_dir.as_os_str().is_empty() {
|
self.cache_dir = if self.cache_dir.as_os_str().is_empty() {
|
||||||
Xdg::cache_dir().to_owned()
|
Xdg::cache_dir().to_owned()
|
||||||
} else if let Some(p) = expand_url(Url::regular(&self.cache_dir)).into_path() {
|
} else if let Some(p) = expand_url(self.cache_dir).into_path() {
|
||||||
p
|
p
|
||||||
} else {
|
} else {
|
||||||
bail!("[preview].cache_dir must be a path within local filesystem.");
|
bail!("[preview].cache_dir must be a path within local filesystem.");
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ use std::{io, path::PathBuf};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use yazi_fs::path::expand_url;
|
use yazi_fs::path::expand_url;
|
||||||
use yazi_shared::url::Url;
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
#[serde(tag = "type", rename_all = "kebab-case")]
|
#[serde(tag = "type", rename_all = "kebab-case")]
|
||||||
|
|
@ -45,7 +44,7 @@ pub struct ProviderSftp {
|
||||||
impl ProviderSftp {
|
impl ProviderSftp {
|
||||||
fn reshape(&mut self) -> io::Result<()> {
|
fn reshape(&mut self) -> io::Result<()> {
|
||||||
if !self.key_file.as_os_str().is_empty() {
|
if !self.key_file.as_os_str().is_empty() {
|
||||||
self.key_file = expand_url(Url::regular(&self.key_file))
|
self.key_file = expand_url(&self.key_file)
|
||||||
.into_path()
|
.into_path()
|
||||||
.ok_or_else(|| io::Error::other("key_file must be a path within local filesystem"))?;
|
.ok_or_else(|| io::Error::other("key_file must be a path within local filesystem"))?;
|
||||||
}
|
}
|
||||||
|
|
@ -56,7 +55,7 @@ impl ProviderSftp {
|
||||||
.filter(|p| p.is_absolute())
|
.filter(|p| p.is_absolute())
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
} else {
|
} else {
|
||||||
expand_url(Url::regular(&self.identity_agent))
|
expand_url(&self.identity_agent)
|
||||||
.into_path()
|
.into_path()
|
||||||
.ok_or_else(|| io::Error::other("identity_agent must be a path within local filesystem"))?
|
.ok_or_else(|| io::Error::other("identity_agent must be a path within local filesystem"))?
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ pub enum Spark<'a> {
|
||||||
UpdatePeeked(yazi_parser::mgr::UpdatePeekedOpt),
|
UpdatePeeked(yazi_parser::mgr::UpdatePeekedOpt),
|
||||||
UpdateSpotted(yazi_parser::mgr::UpdateSpottedOpt),
|
UpdateSpotted(yazi_parser::mgr::UpdateSpottedOpt),
|
||||||
UpdateYanked(yazi_parser::mgr::UpdateYankedOpt<'a>),
|
UpdateYanked(yazi_parser::mgr::UpdateYankedOpt<'a>),
|
||||||
|
Upload(yazi_parser::mgr::UploadOpt),
|
||||||
VisualMode(yazi_parser::mgr::VisualModeOpt),
|
VisualMode(yazi_parser::mgr::VisualModeOpt),
|
||||||
Watch(yazi_parser::VoidOpt),
|
Watch(yazi_parser::VoidOpt),
|
||||||
Yank(yazi_parser::mgr::YankOpt),
|
Yank(yazi_parser::mgr::YankOpt),
|
||||||
|
|
@ -189,6 +190,7 @@ impl<'a> IntoLua for Spark<'a> {
|
||||||
Self::UpdatePeeked(b) => b.into_lua(lua),
|
Self::UpdatePeeked(b) => b.into_lua(lua),
|
||||||
Self::UpdateSpotted(b) => b.into_lua(lua),
|
Self::UpdateSpotted(b) => b.into_lua(lua),
|
||||||
Self::UpdateYanked(b) => b.into_lua(lua),
|
Self::UpdateYanked(b) => b.into_lua(lua),
|
||||||
|
Self::Upload(b) => b.into_lua(lua),
|
||||||
Self::VisualMode(b) => b.into_lua(lua),
|
Self::VisualMode(b) => b.into_lua(lua),
|
||||||
Self::Watch(b) => b.into_lua(lua),
|
Self::Watch(b) => b.into_lua(lua),
|
||||||
Self::Yank(b) => b.into_lua(lua),
|
Self::Yank(b) => b.into_lua(lua),
|
||||||
|
|
@ -315,6 +317,7 @@ try_from_spark!(mgr::UpdatePagedOpt, mgr:update_paged);
|
||||||
try_from_spark!(mgr::UpdatePeekedOpt, mgr:update_peeked);
|
try_from_spark!(mgr::UpdatePeekedOpt, mgr:update_peeked);
|
||||||
try_from_spark!(mgr::UpdateSpottedOpt, mgr:update_spotted);
|
try_from_spark!(mgr::UpdateSpottedOpt, mgr:update_spotted);
|
||||||
try_from_spark!(mgr::UpdateYankedOpt<'a>, mgr:update_yanked);
|
try_from_spark!(mgr::UpdateYankedOpt<'a>, mgr:update_yanked);
|
||||||
|
try_from_spark!(mgr::UploadOpt, mgr:upload);
|
||||||
try_from_spark!(mgr::VisualModeOpt, mgr:visual_mode);
|
try_from_spark!(mgr::VisualModeOpt, mgr:visual_mode);
|
||||||
try_from_spark!(mgr::YankOpt, mgr:yank);
|
try_from_spark!(mgr::YankOpt, mgr:yank);
|
||||||
try_from_spark!(notify::TickOpt, notify:tick);
|
try_from_spark!(notify::TickOpt, notify:tick);
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ yazi-watcher = { path = "../yazi-watcher", version = "25.9.15" }
|
||||||
yazi-widgets = { path = "../yazi-widgets", version = "25.9.15" }
|
yazi-widgets = { path = "../yazi-widgets", version = "25.9.15" }
|
||||||
|
|
||||||
# External dependencies
|
# External dependencies
|
||||||
base64 = { workspace = true }
|
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
better-panic = "0.3.0"
|
better-panic = "0.3.0"
|
||||||
crossterm = { workspace = true }
|
crossterm = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,7 @@ impl<'a> Executor<'a> {
|
||||||
|
|
||||||
// VFS
|
// VFS
|
||||||
on!(download);
|
on!(download);
|
||||||
|
on!(upload);
|
||||||
|
|
||||||
match cmd.name.as_ref() {
|
match cmd.name.as_ref() {
|
||||||
// Help
|
// Help
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ yazi-shim = { path = "../yazi-shim", version = "25.9.15" }
|
||||||
# External dependencies
|
# External dependencies
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
arc-swap = "1.7.1"
|
arc-swap = "1.7.1"
|
||||||
base64 = { workspace = true }
|
|
||||||
bitflags = { workspace = true }
|
bitflags = { workspace = true }
|
||||||
dirs = { workspace = true }
|
dirs = { workspace = true }
|
||||||
foldhash = { workspace = true }
|
foldhash = { workspace = true }
|
||||||
|
|
@ -29,14 +28,13 @@ scopeguard = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
tokio = { workspace = true }
|
tokio = { workspace = true }
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
twox-hash = { workspace = true }
|
|
||||||
|
|
||||||
[target."cfg(unix)".dependencies]
|
[target."cfg(unix)".dependencies]
|
||||||
libc = { workspace = true }
|
libc = { workspace = true }
|
||||||
uzers = { workspace = true }
|
uzers = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
windows-sys = { version = "0.61.1", features = [ "Win32_Storage_FileSystem" ] }
|
windows-sys = { version = "0.61.2", features = [ "Win32_Storage_FileSystem" ] }
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
core-foundation-sys = { workspace = true }
|
core-foundation-sys = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ impl Hash for File {
|
||||||
self.url.hash(state);
|
self.url.hash(state);
|
||||||
self.cha.len.hash(state);
|
self.cha.len.hash(state);
|
||||||
self.cha.btime.hash(state);
|
self.cha.btime.hash(state);
|
||||||
|
self.cha.ctime.hash(state);
|
||||||
self.cha.mtime.hash(state);
|
self.cha.mtime.hash(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
use std::{borrow::Cow, path::{Path, PathBuf}};
|
use std::{borrow::Cow, path::{Path, PathBuf}};
|
||||||
|
|
||||||
use anyhow::{Result, bail};
|
use anyhow::{Result, bail};
|
||||||
use yazi_shared::{loc::LocBuf, url::{Url, UrlBuf, UrlCow, UrlLike}};
|
use yazi_shared::{loc::LocBuf, url::{UrlBuf, UrlCow, UrlLike}};
|
||||||
|
|
||||||
pub fn path_relative_to<'a>(
|
pub fn path_relative_to<'a>(
|
||||||
from: impl AsRef<Path>,
|
from: impl AsRef<Path>,
|
||||||
to: &'a impl AsRef<Path>,
|
to: &'a impl AsRef<Path>,
|
||||||
) -> Result<Cow<'a, Path>> {
|
) -> Result<Cow<'a, Path>> {
|
||||||
Ok(match url_relative_to(Url::regular(&from).into(), Url::regular(to).into())? {
|
Ok(match url_relative_to(from.as_ref().into(), to.as_ref().into())? {
|
||||||
UrlCow::Borrowed { loc, .. } => Cow::Borrowed(loc.as_path()),
|
UrlCow::Borrowed { loc, .. } => Cow::Borrowed(loc.as_path()),
|
||||||
UrlCow::Owned { loc, .. } => Cow::Owned(loc.into_path()),
|
UrlCow::Owned { loc, .. } => Cow::Owned(loc.into_path()),
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ yazi_macro::mod_flat!(
|
||||||
update_peeked
|
update_peeked
|
||||||
update_spotted
|
update_spotted
|
||||||
update_yanked
|
update_yanked
|
||||||
|
upload
|
||||||
visual_mode
|
visual_mode
|
||||||
yank
|
yank
|
||||||
);
|
);
|
||||||
|
|
|
||||||
19
yazi-parser/src/mgr/upload.rs
Normal file
19
yazi-parser/src/mgr/upload.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
use mlua::{ExternalError, FromLua, IntoLua, Lua, Value};
|
||||||
|
use yazi_shared::{event::CmdCow, url::UrlCow};
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct UploadOpt {
|
||||||
|
pub urls: Vec<UrlCow<'static>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<CmdCow> for UploadOpt {
|
||||||
|
fn from(mut c: CmdCow) -> Self { Self { urls: c.take_seq() } }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromLua for UploadOpt {
|
||||||
|
fn from_lua(_: Value, _: &Lua) -> mlua::Result<Self> { Err("unsupported".into_lua_err()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoLua for UploadOpt {
|
||||||
|
fn into_lua(self, _: &Lua) -> mlua::Result<Value> { Err("unsupported".into_lua_err()) }
|
||||||
|
}
|
||||||
|
|
@ -51,7 +51,7 @@ libc = { workspace = true }
|
||||||
uzers = { workspace = true }
|
uzers = { workspace = true }
|
||||||
|
|
||||||
[target."cfg(windows)".dependencies]
|
[target."cfg(windows)".dependencies]
|
||||||
windows-sys = { version = "0.61.1", features = [ "Win32_System_JobObjects" ] }
|
windows-sys = { version = "0.61.2", features = [ "Win32_System_JobObjects" ] }
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
crossterm = { workspace = true, features = [ "use-dev-tty", "libc" ] }
|
crossterm = { workspace = true, features = [ "use-dev-tty", "libc" ] }
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@ local M = {}
|
||||||
|
|
||||||
function M:peek(job)
|
function M:peek(job)
|
||||||
local cmd = os.getenv("YAZI_FILE_ONE") or "file"
|
local cmd = os.getenv("YAZI_FILE_ONE") or "file"
|
||||||
local output, err = Command(cmd):arg({ "-bL", "--", tostring(job.file.url) }):stdout(Command.PIPED):output()
|
local path = tostring(job.file.cache or job.file.url)
|
||||||
|
local output, err = Command(cmd):arg({ "-bL", "--", path }):stdout(Command.PIPED):output()
|
||||||
|
|
||||||
local text
|
local text
|
||||||
if output then
|
if output then
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,13 @@ impl MgrProxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_paged_by(page: usize, only_if: &UrlBuf) {
|
pub fn update_paged_by(page: usize, only_if: &UrlBuf) {
|
||||||
emit!(Call(relay!(mgr:update_paged, [page]).with_any("only-if", only_if.clone())));
|
emit!(Call(relay!(mgr:update_paged, [page]).with("only-if", only_if)));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn upload<I>(urls: I)
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = UrlBuf>,
|
||||||
|
{
|
||||||
|
emit!(Call(relay!(mgr:upload).with_seq(urls)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{borrow::Cow, collections::VecDeque, hash::{BuildHasher, Hash, Hasher}, path::{Path, PathBuf}};
|
use std::{borrow::Cow, collections::VecDeque, hash::{BuildHasher, Hash, Hasher}};
|
||||||
|
|
||||||
use anyhow::{Context, Result, anyhow};
|
use anyhow::{Context, Result, anyhow};
|
||||||
use tokio::{io::{self, ErrorKind::{AlreadyExists, NotFound}}, sync::mpsc};
|
use tokio::{io::{self, ErrorKind::{AlreadyExists, NotFound}}, sync::mpsc};
|
||||||
|
|
@ -6,11 +6,11 @@ use tracing::warn;
|
||||||
use yazi_config::YAZI;
|
use yazi_config::YAZI;
|
||||||
use yazi_fs::{FsHash128, FsUrl, cha::Cha, ok_or_not_found, path::{path_relative_to, skip_url}, provider::{DirReader, FileHolder, Provider, local::Local}};
|
use yazi_fs::{FsHash128, FsUrl, cha::Cha, ok_or_not_found, path::{path_relative_to, skip_url}, provider::{DirReader, FileHolder, Provider, local::Local}};
|
||||||
use yazi_macro::ok_or_not_found;
|
use yazi_macro::ok_or_not_found;
|
||||||
use yazi_shared::{timestamp_us, url::{AsUrl, Url, UrlCow, UrlLike}};
|
use yazi_shared::{timestamp_us, url::{AsUrl, UrlBuf, UrlCow, UrlLike}};
|
||||||
use yazi_vfs::{VfsCha, copy_with_progress, maybe_exists, provider::{self, DirEntry}, unique_name};
|
use yazi_vfs::{VfsCha, copy_with_progress, maybe_exists, provider::{self, DirEntry}, unique_name};
|
||||||
|
|
||||||
use super::{FileInDelete, FileInHardlink, FileInLink, FileInPaste, FileInTrash};
|
use super::{FileInDelete, FileInHardlink, FileInLink, FileInPaste, FileInTrash};
|
||||||
use crate::{LOW, NORMAL, TaskIn, TaskOp, TaskOps, file::{FileInDownload, FileInUpload, FileOutDelete, FileOutDeleteDo, FileOutDownload, FileOutDownloadDo, FileOutHardlink, FileOutHardlinkDo, FileOutLink, FileOutPaste, FileOutPasteDo, FileOutTrash, FileOutUpload, FileOutUploadDo}};
|
use crate::{LOW, NORMAL, TaskIn, TaskOp, TaskOps, file::{FileInDownload, FileInUpload, FileInUploadDo, FileOutDelete, FileOutDeleteDo, FileOutDownload, FileOutDownloadDo, FileOutHardlink, FileOutHardlinkDo, FileOutLink, FileOutPaste, FileOutPasteDo, FileOutTrash, FileOutUpload, FileOutUploadDo}};
|
||||||
|
|
||||||
pub(crate) struct File {
|
pub(crate) struct File {
|
||||||
ops: TaskOps,
|
ops: TaskOps,
|
||||||
|
|
@ -353,11 +353,11 @@ impl File {
|
||||||
let cache = task.url.cache().context("Cannot determine cache path")?;
|
let cache = task.url.cache().context("Cannot determine cache path")?;
|
||||||
let cache_tmp = Self::tmp(&cache).await?;
|
let cache_tmp = Self::tmp(&cache).await?;
|
||||||
|
|
||||||
let mut it = copy_with_progress(&task.url, Url::regular(&cache_tmp), cha);
|
let mut it = copy_with_progress(&task.url, &cache_tmp, cha);
|
||||||
while let Some(res) = it.recv().await {
|
while let Some(res) = it.recv().await {
|
||||||
match res {
|
match res {
|
||||||
Ok(0) => {
|
Ok(0) => {
|
||||||
Local.rename(&cache_tmp, &cache).await?;
|
provider::rename(&cache_tmp, &cache).await?;
|
||||||
|
|
||||||
let lock = task.url.cache_lock().context("Cannot determine cache lock")?;
|
let lock = task.url.cache_lock().context("Cannot determine cache lock")?;
|
||||||
Local.write(lock, format!("{:x}", cha.hash_u128())).await?;
|
Local.write(lock, format!("{:x}", cha.hash_u128())).await?;
|
||||||
|
|
@ -385,66 +385,98 @@ impl File {
|
||||||
Ok(self.ops.out(task.id, FileOutDownloadDo::Succ))
|
Ok(self.ops.out(task.id, FileOutDownloadDo::Succ))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn upload(&self, mut task: FileInUpload) -> Result<(), FileOutUpload> {
|
pub(crate) async fn upload(&self, task: FileInUpload) -> Result<(), FileOutUpload> {
|
||||||
todo!();
|
let cha = Self::cha(&task.url, true, None).await?;
|
||||||
// if task.cha.is_none() {
|
if cha.is_orphan() {
|
||||||
// task.cha = Some(Self::cha(Url::regular(&task.path), true, None).await?);
|
Err(io::Error::new(NotFound, "Source of symlink doesn't exist"))?;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// let cha = task.cha.unwrap();
|
if !cha.is_dir() {
|
||||||
// if cha.is_orphan() {
|
let cache = task.url.cache().context("Cannot determine cache path")?;
|
||||||
// Err(io::Error::new(NotFound, "Source of symlink doesn't exist"))?;
|
match Self::cha(&cache, true, None).await {
|
||||||
// }
|
Ok(c) if c.mtime == cha.mtime => {}
|
||||||
|
Ok(c) => {
|
||||||
|
self.ops.out(task.id, FileOutUpload::New(c.len));
|
||||||
|
self.queue(FileInUploadDo { id: task.id, url: task.url, cha, cache }, LOW);
|
||||||
|
}
|
||||||
|
Err(e) if e.kind() == NotFound => {}
|
||||||
|
Err(e) => Err(e)?,
|
||||||
|
};
|
||||||
|
return Ok(self.ops.out(task.id, FileOutUpload::Succ));
|
||||||
|
}
|
||||||
|
|
||||||
// if !cha.is_dir() {
|
macro_rules! continue_unless_ok {
|
||||||
// let id = task.id;
|
($result:expr) => {
|
||||||
// self.ops.out(id, FileOutUpload::New(cha.len));
|
match $result {
|
||||||
// self.queue(task, LOW);
|
Ok(v) => v,
|
||||||
// return Ok(self.ops.out(id, FileOutUpload::Succ));
|
Err(e) => {
|
||||||
// }
|
self.ops.out(task.id, FileOutUpload::Deform(e.to_string()));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// macro_rules! continue_unless_ok {
|
let mut dirs = VecDeque::from([task.url]);
|
||||||
// ($result:expr) => {
|
while let Some(src) = dirs.pop_front() {
|
||||||
// match $result {
|
let mut it = continue_unless_ok!(provider::read_dir(&src).await);
|
||||||
// Ok(v) => v,
|
while let Ok(Some(entry)) = it.next().await {
|
||||||
// Err(e) => {
|
let from = entry.url();
|
||||||
// self.ops.out(task.id, FileOutUpload::Deform(e.to_string()));
|
let cha = continue_unless_ok!(Self::cha(&from, true, Some(entry)).await);
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let mut dirs = VecDeque::from([task.path.clone()]);
|
if cha.is_orphan() {
|
||||||
// while let Some(src) = dirs.pop_front() {
|
continue_unless_ok!(Err("Source of symlink doesn't exist"));
|
||||||
// let cache = continue_unless_ok!(src.cache().ok_or("Cannot determine
|
} else if cha.is_dir() {
|
||||||
// cache path")); continue_unless_ok!(match
|
dirs.push_back(from);
|
||||||
// Local.create_dir(&cache).await { Err(e) if e.kind() != AlreadyExists
|
continue;
|
||||||
// => Err(e), _ => Ok(()),
|
}
|
||||||
// });
|
|
||||||
|
|
||||||
// let mut it = continue_unless_ok!(provider::read_dir(&src).await);
|
let cache = continue_unless_ok!(from.cache().ok_or("Cannot determine cache path"));
|
||||||
// while let Ok(Some(entry)) = it.next().await {
|
let cache_cha = continue_unless_ok!(match Self::cha(&cache, true, None).await {
|
||||||
// let from = entry.url();
|
Ok(c) if c.mtime == cha.mtime => continue,
|
||||||
// let cha = continue_unless_ok!(Self::cha(&from, true,
|
Ok(c) => Ok(c),
|
||||||
// Some(entry)).await);
|
Err(e) if e.kind() == NotFound => continue,
|
||||||
|
Err(e) => Err(e),
|
||||||
|
});
|
||||||
|
|
||||||
// if cha.is_orphan() {
|
self.ops.out(task.id, FileOutUpload::New(cache_cha.len));
|
||||||
// continue_unless_ok!(Err("Source of symlink doesn't exist"));
|
self.queue(FileInUploadDo { id: task.id, url: from, cha, cache }, LOW);
|
||||||
// } else if cha.is_dir() {
|
}
|
||||||
// dirs.push_back(from);
|
}
|
||||||
// } else {
|
|
||||||
// self.ops.out(task.id, FileOutUpload::New(cha.len));
|
|
||||||
// self.queue(task.spawn(from, cha), LOW);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Ok(self.ops.out(task.id, FileOutUpload::Succ))
|
Ok(self.ops.out(task.id, FileOutUpload::Succ))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn upload_do(&self, mut task: FileInUpload) -> Result<(), FileOutUploadDo> {
|
pub(crate) async fn upload_do(&self, task: FileInUploadDo) -> Result<(), FileOutUploadDo> {
|
||||||
todo!()
|
let lock = task.url.cache_lock().context("Cannot determine cache lock")?;
|
||||||
|
|
||||||
|
let hash = Local.read_to_string(&lock).await.context("Cannot read cache lock")?;
|
||||||
|
let hash = u128::from_str_radix(&hash, 16).context("Cannot parse hash from lock")?;
|
||||||
|
if hash != task.cha.hash_u128() {
|
||||||
|
Err(anyhow!("Remote file has changed since last download"))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let tmp = Self::tmp(&task.url).await?;
|
||||||
|
let mut it = copy_with_progress(&task.cache, &tmp, task.cha);
|
||||||
|
|
||||||
|
while let Some(res) = it.recv().await {
|
||||||
|
match res {
|
||||||
|
Ok(0) if hash != Self::cha(&task.url, true, None).await?.hash_u128() => {
|
||||||
|
Err(anyhow!("Remote file has changed during upload"))?
|
||||||
|
}
|
||||||
|
Ok(0) => {
|
||||||
|
provider::rename(&tmp, &task.url).await?;
|
||||||
|
|
||||||
|
let hash = format!("{:x}", Self::cha(&task.url, true, None).await?.hash_u128());
|
||||||
|
Local.write(lock, hash).await?;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Ok(n) => self.ops.out(task.id, FileOutUploadDo::Adv(n)),
|
||||||
|
Err(e) => Err(e)?,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(self.ops.out(task.id, FileOutUploadDo::Succ))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn cha<U>(url: U, follow: bool, entry: Option<DirEntry>) -> io::Result<Cha>
|
async fn cha<U>(url: U, follow: bool, entry: Option<DirEntry>) -> io::Result<Cha>
|
||||||
|
|
@ -459,17 +491,20 @@ impl File {
|
||||||
Ok(if follow { Cha::from_follow(url, cha).await } else { cha })
|
Ok(if follow { Cha::from_follow(url, cha).await } else { cha })
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn tmp(path: &Path) -> io::Result<PathBuf> {
|
async fn tmp<U>(url: U) -> io::Result<UrlBuf>
|
||||||
let Some(parent) = path.parent() else {
|
where
|
||||||
Err(io::Error::new(io::ErrorKind::InvalidInput, "Path has no parent"))?
|
U: AsUrl,
|
||||||
|
{
|
||||||
|
let url = url.as_url();
|
||||||
|
let Some(parent) = url.parent() else {
|
||||||
|
Err(io::Error::new(io::ErrorKind::InvalidInput, "Url has no parent"))?
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut h = foldhash::fast::FixedState::default().build_hasher();
|
let mut h = foldhash::fast::FixedState::default().build_hasher();
|
||||||
path.hash(&mut h);
|
url.hash(&mut h);
|
||||||
timestamp_us().hash(&mut h);
|
timestamp_us().hash(&mut h);
|
||||||
|
|
||||||
let u = parent.join(format!(".{:x}.%tmp", h.finish())).into();
|
unique_name(parent.join(format!(".{:x}.%tmp", h.finish())), async { false }).await
|
||||||
Ok(unique_name(u, async { false }).await?.into_path().expect("a path"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,13 +102,15 @@ impl FileInDownload {
|
||||||
// --- Upload
|
// --- Upload
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct FileInUpload {
|
pub(crate) struct FileInUpload {
|
||||||
pub(crate) id: Id,
|
pub(crate) id: Id,
|
||||||
pub(crate) path: PathBuf,
|
pub(crate) url: UrlBuf,
|
||||||
pub(crate) cha: Option<Cha>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileInUpload {
|
// --- UploadDo
|
||||||
pub(super) fn spawn(&self, path: PathBuf, cha: Cha) -> Self {
|
#[derive(Clone, Debug)]
|
||||||
Self { id: self.id, path, cha: Some(cha) }
|
pub(crate) struct FileInUploadDo {
|
||||||
}
|
pub(crate) id: Id,
|
||||||
|
pub(crate) url: UrlBuf,
|
||||||
|
pub(crate) cha: Cha,
|
||||||
|
pub(crate) cache: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -354,6 +354,10 @@ impl From<std::io::Error> for FileOutUpload {
|
||||||
fn from(value: std::io::Error) -> Self { Self::Fail(value.to_string()) }
|
fn from(value: std::io::Error) -> Self { Self::Fail(value.to_string()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<anyhow::Error> for FileOutUpload {
|
||||||
|
fn from(value: anyhow::Error) -> Self { Self::Fail(value.to_string()) }
|
||||||
|
}
|
||||||
|
|
||||||
impl FileOutUpload {
|
impl FileOutUpload {
|
||||||
pub(crate) fn reduce(self, task: &mut Task) {
|
pub(crate) fn reduce(self, task: &mut Task) {
|
||||||
let TaskProg::FileUpload(prog) = &mut task.prog else { return };
|
let TaskProg::FileUpload(prog) = &mut task.prog else { return };
|
||||||
|
|
@ -382,7 +386,6 @@ impl FileOutUpload {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum FileOutUploadDo {
|
pub(crate) enum FileOutUploadDo {
|
||||||
Adv(u64),
|
Adv(u64),
|
||||||
Log(String),
|
|
||||||
Succ,
|
Succ,
|
||||||
Fail(String),
|
Fail(String),
|
||||||
}
|
}
|
||||||
|
|
@ -402,9 +405,6 @@ impl FileOutUploadDo {
|
||||||
Self::Adv(size) => {
|
Self::Adv(size) => {
|
||||||
prog.processed_bytes += size;
|
prog.processed_bytes += size;
|
||||||
}
|
}
|
||||||
Self::Log(line) => {
|
|
||||||
task.log(line);
|
|
||||||
}
|
|
||||||
Self::Succ => {
|
Self::Succ => {
|
||||||
prog.success_files += 1;
|
prog.success_files += 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use yazi_shared::Id;
|
use yazi_shared::Id;
|
||||||
|
|
||||||
use crate::{file::{FileInDelete, FileInDownload, FileInHardlink, FileInLink, FileInPaste, FileInTrash, FileInUpload}, impl_from_in, plugin::PluginInEntry, prework::{PreworkInFetch, PreworkInLoad, PreworkInSize}};
|
use crate::{file::{FileInDelete, FileInDownload, FileInHardlink, FileInLink, FileInPaste, FileInTrash, FileInUpload, FileInUploadDo}, impl_from_in, plugin::PluginInEntry, prework::{PreworkInFetch, PreworkInLoad, PreworkInSize}};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum TaskIn {
|
pub(crate) enum TaskIn {
|
||||||
|
|
@ -12,10 +12,9 @@ pub(crate) enum TaskIn {
|
||||||
FileTrash(FileInTrash),
|
FileTrash(FileInTrash),
|
||||||
FileDownload(FileInDownload),
|
FileDownload(FileInDownload),
|
||||||
FileUpload(FileInUpload),
|
FileUpload(FileInUpload),
|
||||||
|
FileUploadDo(FileInUploadDo),
|
||||||
// Plugin
|
// Plugin
|
||||||
PluginEntry(PluginInEntry),
|
PluginEntry(PluginInEntry),
|
||||||
|
|
||||||
// Prework
|
// Prework
|
||||||
PreworkFetch(PreworkInFetch),
|
PreworkFetch(PreworkInFetch),
|
||||||
PreworkLoad(PreworkInLoad),
|
PreworkLoad(PreworkInLoad),
|
||||||
|
|
@ -24,7 +23,7 @@ pub(crate) enum TaskIn {
|
||||||
|
|
||||||
impl_from_in! {
|
impl_from_in! {
|
||||||
// File
|
// File
|
||||||
FilePaste(FileInPaste), FileLink(FileInLink), FileHardlink(FileInHardlink), FileDelete(FileInDelete), FileTrash(FileInTrash), FileDownload(FileInDownload), FileUpload(FileInUpload),
|
FilePaste(FileInPaste), FileLink(FileInLink), FileHardlink(FileInHardlink), FileDelete(FileInDelete), FileTrash(FileInTrash), FileDownload(FileInDownload), FileUpload(FileInUpload), FileUploadDo(FileInUploadDo),
|
||||||
// Plugin
|
// Plugin
|
||||||
PluginEntry(PluginInEntry),
|
PluginEntry(PluginInEntry),
|
||||||
// Prework
|
// Prework
|
||||||
|
|
@ -42,6 +41,7 @@ impl TaskIn {
|
||||||
Self::FileTrash(r#in) => r#in.id,
|
Self::FileTrash(r#in) => r#in.id,
|
||||||
Self::FileDownload(r#in) => r#in.id,
|
Self::FileDownload(r#in) => r#in.id,
|
||||||
Self::FileUpload(r#in) => r#in.id,
|
Self::FileUpload(r#in) => r#in.id,
|
||||||
|
Self::FileUploadDo(r#in) => r#in.id,
|
||||||
// Plugin
|
// Plugin
|
||||||
Self::PluginEntry(r#in) => r#in.id,
|
Self::PluginEntry(r#in) => r#in.id,
|
||||||
// Prework
|
// Prework
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,13 @@ use parking_lot::Mutex;
|
||||||
use tokio::{select, sync::{mpsc::{self, UnboundedReceiver}, oneshot}, task::JoinHandle};
|
use tokio::{select, sync::{mpsc::{self, UnboundedReceiver}, oneshot}, task::JoinHandle};
|
||||||
use yazi_config::{YAZI, plugin::{Fetcher, Preloader}};
|
use yazi_config::{YAZI, plugin::{Fetcher, Preloader}};
|
||||||
use yazi_dds::Pump;
|
use yazi_dds::Pump;
|
||||||
use yazi_fs::FsUrl;
|
|
||||||
use yazi_parser::{app::PluginOpt, tasks::ProcessOpenOpt};
|
use yazi_parser::{app::PluginOpt, tasks::ProcessOpenOpt};
|
||||||
use yazi_proxy::TasksProxy;
|
use yazi_proxy::TasksProxy;
|
||||||
use yazi_shared::{Id, Throttle, url::{UrlBuf, UrlLike}};
|
use yazi_shared::{Id, Throttle, url::{UrlBuf, UrlLike}};
|
||||||
use yazi_vfs::{must_be_dir, provider, unique_name};
|
use yazi_vfs::{must_be_dir, provider, unique_name};
|
||||||
|
|
||||||
use super::{Ongoing, TaskOp};
|
use super::{Ongoing, TaskOp};
|
||||||
use crate::{HIGH, LOW, NORMAL, TaskIn, TaskOps, TaskOut, file::{File, FileInDelete, FileInDownload, FileInHardlink, FileInLink, FileInPaste, FileInTrash, FileOutDelete, FileOutDownload, FileOutHardlink, FileOutPaste, FileProgDelete, FileProgDownload, FileProgHardlink, FileProgLink, FileProgPaste, FileProgTrash}, plugin::{Plugin, PluginInEntry, PluginProgEntry}, prework::{Prework, PreworkInFetch, PreworkInLoad, PreworkInSize, PreworkProgFetch, PreworkProgLoad, PreworkProgSize}, process::{Process, ProcessInBg, ProcessInBlock, ProcessInOrphan, ProcessOutBg, ProcessOutBlock, ProcessOutOrphan, ProcessProgBg, ProcessProgBlock, ProcessProgOrphan}};
|
use crate::{HIGH, LOW, NORMAL, TaskIn, TaskOps, TaskOut, file::{File, FileInDelete, FileInDownload, FileInHardlink, FileInLink, FileInPaste, FileInTrash, FileInUpload, FileOutDelete, FileOutDownload, FileOutHardlink, FileOutPaste, FileOutUpload, FileProgDelete, FileProgDownload, FileProgHardlink, FileProgLink, FileProgPaste, FileProgTrash, FileProgUpload}, plugin::{Plugin, PluginInEntry, PluginProgEntry}, prework::{Prework, PreworkInFetch, PreworkInLoad, PreworkInSize, PreworkProgFetch, PreworkProgLoad, PreworkProgSize}, process::{Process, ProcessInBg, ProcessInBlock, ProcessInOrphan, ProcessOutBg, ProcessOutBlock, ProcessOutOrphan, ProcessProgBg, ProcessProgBlock, ProcessProgOrphan}};
|
||||||
|
|
||||||
pub struct Scheduler {
|
pub struct Scheduler {
|
||||||
file: Arc<File>,
|
file: Arc<File>,
|
||||||
|
|
@ -226,6 +225,18 @@ impl Scheduler {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn file_upload(&self, url: UrlBuf) {
|
||||||
|
let mut ongoing = self.ongoing.lock();
|
||||||
|
let id = ongoing.add::<FileProgUpload>(format!("Upload {}", url.display()));
|
||||||
|
|
||||||
|
if !url.scheme.is_virtual() {
|
||||||
|
return self.ops.out(id, FileOutUpload::Fail("Cannot upload non-remote file".to_owned()));
|
||||||
|
};
|
||||||
|
|
||||||
|
let file = self.file.clone();
|
||||||
|
self.send_micro(id, LOW, async move { file.upload(FileInUpload { id, url }).await });
|
||||||
|
}
|
||||||
|
|
||||||
pub fn plugin_micro(&self, opt: PluginOpt) {
|
pub fn plugin_micro(&self, opt: PluginOpt) {
|
||||||
let id = self.ongoing.lock().add::<PluginProgEntry>(format!("Run micro plugin `{}`", opt.id));
|
let id = self.ongoing.lock().add::<PluginProgEntry>(format!("Run micro plugin `{}`", opt.id));
|
||||||
|
|
||||||
|
|
@ -398,7 +409,8 @@ impl Scheduler {
|
||||||
TaskIn::FileDelete(r#in) => file.delete_do(r#in).await.map_err(Into::into),
|
TaskIn::FileDelete(r#in) => file.delete_do(r#in).await.map_err(Into::into),
|
||||||
TaskIn::FileTrash(r#in) => file.trash_do(r#in).await.map_err(Into::into),
|
TaskIn::FileTrash(r#in) => file.trash_do(r#in).await.map_err(Into::into),
|
||||||
TaskIn::FileDownload(r#in) => file.download_do(r#in).await.map_err(Into::into),
|
TaskIn::FileDownload(r#in) => file.download_do(r#in).await.map_err(Into::into),
|
||||||
TaskIn::FileUpload(r#in) => file.upload_do(r#in).await.map_err(Into::into),
|
TaskIn::FileUpload(r#in) => file.upload(r#in).await.map_err(Into::into),
|
||||||
|
TaskIn::FileUploadDo(r#in) => file.upload_do(r#in).await.map_err(Into::into),
|
||||||
// Plugin
|
// Plugin
|
||||||
TaskIn::PluginEntry(r#in) => plugin.macro_do(r#in).await.map_err(Into::into),
|
TaskIn::PluginEntry(r#in) => plugin.macro_do(r#in).await.map_err(Into::into),
|
||||||
// Prework
|
// Prework
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ libc = { workspace = true }
|
||||||
uzers = { workspace = true }
|
uzers = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
windows-sys = { version = "0.61.1", features = [ "Win32_UI_Shell" ] }
|
windows-sys = { version = "0.61.2", features = [ "Win32_UI_Shell" ] }
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
crossterm = { workspace = true, features = [ "use-dev-tty", "libc" ] }
|
crossterm = { workspace = true, features = [ "use-dev-tty", "libc" ] }
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,10 @@ impl From<Id> for Data {
|
||||||
fn from(value: Id) -> Self { Self::Id(value) }
|
fn from(value: Id) -> Self { Self::Id(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<UrlBuf> for Data {
|
||||||
|
fn from(value: UrlBuf) -> Self { Self::Url(value) }
|
||||||
|
}
|
||||||
|
|
||||||
impl From<&UrlBuf> for Data {
|
impl From<&UrlBuf> for Data {
|
||||||
fn from(value: &UrlBuf) -> Self { Self::Url(value.clone()) }
|
fn from(value: &UrlBuf) -> Self { Self::Url(value.clone()) }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,9 +65,13 @@ impl Cmd {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_opt(mut self, name: impl Into<DataKey>, value: Option<impl Into<Data>>) -> Self {
|
pub fn with_seq<I>(mut self, values: I) -> Self
|
||||||
if let Some(v) = value {
|
where
|
||||||
self.args.insert(name.into(), v.into());
|
I: IntoIterator,
|
||||||
|
I::Item: Into<Data>,
|
||||||
|
{
|
||||||
|
for (i, v) in values.into_iter().enumerate() {
|
||||||
|
self.args.insert(DataKey::Integer(i as i64), v.into());
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,11 @@ impl<'a> From<Url<'a>> for UrlCow<'a> {
|
||||||
fn from(value: Url<'a>) -> Self { Self::Borrowed { loc: value.loc, scheme: value.scheme.into() } }
|
fn from(value: Url<'a>) -> Self { Self::Borrowed { loc: value.loc, scheme: value.scheme.into() } }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a UrlBuf> for UrlCow<'a> {
|
impl<'a, T> From<&'a T> for UrlCow<'a>
|
||||||
fn from(value: &'a UrlBuf) -> Self { value.as_url().into() }
|
where
|
||||||
}
|
T: AsUrl + ?Sized,
|
||||||
|
{
|
||||||
impl<'a> From<&'a UrlCow<'a>> for UrlCow<'a> {
|
fn from(value: &'a T) -> Self { value.as_url().into() }
|
||||||
fn from(value: &'a UrlCow<'a>) -> Self { value.as_url().into() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<UrlBuf> for UrlCow<'_> {
|
impl From<UrlBuf> for UrlCow<'_> {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,32 @@
|
||||||
use std::{borrow::Cow, ffi::OsStr, path::Path};
|
use std::{borrow::Cow, ffi::OsStr, path::{Path, PathBuf}};
|
||||||
|
|
||||||
use crate::url::{Components, Display, Uri, Url, UrlBuf, UrlCow, Urn};
|
use crate::{scheme::SchemeRef, url::{Components, Display, Uri, Url, UrlBuf, UrlCow, Urn}};
|
||||||
|
|
||||||
// --- AsUrl
|
// --- AsUrl
|
||||||
pub trait AsUrl {
|
pub trait AsUrl {
|
||||||
fn as_url(&self) -> Url<'_>;
|
fn as_url(&self) -> Url<'_>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsUrl for Path {
|
||||||
|
#[inline]
|
||||||
|
fn as_url(&self) -> Url<'_> { Url { loc: self.into(), scheme: SchemeRef::Regular } }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsUrl for &Path {
|
||||||
|
#[inline]
|
||||||
|
fn as_url(&self) -> Url<'_> { (*self).as_url() }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsUrl for PathBuf {
|
||||||
|
#[inline]
|
||||||
|
fn as_url(&self) -> Url<'_> { self.as_path().as_url() }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsUrl for &PathBuf {
|
||||||
|
#[inline]
|
||||||
|
fn as_url(&self) -> Url<'_> { (*self).as_path().as_url() }
|
||||||
|
}
|
||||||
|
|
||||||
impl AsUrl for Url<'_> {
|
impl AsUrl for Url<'_> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_url(&self) -> Url<'_> { *self }
|
fn as_url(&self) -> Url<'_> { *self }
|
||||||
|
|
@ -42,11 +62,17 @@ impl AsUrl for &UrlCow<'_> {
|
||||||
fn as_url(&self) -> Url<'_> { (**self).as_url() }
|
fn as_url(&self) -> Url<'_> { (**self).as_url() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: AsUrl> From<&'a T> for Url<'a> {
|
impl<'a, T> From<&'a T> for Url<'a>
|
||||||
|
where
|
||||||
|
T: AsUrl + ?Sized,
|
||||||
|
{
|
||||||
fn from(value: &'a T) -> Self { value.as_url() }
|
fn from(value: &'a T) -> Self { value.as_url() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: AsUrl> From<&'a mut T> for Url<'a> {
|
impl<'a, T> From<&'a mut T> for Url<'a>
|
||||||
|
where
|
||||||
|
T: AsUrl + ?Sized,
|
||||||
|
{
|
||||||
fn from(value: &'a mut T) -> Self { value.as_url() }
|
fn from(value: &'a mut T) -> Self { value.as_url() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,4 +122,6 @@ where
|
||||||
fn urn(&self) -> &Urn { self.as_url().urn() }
|
fn urn(&self) -> &Urn { self.as_url().urn() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsUrl> UrlLike for T {}
|
impl UrlLike for Url<'_> {}
|
||||||
|
impl UrlLike for UrlBuf {}
|
||||||
|
impl UrlLike for UrlCow<'_> {}
|
||||||
|
|
|
||||||
|
|
@ -26,4 +26,4 @@ libc = { workspace = true }
|
||||||
crossterm = { workspace = true, features = [ "use-dev-tty", "libc" ] }
|
crossterm = { workspace = true, features = [ "use-dev-tty", "libc" ] }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
windows-sys = { version = "0.61.1", features = [ "Win32_Globalization", "Win32_Storage_FileSystem", "Win32_System_IO", "Win32_System_Console", "Win32_System_Threading", "Win32_Security" ] }
|
windows-sys = { version = "0.61.2", features = [ "Win32_Globalization", "Win32_Storage_FileSystem", "Win32_System_IO", "Win32_System_Console", "Win32_System_Threading", "Win32_Security" ] }
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,3 @@ parking_lot = { workspace = true }
|
||||||
russh = { workspace = true }
|
russh = { workspace = true }
|
||||||
tokio = { workspace = true }
|
tokio = { workspace = true }
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
|
|
||||||
[target."cfg(unix)".dependencies]
|
|
||||||
uzers = { workspace = true }
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ yazi-adapter = { path = "../yazi-adapter", version = "25.9.15" }
|
||||||
yazi-dds = { path = "../yazi-dds", version = "25.9.15" }
|
yazi-dds = { path = "../yazi-dds", version = "25.9.15" }
|
||||||
yazi-fs = { path = "../yazi-fs", version = "25.9.15" }
|
yazi-fs = { path = "../yazi-fs", version = "25.9.15" }
|
||||||
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
yazi-macro = { path = "../yazi-macro", version = "25.9.15" }
|
||||||
|
yazi-proxy = { path = "../yazi-proxy", version = "25.9.15" }
|
||||||
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
yazi-shared = { path = "../yazi-shared", version = "25.9.15" }
|
||||||
yazi-vfs = { path = "../yazi-vfs", version = "25.9.15" }
|
yazi-vfs = { path = "../yazi-vfs", version = "25.9.15" }
|
||||||
|
|
||||||
|
|
@ -21,11 +22,9 @@ tracing = { workspace = true }
|
||||||
|
|
||||||
# External dependencies
|
# External dependencies
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
base64 = { workspace = true }
|
|
||||||
hashbrown = { workspace = true }
|
hashbrown = { workspace = true }
|
||||||
notify = { version = "8.2.0", default-features = false, features = [ "macos_fsevent" ] }
|
notify = { version = "8.2.0", default-features = false, features = [ "macos_fsevent" ] }
|
||||||
parking_lot = { workspace = true }
|
parking_lot = { workspace = true }
|
||||||
percent-encoding = { workspace = true }
|
percent-encoding = { workspace = true }
|
||||||
tokio = { workspace = true }
|
tokio = { workspace = true }
|
||||||
tokio-stream = { workspace = true }
|
tokio-stream = { workspace = true }
|
||||||
twox-hash = { workspace = true }
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ impl Linked {
|
||||||
pub fn from_file(&self, url: Url) -> Vec<PathBuf> {
|
pub fn from_file(&self, url: Url) -> Vec<PathBuf> {
|
||||||
let Some(path) = url.as_path() else { return vec![] };
|
let Some(path) = url.as_path() else { return vec![] };
|
||||||
if let Some((parent, name)) = path.parent().zip(path.file_name()) {
|
if let Some((parent, name)) = path.parent().zip(path.file_name()) {
|
||||||
self.from_dir(Url::regular(parent)).map(|p| p.join(name)).collect()
|
self.from_dir(parent).map(|p| p.join(name)).collect()
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +51,7 @@ impl Linked {
|
||||||
let watched = watched.read();
|
let watched = watched.read();
|
||||||
|
|
||||||
// Remove entries that are no longer watched
|
// Remove entries that are no longer watched
|
||||||
linked.write().retain(|from, _| watched.contains(Url::regular(from)));
|
linked.write().retain(|from, _| watched.contains(from));
|
||||||
|
|
||||||
// Update existing entries and remove broken links
|
// Update existing entries and remove broken links
|
||||||
for from in watched.paths() {
|
for from in watched.paths() {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
use std::time::Duration;
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
use tokio::{pin, sync::mpsc::UnboundedReceiver};
|
use tokio::{pin, sync::mpsc::UnboundedReceiver};
|
||||||
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
|
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
|
||||||
|
use yazi_fs::{File, FilesOp};
|
||||||
|
use yazi_proxy::MgrProxy;
|
||||||
use yazi_shared::url::{Url, UrlBuf, UrlLike};
|
use yazi_shared::url::{Url, UrlBuf, UrlLike};
|
||||||
|
use yazi_vfs::VfsFile;
|
||||||
|
|
||||||
use crate::{Reporter, WATCHER};
|
use crate::{Reporter, WATCHER};
|
||||||
|
|
||||||
|
|
@ -27,14 +30,30 @@ impl Remote {
|
||||||
|
|
||||||
while let Some(chunk) = rx.next().await {
|
while let Some(chunk) = rx.next().await {
|
||||||
let urls: HashSet<_> = chunk.into_iter().collect();
|
let urls: HashSet<_> = chunk.into_iter().collect();
|
||||||
|
|
||||||
let _permit = WATCHER.acquire().await.unwrap();
|
let _permit = WATCHER.acquire().await.unwrap();
|
||||||
|
|
||||||
|
let mut ops = Vec::with_capacity(urls.len());
|
||||||
|
let mut ups = Vec::with_capacity(urls.len());
|
||||||
|
|
||||||
for u in urls {
|
for u in urls {
|
||||||
let Some((parent, urn)) = u.pair() else { continue };
|
let Some((parent, urn)) = u.pair() else { continue };
|
||||||
|
let Ok(mut file) = File::new(&u).await else {
|
||||||
|
ops.push(FilesOp::Deleting(parent.into(), [urn.into()].into()));
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
// FIXME
|
let is_file = file.is_file();
|
||||||
tracing::debug!("Remote changed: {}", u.display());
|
file.cha.ctime = Some(SystemTime::now());
|
||||||
|
|
||||||
|
ops.push(FilesOp::Upserting(parent.into(), [(urn.into(), file)].into()));
|
||||||
|
if is_file {
|
||||||
|
ups.push(u);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilesOp::mutate(ops);
|
||||||
|
MgrProxy::upload(ups);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,15 +33,18 @@ impl Reporter {
|
||||||
|
|
||||||
let watched = WATCHED.read();
|
let watched = WATCHED.read();
|
||||||
for parent in [parent].into_iter().chain(linked) {
|
for parent in [parent].into_iter().chain(linked) {
|
||||||
|
if watched.contains(parent) {
|
||||||
|
self.local_tx.send(url.to_owned()).ok();
|
||||||
|
self.local_tx.send(parent.to_owned()).ok();
|
||||||
|
}
|
||||||
|
if name.extension() == Some("%tmp".as_ref()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// SFTP caches
|
// SFTP caches
|
||||||
if let Some(dir) = watched.find_by_cache(&parent.loc) {
|
if let Some(dir) = watched.find_by_cache(&parent.loc) {
|
||||||
self.remote_tx.send(dir.join(name)).ok();
|
self.remote_tx.send(dir.join(name)).ok();
|
||||||
self.remote_tx.send(dir.to_owned()).ok();
|
self.remote_tx.send(dir.to_owned()).ok();
|
||||||
}
|
}
|
||||||
if watched.contains(parent) {
|
|
||||||
self.local_tx.send(url.to_owned()).ok();
|
|
||||||
self.local_tx.send(parent.to_owned()).ok();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue