mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: new duplicate DDS event for copying files (#3456)
This commit is contained in:
parent
6e3c96289e
commit
8c81172a19
24 changed files with 441 additions and 158 deletions
|
|
@ -35,6 +35,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
|||
- Support invalid UTF-8 paths throughout the codebase ([#2884], [#2889], [#2890], [#2895], [#3023], [#3290], [#3369])
|
||||
- Allow upgrading only specific packages with `ya pkg` ([#2841])
|
||||
- Respect the user's `image_filter` setting in the preset ImageMagick previewer ([#3286])
|
||||
- New `duplicate` DDS event for copying files ([#3456])
|
||||
- New `ind-sort` and `key-sort` DDS events to change sorting in Lua ([#3391])
|
||||
- Allow custom mouse click behavior for individual files ([#2925])
|
||||
- Display newlines in input as spaces to improve readability ([#2932])
|
||||
|
|
@ -1558,3 +1559,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
|||
[#3419]: https://github.com/sxyazi/yazi/pull/3419
|
||||
[#3422]: https://github.com/sxyazi/yazi/pull/3422
|
||||
[#3429]: https://github.com/sxyazi/yazi/pull/3429
|
||||
[#3456]: https://github.com/sxyazi/yazi/pull/3456
|
||||
|
|
|
|||
361
Cargo.lock
generated
361
Cargo.lock
generated
|
|
@ -23,7 +23,7 @@ version = "0.5.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"crypto-common 0.1.7",
|
||||
"generic-array 0.14.7",
|
||||
]
|
||||
|
||||
|
|
@ -171,9 +171,12 @@ checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
|
|||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
version = "1.7.1"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
|
||||
checksum = "51d03449bb8ca2cc2ef70869af31463d1ae5ccc8fa3e334b307203fbf815207e"
|
||||
dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arg_enum_proc_macro"
|
||||
|
|
@ -292,6 +295,12 @@ version = "0.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
|
||||
|
||||
[[package]]
|
||||
name = "base16ct"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8b59d472eab27ade8d770dcb11da7201c11234bef9f82ce7aa517be028d462b"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.22.1"
|
||||
|
|
@ -312,7 +321,7 @@ checksum = "6aeac2e1fe888769f34f05ac343bbef98b14d1ffb292ab69d4608b3abc86f2a2"
|
|||
dependencies = [
|
||||
"blowfish",
|
||||
"pbkdf2",
|
||||
"sha2",
|
||||
"sha2 0.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -382,7 +391,7 @@ version = "0.10.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"digest 0.10.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -394,6 +403,15 @@ dependencies = [
|
|||
"generic-array 0.14.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96eb4cdd6cf1b31d671e9efe75c5d1ec614776856cefbe109ca373554a6d514f"
|
||||
dependencies = [
|
||||
"hybrid-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.3.3"
|
||||
|
|
@ -505,9 +523,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.49"
|
||||
version = "1.2.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215"
|
||||
checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"jobserver",
|
||||
|
|
@ -557,7 +575,7 @@ version = "0.4.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"crypto-common 0.1.7",
|
||||
"inout",
|
||||
]
|
||||
|
||||
|
|
@ -693,6 +711,12 @@ version = "0.9.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
|
||||
|
||||
[[package]]
|
||||
name = "const-oid"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dabb6555f92fb9ee4140454eb5dcd14c7960e1225c6d1a6cc361f032947713e"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.10.0"
|
||||
|
|
@ -811,7 +835,7 @@ dependencies = [
|
|||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"rustix 1.1.2",
|
||||
"rustix 1.1.3",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
|
|
@ -844,6 +868,19 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-bigint"
|
||||
version = "0.7.0-rc.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6715836b4946e8585016e80b79c7561476aff3b22f7b756778e7b109d86086c6"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"rand_core 0.10.0-rc-3",
|
||||
"serdect",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.7"
|
||||
|
|
@ -854,6 +891,26 @@ dependencies = [
|
|||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.2.0-rc.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "919bd05924682a5480aec713596b9e2aabed3a0a6022fab6847f85a99e5f190a"
|
||||
dependencies = [
|
||||
"hybrid-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-primes"
|
||||
version = "0.7.0-pre.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdd9b2855017318a49714c07ee8895b89d3510d54fa6d86be5835de74c389609"
|
||||
dependencies = [
|
||||
"crypto-bigint 0.7.0-rc.10",
|
||||
"libm",
|
||||
"rand_core 0.10.0-rc-3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctr"
|
||||
version = "0.9.2"
|
||||
|
|
@ -872,7 +929,7 @@ dependencies = [
|
|||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"curve25519-dalek-derive",
|
||||
"digest",
|
||||
"digest 0.10.7",
|
||||
"fiat-crypto",
|
||||
"rustc_version",
|
||||
"subtle",
|
||||
|
|
@ -969,8 +1026,19 @@ version = "0.7.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"pem-rfc7468",
|
||||
"const-oid 0.9.6",
|
||||
"pem-rfc7468 0.7.0",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "der"
|
||||
version = "0.8.0-rc.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02c1d73e9668ea6b6a28172aa55f3ebec38507131ce179051c8033b5c6037653"
|
||||
dependencies = [
|
||||
"const-oid 0.10.1",
|
||||
"pem-rfc7468 1.0.0",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
|
|
@ -1016,18 +1084,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "2.1.0"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618"
|
||||
checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134"
|
||||
dependencies = [
|
||||
"derive_more-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more-impl"
|
||||
version = "2.1.0"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b"
|
||||
checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
|
|
@ -1042,12 +1110,23 @@ version = "0.10.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"const-oid",
|
||||
"crypto-common",
|
||||
"block-buffer 0.10.4",
|
||||
"const-oid 0.9.6",
|
||||
"crypto-common 0.1.7",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.11.0-rc.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea390c940e465846d64775e55e3115d5dc934acb953de6f6e6360bc232fe2bf7"
|
||||
dependencies = [
|
||||
"block-buffer 0.11.0",
|
||||
"const-oid 0.10.1",
|
||||
"crypto-common 0.2.0-rc.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "6.0.0"
|
||||
|
|
@ -1084,12 +1163,12 @@ version = "0.16.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca"
|
||||
dependencies = [
|
||||
"der",
|
||||
"digest",
|
||||
"der 0.7.10",
|
||||
"digest 0.10.7",
|
||||
"elliptic-curve",
|
||||
"rfc6979",
|
||||
"signature",
|
||||
"spki",
|
||||
"signature 2.2.0",
|
||||
"spki 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1098,8 +1177,8 @@ version = "2.2.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
|
||||
dependencies = [
|
||||
"pkcs8",
|
||||
"signature",
|
||||
"pkcs8 0.10.2",
|
||||
"signature 2.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1112,7 +1191,7 @@ dependencies = [
|
|||
"ed25519",
|
||||
"rand_core 0.6.4",
|
||||
"serde",
|
||||
"sha2",
|
||||
"sha2 0.10.9",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
|
@ -1129,15 +1208,15 @@ version = "0.13.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47"
|
||||
dependencies = [
|
||||
"base16ct",
|
||||
"crypto-bigint",
|
||||
"digest",
|
||||
"base16ct 0.2.0",
|
||||
"crypto-bigint 0.5.5",
|
||||
"digest 0.10.7",
|
||||
"ff",
|
||||
"generic-array 0.14.7",
|
||||
"group",
|
||||
"hkdf",
|
||||
"pem-rfc7468",
|
||||
"pkcs8",
|
||||
"pem-rfc7468 0.7.0",
|
||||
"pkcs8 0.10.2",
|
||||
"rand_core 0.6.4",
|
||||
"sec1",
|
||||
"subtle",
|
||||
|
|
@ -1644,7 +1723,7 @@ version = "0.12.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"digest 0.10.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1656,6 +1735,15 @@ dependencies = [
|
|||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hybrid-array"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f471e0a81b2f90ffc0cb2f951ae04da57de8baa46fa99112b062a5173a5088d0"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.64"
|
||||
|
|
@ -1790,12 +1878,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "internal-russh-forked-ssh-key"
|
||||
version = "0.6.11+upstream-0.6.7"
|
||||
version = "0.6.16+upstream-0.6.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0a77eae781ed6a7709fb15b64862fcca13d886b07c7e2786f5ed34e5e2b9187"
|
||||
checksum = "fe44f2bbd99fcb302e246e2d6bcf51aeda346d02a365f80296a07a8c711b6da6"
|
||||
dependencies = [
|
||||
"argon2",
|
||||
"bcrypt-pbkdf",
|
||||
"digest 0.11.0-rc.4",
|
||||
"ecdsa",
|
||||
"ed25519-dalek",
|
||||
"hex",
|
||||
|
|
@ -1807,9 +1896,11 @@ dependencies = [
|
|||
"rand_core 0.6.4",
|
||||
"rsa",
|
||||
"sec1",
|
||||
"sha1",
|
||||
"sha2",
|
||||
"signature",
|
||||
"sha1 0.10.6",
|
||||
"sha1 0.11.0-rc.3",
|
||||
"sha2 0.10.9",
|
||||
"signature 2.2.0",
|
||||
"signature 3.0.0-rc.5",
|
||||
"ssh-cipher",
|
||||
"ssh-encoding",
|
||||
"subtle",
|
||||
|
|
@ -1853,9 +1944,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010"
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
|
|
@ -2306,8 +2397,8 @@ dependencies = [
|
|||
"num-iter",
|
||||
"num-traits",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2496,7 +2587,7 @@ dependencies = [
|
|||
"ecdsa",
|
||||
"elliptic-curve",
|
||||
"primeorder",
|
||||
"sha2",
|
||||
"sha2 0.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2508,7 +2599,7 @@ dependencies = [
|
|||
"ecdsa",
|
||||
"elliptic-curve",
|
||||
"primeorder",
|
||||
"sha2",
|
||||
"sha2 0.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2517,12 +2608,12 @@ version = "0.13.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2"
|
||||
dependencies = [
|
||||
"base16ct",
|
||||
"base16ct 0.2.0",
|
||||
"ecdsa",
|
||||
"elliptic-curve",
|
||||
"primeorder",
|
||||
"rand_core 0.6.4",
|
||||
"sha2",
|
||||
"sha2 0.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2537,7 +2628,7 @@ dependencies = [
|
|||
"futures",
|
||||
"log",
|
||||
"rand 0.8.5",
|
||||
"sha2",
|
||||
"sha2 0.10.9",
|
||||
"thiserror 1.0.69",
|
||||
"tokio",
|
||||
"windows 0.62.2",
|
||||
|
|
@ -2626,7 +2717,7 @@ version = "0.12.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"digest 0.10.7",
|
||||
"hmac",
|
||||
]
|
||||
|
||||
|
|
@ -2639,6 +2730,15 @@ dependencies = [
|
|||
"base64ct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pem-rfc7468"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6305423e0e7738146434843d1694d621cce767262b2a86910beab705e4493d9"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.2"
|
||||
|
|
@ -2659,13 +2759,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
|||
|
||||
[[package]]
|
||||
name = "pkcs1"
|
||||
version = "0.7.5"
|
||||
version = "0.8.0-rc.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
|
||||
checksum = "986d2e952779af96ea048f160fd9194e1751b4faea78bcf3ceb456efe008088e"
|
||||
dependencies = [
|
||||
"der",
|
||||
"pkcs8",
|
||||
"spki",
|
||||
"der 0.8.0-rc.10",
|
||||
"spki 0.8.0-rc.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2676,11 +2775,11 @@ checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6"
|
|||
dependencies = [
|
||||
"aes",
|
||||
"cbc",
|
||||
"der",
|
||||
"der 0.7.10",
|
||||
"pbkdf2",
|
||||
"scrypt",
|
||||
"sha2",
|
||||
"spki",
|
||||
"sha2 0.10.9",
|
||||
"spki 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2689,10 +2788,20 @@ version = "0.10.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
|
||||
dependencies = [
|
||||
"der",
|
||||
"der 0.7.10",
|
||||
"pkcs5",
|
||||
"rand_core 0.6.4",
|
||||
"spki",
|
||||
"spki 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkcs8"
|
||||
version = "0.11.0-rc.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77089aec8290d0b7bb01b671b091095cf1937670725af4fd73d47249f03b12c0"
|
||||
dependencies = [
|
||||
"der 0.8.0-rc.10",
|
||||
"spki 0.8.0-rc.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2955,6 +3064,12 @@ dependencies = [
|
|||
"getrandom 0.3.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.10.0-rc-3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f66ee92bc15280519ef199a274fe0cafff4245d31bc39aaa31c011ad56cb1f05"
|
||||
|
||||
[[package]]
|
||||
name = "ratatui"
|
||||
version = "0.29.0"
|
||||
|
|
@ -3147,30 +3262,29 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rsa"
|
||||
version = "0.9.9"
|
||||
version = "0.10.0-rc.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40a0376c50d0358279d9d643e4bf7b7be212f1f4ff1da9070a7b54d22ef75c88"
|
||||
checksum = "e499c52862d75a86c0024cc99dcb6d7127d15af3beae7b03573d62fab7ade08a"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"digest",
|
||||
"num-bigint-dig",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"const-oid 0.10.1",
|
||||
"crypto-bigint 0.7.0-rc.10",
|
||||
"crypto-primes",
|
||||
"digest 0.11.0-rc.4",
|
||||
"pkcs1",
|
||||
"pkcs8",
|
||||
"rand_core 0.6.4",
|
||||
"sha2",
|
||||
"signature",
|
||||
"spki",
|
||||
"pkcs8 0.11.0-rc.8",
|
||||
"rand_core 0.10.0-rc-3",
|
||||
"sha2 0.11.0-rc.3",
|
||||
"signature 3.0.0-rc.5",
|
||||
"spki 0.8.0-rc.4",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "russh"
|
||||
version = "0.55.0"
|
||||
version = "0.56.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82b4d036bb45d7bbe99dbfef4ec60eaeb614708d22ff107124272f8ef6b54548"
|
||||
checksum = "bdbb7dcdd62c17ac911307ff693f55b3ec6712004d2d66ffdb8c0fa00269fd66"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"bitflags 2.10.0",
|
||||
|
|
@ -3182,8 +3296,8 @@ dependencies = [
|
|||
"curve25519-dalek",
|
||||
"data-encoding",
|
||||
"delegate",
|
||||
"der",
|
||||
"digest",
|
||||
"der 0.7.10",
|
||||
"digest 0.10.7",
|
||||
"ecdsa",
|
||||
"ed25519-dalek",
|
||||
"elliptic-curve",
|
||||
|
|
@ -3207,7 +3321,7 @@ dependencies = [
|
|||
"pbkdf2",
|
||||
"pkcs1",
|
||||
"pkcs5",
|
||||
"pkcs8",
|
||||
"pkcs8 0.10.2",
|
||||
"rand 0.8.5",
|
||||
"rand_core 0.6.4",
|
||||
"ring",
|
||||
|
|
@ -3215,10 +3329,10 @@ dependencies = [
|
|||
"russh-cryptovec",
|
||||
"russh-util",
|
||||
"sec1",
|
||||
"sha1",
|
||||
"sha2",
|
||||
"signature",
|
||||
"spki",
|
||||
"sha1 0.10.6",
|
||||
"sha2 0.10.9",
|
||||
"signature 2.2.0",
|
||||
"spki 0.7.3",
|
||||
"ssh-encoding",
|
||||
"subtle",
|
||||
"thiserror 1.0.69",
|
||||
|
|
@ -3288,9 +3402,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.1.2"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
|
||||
checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"errno",
|
||||
|
|
@ -3307,9 +3421,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
|||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.20"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||
checksum = "62049b2877bf12821e8f9ad256ee38fdc31db7387ec2d3b3f403024de2034aea"
|
||||
|
||||
[[package]]
|
||||
name = "safe_arch"
|
||||
|
|
@ -3352,7 +3466,7 @@ checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f"
|
|||
dependencies = [
|
||||
"pbkdf2",
|
||||
"salsa20",
|
||||
"sha2",
|
||||
"sha2 0.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3361,10 +3475,10 @@ version = "0.7.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc"
|
||||
dependencies = [
|
||||
"base16ct",
|
||||
"der",
|
||||
"base16ct 0.2.0",
|
||||
"der 0.7.10",
|
||||
"generic-array 0.14.7",
|
||||
"pkcs8",
|
||||
"pkcs8 0.10.2",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
|
@ -3417,9 +3531,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.145"
|
||||
version = "1.0.146"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
|
||||
checksum = "217ca874ae0207aac254aa02c957ded05585a90892cc8d87f9e5fa49669dadd8"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
|
|
@ -3437,6 +3551,16 @@ dependencies = [
|
|||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serdect"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3ef0e35b322ddfaecbc60f34ab448e157e48531288ee49fafbb053696b8ffe2"
|
||||
dependencies = [
|
||||
"base16ct 0.3.0",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.6"
|
||||
|
|
@ -3445,7 +3569,18 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
|
|||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
"digest 0.10.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.11.0-rc.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa1ae819b9870cadc959a052363de870944a1646932d274a4e270f64bf79e5ef"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest 0.11.0-rc.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3456,7 +3591,18 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
|||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
"digest 0.10.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.11.0-rc.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19d43dc0354d88b791216bb5c1bfbb60c0814460cc653ae0ebd71f286d0bd927"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest 0.11.0-rc.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3522,10 +3668,20 @@ version = "2.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"digest 0.10.7",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signature"
|
||||
version = "3.0.0-rc.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a0251c9d6468f4ba853b6352b190fb7c1e405087779917c238445eb03993826"
|
||||
dependencies = [
|
||||
"digest 0.11.0-rc.4",
|
||||
"rand_core 0.10.0-rc-3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.8"
|
||||
|
|
@ -3582,7 +3738,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"der",
|
||||
"der 0.7.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spki"
|
||||
version = "0.8.0-rc.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8baeff88f34ed0691978ec34440140e1572b68c7dd4a495fd14a3dc1944daa80"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"der 0.8.0-rc.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3610,8 +3776,8 @@ checksum = "eb9242b9ef4108a78e8cd1a2c98e193ef372437f8c22be363075233321dd4a15"
|
|||
dependencies = [
|
||||
"base64ct",
|
||||
"bytes",
|
||||
"pem-rfc7468",
|
||||
"sha2",
|
||||
"pem-rfc7468 0.7.0",
|
||||
"sha2 0.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4070,7 +4236,7 @@ version = "0.5.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"crypto-common 0.1.7",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
|
|
@ -4281,7 +4447,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "d3fabb953106c3c8eea8306e4393700d7657561cb43122571b172bbfb7c7ba1d"
|
||||
dependencies = [
|
||||
"env_home",
|
||||
"rustix 1.1.2",
|
||||
"rustix 1.1.3",
|
||||
"winsafe",
|
||||
]
|
||||
|
||||
|
|
@ -4889,7 +5055,6 @@ dependencies = [
|
|||
"serde_json",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
"uzers",
|
||||
"vergen-gitcl",
|
||||
|
|
@ -5273,9 +5438,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zune-jpeg"
|
||||
version = "0.5.7"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51d915729b0e7d5fe35c2f294c5dc10b30207cc637920e5b59077bfa3da63f28"
|
||||
checksum = "e35aee689668bf9bd6f6f3a6c60bb29ba1244b3b43adfd50edd554a371da37d5"
|
||||
dependencies = [
|
||||
"zune-core",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -50,10 +50,10 @@ percent-encoding = "2.3.2"
|
|||
rand = { version = "0.9.2", default-features = false, features = [ "os_rng", "small_rng", "std" ] }
|
||||
ratatui = { version = "0.29.0", features = [ "serde", "unstable-rendered-line-info", "unstable-widget-ref" ] }
|
||||
regex = "1.12.2"
|
||||
russh = { version = "0.55.0", default-features = false, features = [ "ring", "rsa" ] }
|
||||
russh = { version = "0.56.0", default-features = false, features = [ "ring", "rsa" ] }
|
||||
scopeguard = "1.2.0"
|
||||
serde = { version = "1.0.228", features = [ "derive" ] }
|
||||
serde_json = "1.0.145"
|
||||
serde_json = "1.0.146"
|
||||
syntect = { version = "5.3.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] }
|
||||
thiserror = "2.0.17"
|
||||
tokio = { version = "1.48.0", features = [ "full" ] }
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ serde = { workspace = true }
|
|||
serde_json = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
tokio-stream = { workspace = true }
|
||||
tokio-util = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
|
|
|
|||
52
yazi-dds/src/ember/duplicate.rs
Normal file
52
yazi-dds/src/ember/duplicate.rs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use mlua::{IntoLua, Lua, Value};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use yazi_shared::url::UrlBuf;
|
||||
|
||||
use super::Ember;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct EmberDuplicate<'a> {
|
||||
pub items: Cow<'a, Vec<BodyDuplicateItem>>,
|
||||
}
|
||||
|
||||
impl<'a> EmberDuplicate<'a> {
|
||||
pub fn borrowed(items: &'a Vec<BodyDuplicateItem>) -> Ember<'a> {
|
||||
Self { items: Cow::Borrowed(items) }.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl EmberDuplicate<'static> {
|
||||
pub fn owned(items: Vec<BodyDuplicateItem>) -> Ember<'static> {
|
||||
Self { items: Cow::Owned(items) }.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<EmberDuplicate<'a>> for Ember<'a> {
|
||||
fn from(value: EmberDuplicate<'a>) -> Self { Self::Duplicate(value) }
|
||||
}
|
||||
|
||||
impl IntoLua for EmberDuplicate<'_> {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
|
||||
lua.create_table_from([("items", self.items.into_owned())])?.into_lua(lua)
|
||||
}
|
||||
}
|
||||
|
||||
// --- Item
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct BodyDuplicateItem {
|
||||
pub from: UrlBuf,
|
||||
pub to: UrlBuf,
|
||||
}
|
||||
|
||||
impl IntoLua for BodyDuplicateItem {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
|
||||
lua
|
||||
.create_table_from([
|
||||
("from", yazi_binding::Url::new(self.from)),
|
||||
("to", yazi_binding::Url::new(self.to)),
|
||||
])?
|
||||
.into_lua(lua)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ use anyhow::{Result, bail};
|
|||
use mlua::{ExternalResult, IntoLua, Lua, Value};
|
||||
use yazi_shared::Id;
|
||||
|
||||
use super::{EmberBulk, EmberBye, EmberCd, EmberCustom, EmberDelete, EmberHey, EmberHi, EmberHover, EmberLoad, EmberMount, EmberMove, EmberRename, EmberTab, EmberTrash, EmberYank};
|
||||
use super::{EmberBulk, EmberBye, EmberCd, EmberCustom, EmberDelete, EmberDuplicate, EmberHey, EmberHi, EmberHover, EmberLoad, EmberMount, EmberMove, EmberRename, EmberTab, EmberTrash, EmberYank};
|
||||
use crate::Payload;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -17,6 +17,7 @@ pub enum Ember<'a> {
|
|||
Rename(EmberRename<'a>),
|
||||
Bulk(EmberBulk<'a>),
|
||||
Yank(EmberYank<'a>),
|
||||
Duplicate(EmberDuplicate<'a>),
|
||||
Move(EmberMove<'a>),
|
||||
Trash(EmberTrash<'a>),
|
||||
Delete(EmberDelete<'a>),
|
||||
|
|
@ -37,6 +38,7 @@ impl Ember<'static> {
|
|||
"rename" => Self::Rename(serde_json::from_str(body)?),
|
||||
"bulk" => Self::Bulk(serde_json::from_str(body)?),
|
||||
"@yank" => Self::Yank(serde_json::from_str(body)?),
|
||||
"duplicate" => Self::Duplicate(serde_json::from_str(body)?),
|
||||
"move" => Self::Move(serde_json::from_str(body)?),
|
||||
"trash" => Self::Trash(serde_json::from_str(body)?),
|
||||
"delete" => Self::Delete(serde_json::from_str(body)?),
|
||||
|
|
@ -63,6 +65,7 @@ impl Ember<'static> {
|
|||
| "rename"
|
||||
| "bulk"
|
||||
| "@yank"
|
||||
| "duplicate"
|
||||
| "move"
|
||||
| "trash"
|
||||
| "delete"
|
||||
|
|
@ -100,6 +103,7 @@ impl<'a> Ember<'a> {
|
|||
Self::Rename(_) => "rename",
|
||||
Self::Bulk(_) => "bulk",
|
||||
Self::Yank(_) => "@yank",
|
||||
Self::Duplicate(_) => "duplicate",
|
||||
Self::Move(_) => "move",
|
||||
Self::Trash(_) => "trash",
|
||||
Self::Delete(_) => "delete",
|
||||
|
|
@ -128,6 +132,7 @@ impl<'a> IntoLua for Ember<'a> {
|
|||
Self::Rename(b) => b.into_lua(lua),
|
||||
Self::Bulk(b) => b.into_lua(lua),
|
||||
Self::Yank(b) => b.into_lua(lua),
|
||||
Self::Duplicate(b) => b.into_lua(lua),
|
||||
Self::Move(b) => b.into_lua(lua),
|
||||
Self::Trash(b) => b.into_lua(lua),
|
||||
Self::Delete(b) => b.into_lua(lua),
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
yazi_macro::mod_flat!(
|
||||
bulk bye cd custom delete ember hey hi hover load mount r#move rename tab trash yank
|
||||
bulk bye cd custom delete duplicate ember hey hi hover load mount r#move rename tab trash yank
|
||||
);
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ impl Display for Payload<'_> {
|
|||
Ember::Rename(b) => serde_json::to_string(b),
|
||||
Ember::Bulk(b) => serde_json::to_string(b),
|
||||
Ember::Yank(b) => serde_json::to_string(b),
|
||||
Ember::Duplicate(b) => serde_json::to_string(b),
|
||||
Ember::Move(b) => serde_json::to_string(b),
|
||||
Ember::Trash(b) => serde_json::to_string(b),
|
||||
Ember::Delete(b) => serde_json::to_string(b),
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use yazi_boot::BOOT;
|
|||
use yazi_fs::FolderStage;
|
||||
use yazi_shared::{Id, RoCell, url::{Url, UrlBuf, UrlBufCov}};
|
||||
|
||||
use crate::{Client, ID, PEERS, ember::{BodyMoveItem, Ember, EmberBulk, EmberHi}};
|
||||
use crate::{Client, ID, PEERS, ember::{BodyDuplicateItem, BodyMoveItem, Ember, EmberBulk, EmberHi}};
|
||||
|
||||
pub static LOCAL: RoCell<RwLock<HashMap<String, HashMap<String, Function>>>> = RoCell::new();
|
||||
|
||||
|
|
@ -157,6 +157,8 @@ impl Pubsub {
|
|||
|
||||
pub_after!(@yank(cut: bool, urls: &HashSet<UrlBufCov>), (cut, urls));
|
||||
|
||||
pub_after!(duplicate(items: Vec<BodyDuplicateItem>), (&items), (items));
|
||||
|
||||
pub_after!(move(items: Vec<BodyMoveItem>), (&items), (items));
|
||||
|
||||
pub_after!(trash(urls: Vec<UrlBuf>), (&urls), (urls));
|
||||
|
|
|
|||
|
|
@ -1,60 +1,65 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use parking_lot::Mutex;
|
||||
use tokio::{pin, select, sync::mpsc};
|
||||
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use yazi_macro::err;
|
||||
use yazi_shared::{RoCell, url::{AsUrl, UrlBuf}};
|
||||
use yazi_shared::{RoCell, url::UrlBuf};
|
||||
|
||||
use crate::{Pubsub, ember::BodyMoveItem};
|
||||
use crate::{Pubsub, ember::{BodyDuplicateItem, BodyMoveItem}};
|
||||
|
||||
static CT: RoCell<CancellationToken> = RoCell::new();
|
||||
static MOVE_TX: Mutex<Option<mpsc::UnboundedSender<BodyMoveItem>>> = Mutex::new(None);
|
||||
static TRASH_TX: Mutex<Option<mpsc::UnboundedSender<UrlBuf>>> = Mutex::new(None);
|
||||
static DELETE_TX: Mutex<Option<mpsc::UnboundedSender<UrlBuf>>> = Mutex::new(None);
|
||||
static DUPLICATE_TX: RoCell<mpsc::UnboundedSender<BodyDuplicateItem>> = RoCell::new();
|
||||
static MOVE_TX: RoCell<mpsc::UnboundedSender<BodyMoveItem>> = RoCell::new();
|
||||
static TRASH_TX: RoCell<mpsc::UnboundedSender<UrlBuf>> = RoCell::new();
|
||||
static DELETE_TX: RoCell<mpsc::UnboundedSender<UrlBuf>> = RoCell::new();
|
||||
static SHUTDOWN_TX: RoCell<mpsc::UnboundedSender<()>> = RoCell::new();
|
||||
|
||||
pub struct Pump;
|
||||
|
||||
impl Pump {
|
||||
pub fn push_duplicate<U>(from: U, to: U)
|
||||
where
|
||||
U: Into<UrlBuf>,
|
||||
{
|
||||
DUPLICATE_TX.send(BodyDuplicateItem { from: from.into(), to: to.into() }).ok();
|
||||
}
|
||||
|
||||
pub fn push_move<U>(from: U, to: U)
|
||||
where
|
||||
U: AsUrl,
|
||||
U: Into<UrlBuf>,
|
||||
{
|
||||
if let Some(tx) = &*MOVE_TX.lock() {
|
||||
tx.send(BodyMoveItem { from: from.as_url().to_owned(), to: to.as_url().to_owned() }).ok();
|
||||
}
|
||||
MOVE_TX.send(BodyMoveItem { from: from.into(), to: to.into() }).ok();
|
||||
}
|
||||
|
||||
pub fn push_trash<U>(target: U)
|
||||
where
|
||||
U: AsUrl,
|
||||
U: Into<UrlBuf>,
|
||||
{
|
||||
if let Some(tx) = &*TRASH_TX.lock() {
|
||||
tx.send(target.as_url().to_owned()).ok();
|
||||
}
|
||||
TRASH_TX.send(target.into()).ok();
|
||||
}
|
||||
|
||||
pub fn push_delete<U>(target: U)
|
||||
where
|
||||
U: AsUrl,
|
||||
U: Into<UrlBuf>,
|
||||
{
|
||||
if let Some(tx) = &*DELETE_TX.lock() {
|
||||
tx.send(target.as_url().to_owned()).ok();
|
||||
}
|
||||
DELETE_TX.send(target.into()).ok();
|
||||
}
|
||||
|
||||
pub(super) fn serve() {
|
||||
let (move_tx, move_rx) = mpsc::unbounded_channel();
|
||||
let (duplicate_tx, duplicate_rx) = mpsc::unbounded_channel();
|
||||
let (trash_tx, trash_rx) = mpsc::unbounded_channel();
|
||||
let (delete_tx, delete_rx) = mpsc::unbounded_channel();
|
||||
let (shutdown_tx, mut shutdown_rx) = mpsc::unbounded_channel();
|
||||
|
||||
CT.with(<_>::default);
|
||||
MOVE_TX.lock().replace(move_tx);
|
||||
TRASH_TX.lock().replace(trash_tx);
|
||||
DELETE_TX.lock().replace(delete_tx);
|
||||
DUPLICATE_TX.init(duplicate_tx);
|
||||
MOVE_TX.init(move_tx);
|
||||
TRASH_TX.init(trash_tx);
|
||||
DELETE_TX.init(delete_tx);
|
||||
SHUTDOWN_TX.init(shutdown_tx);
|
||||
|
||||
tokio::spawn(async move {
|
||||
let duplicate_rx =
|
||||
UnboundedReceiverStream::new(duplicate_rx).chunks_timeout(1000, Duration::from_millis(500));
|
||||
let move_rx =
|
||||
UnboundedReceiverStream::new(move_rx).chunks_timeout(1000, Duration::from_millis(500));
|
||||
let trash_rx =
|
||||
|
|
@ -62,28 +67,28 @@ impl Pump {
|
|||
let delete_rx =
|
||||
UnboundedReceiverStream::new(delete_rx).chunks_timeout(1000, Duration::from_millis(500));
|
||||
|
||||
pin!(duplicate_rx);
|
||||
pin!(move_rx);
|
||||
pin!(trash_rx);
|
||||
pin!(delete_rx);
|
||||
|
||||
loop {
|
||||
select! {
|
||||
Some(items) = duplicate_rx.next() => err!(Pubsub::pub_after_duplicate(items)),
|
||||
Some(items) = move_rx.next() => err!(Pubsub::pub_after_move(items)),
|
||||
Some(urls) = trash_rx.next() => err!(Pubsub::pub_after_trash(urls)),
|
||||
Some(urls) = delete_rx.next() => err!(Pubsub::pub_after_delete(urls)),
|
||||
else => {
|
||||
CT.cancel();
|
||||
_ = shutdown_rx.recv() => {
|
||||
shutdown_rx.close();
|
||||
break;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub(super) async fn shutdown() {
|
||||
drop(MOVE_TX.lock().take());
|
||||
drop(TRASH_TX.lock().take());
|
||||
drop(DELETE_TX.lock().take());
|
||||
CT.cancelled().await;
|
||||
SHUTDOWN_TX.send(()).ok();
|
||||
SHUTDOWN_TX.closed().await;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ yazi-shim = { path = "../yazi-shim", version = "25.9.15" }
|
|||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
arc-swap = "1.7.1"
|
||||
arc-swap = "1.8.0"
|
||||
bitflags = { workspace = true }
|
||||
dirs = { workspace = true }
|
||||
foldhash = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ fn expand_variables(p: PathCow) -> PathCow {
|
|||
});
|
||||
|
||||
match (b, p.kind()) {
|
||||
(Cow::Borrowed(_), _) => p.into(),
|
||||
(Cow::Borrowed(_), _) => p,
|
||||
(Cow::Owned(b), PathKind::Os) => {
|
||||
PathBufDyn::Os(std::path::PathBuf::from_wtf8_vec(b).expect("valid WTF-8 path")).into()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ impl From<CmdCow> for CdOpt {
|
|||
let mut target = c.take_first().unwrap_or_default();
|
||||
|
||||
if !c.bool("raw") {
|
||||
target = expand_url(target).into();
|
||||
target = expand_url(target);
|
||||
}
|
||||
|
||||
if let Some(u) = provider::try_absolute(&target)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ impl From<CmdCow> for RevealOpt {
|
|||
let mut target = c.take_first().unwrap_or_default();
|
||||
|
||||
if !c.bool("raw") {
|
||||
target = expand_url(target).into();
|
||||
target = expand_url(target);
|
||||
}
|
||||
|
||||
if let Some(u) = provider::try_absolute(&target)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ impl From<CmdCow> for TabCreateOpt {
|
|||
};
|
||||
|
||||
if !c.bool("raw") {
|
||||
url = expand_url(url).into();
|
||||
url = expand_url(url);
|
||||
}
|
||||
|
||||
if let Some(u) = provider::try_absolute(&url)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,12 @@ impl TasksProxy {
|
|||
done.future().await;
|
||||
}
|
||||
|
||||
pub fn update_succeed(url: impl Into<UrlBuf>) {
|
||||
emit!(Call(relay!(tasks:update_succeed).with_any("urls", vec![url.into()])));
|
||||
pub fn update_succeed<I>(url: I)
|
||||
where
|
||||
I: IntoIterator,
|
||||
I::Item: Into<UrlBuf>,
|
||||
{
|
||||
let urls: Vec<_> = url.into_iter().map(Into::into).collect();
|
||||
emit!(Call(relay!(tasks:update_succeed).with_any("urls", urls)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use yazi_shared::{path::PathCow, timestamp_us, url::{AsUrl, UrlBuf, UrlCow, UrlL
|
|||
use yazi_vfs::{VfsCha, maybe_exists, must_be_dir, provider::{self, DirEntry}, unique_name};
|
||||
|
||||
use super::{FileInCopy, FileInDelete, FileInHardlink, FileInLink, FileInTrash};
|
||||
use crate::{LOW, NORMAL, TaskIn, TaskOp, TaskOps, ctx, file::{FileInCut, FileInDownload, FileInUpload, FileOutCopy, FileOutCopyDo, FileOutCut, FileOutCutDo, FileOutDelete, FileOutDeleteDo, FileOutDownload, FileOutDownloadDo, FileOutHardlink, FileOutHardlinkDo, FileOutLink, FileOutTrash, FileOutUpload, FileOutUploadDo}, hook::HookInOutCut, ok_or_not_found, progress_or_break};
|
||||
use crate::{LOW, NORMAL, TaskIn, TaskOp, TaskOps, ctx, file::{FileInCut, FileInDownload, FileInUpload, FileOutCopy, FileOutCopyDo, FileOutCut, FileOutCutDo, FileOutDelete, FileOutDeleteDo, FileOutDownload, FileOutDownloadDo, FileOutHardlink, FileOutHardlinkDo, FileOutLink, FileOutTrash, FileOutUpload, FileOutUploadDo}, hook::{HookInOutCopy, HookInOutCut}, ok_or_not_found, progress_or_break};
|
||||
|
||||
pub(crate) struct File {
|
||||
ops: TaskOps,
|
||||
|
|
@ -33,6 +33,7 @@ impl File {
|
|||
.context("Cannot determine unique destination name")?;
|
||||
}
|
||||
|
||||
self.ops.out(id, HookInOutCopy::from(&task));
|
||||
super::traverse::<FileOutCopy, _, _, _, _, _>(
|
||||
task,
|
||||
async |dir| match provider::create_dir(dir).await {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ pub(crate) enum FileOutCopy {
|
|||
Deform(String),
|
||||
Succ,
|
||||
Fail(String),
|
||||
Clean,
|
||||
}
|
||||
|
||||
impl From<anyhow::Error> for FileOutCopy {
|
||||
|
|
@ -39,6 +40,9 @@ impl FileOutCopy {
|
|||
prog.collected = Some(false);
|
||||
task.log(reason);
|
||||
}
|
||||
Self::Clean => {
|
||||
prog.cleaned = Some(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ pub struct FileProgCopy {
|
|||
pub total_bytes: u64,
|
||||
pub processed_bytes: u64,
|
||||
pub collected: Option<bool>,
|
||||
pub cleaned: Option<bool>,
|
||||
}
|
||||
|
||||
impl From<FileProgCopy> for TaskSummary {
|
||||
|
|
@ -29,14 +30,16 @@ impl FileProgCopy {
|
|||
}
|
||||
|
||||
pub fn running(self) -> bool {
|
||||
self.collected.is_none() || self.success_files + self.failed_files != self.total_files
|
||||
self.collected.is_none()
|
||||
|| self.success_files + self.failed_files != self.total_files
|
||||
|| (self.cleaned.is_none() && self.cooked())
|
||||
}
|
||||
|
||||
pub fn success(self) -> bool { self.cooked() }
|
||||
pub fn success(self) -> bool { self.cleaned == Some(true) && self.cooked() }
|
||||
|
||||
pub fn failed(self) -> bool { self.collected == Some(false) }
|
||||
pub fn failed(self) -> bool { self.cleaned == Some(false) || self.collected == Some(false) }
|
||||
|
||||
pub fn cleaned(self) -> Option<bool> { None }
|
||||
pub fn cleaned(self) -> Option<bool> { self.cleaned }
|
||||
|
||||
pub fn percent(self) -> Option<f32> {
|
||||
Some(if self.success() {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use yazi_fs::ok_or_not_found;
|
|||
use yazi_proxy::TasksProxy;
|
||||
use yazi_vfs::provider;
|
||||
|
||||
use crate::{Ongoing, TaskOp, TaskOps, file::{FileOutCut, FileOutDelete, FileOutDownload, FileOutTrash}, hook::{HookInOutCut, HookInOutDelete, HookInOutDownload, HookInOutTrash}};
|
||||
use crate::{Ongoing, TaskOp, TaskOps, file::{FileOutCopy, FileOutCut, FileOutDelete, FileOutDownload, FileOutTrash}, hook::{HookInOutCopy, HookInOutCut, HookInOutDelete, HookInOutDownload, HookInOutTrash}};
|
||||
|
||||
pub(crate) struct Hook {
|
||||
ops: TaskOps,
|
||||
|
|
@ -26,19 +26,29 @@ impl Hook {
|
|||
}
|
||||
|
||||
let result = ok_or_not_found(provider::remove_dir_clean(&task.from).await);
|
||||
Pump::push_move(&task.from, &task.to);
|
||||
TasksProxy::update_succeed([&task.to, &task.from]);
|
||||
Pump::push_move(task.from, task.to);
|
||||
|
||||
self.ops.out(task.id, FileOutCut::Clean(result));
|
||||
}
|
||||
|
||||
pub(crate) async fn copy(&self, task: HookInOutCopy) {
|
||||
if self.ongoing.lock().intact(task.id) {
|
||||
TasksProxy::update_succeed([&task.to]);
|
||||
Pump::push_duplicate(task.from, task.to);
|
||||
}
|
||||
|
||||
self.ops.out(task.id, FileOutCopy::Clean);
|
||||
}
|
||||
|
||||
pub(crate) async fn delete(&self, task: HookInOutDelete) {
|
||||
if !self.ongoing.lock().intact(task.id) {
|
||||
return self.ops.out(task.id, FileOutDelete::Clean(Ok(())));
|
||||
}
|
||||
|
||||
let result = ok_or_not_found(provider::remove_dir_all(&task.target).await);
|
||||
TasksProxy::update_succeed(&task.target);
|
||||
Pump::push_delete(&task.target);
|
||||
TasksProxy::update_succeed([&task.target]);
|
||||
Pump::push_delete(task.target);
|
||||
|
||||
self.ops.out(task.id, FileOutDelete::Clean(result));
|
||||
}
|
||||
|
|
@ -46,8 +56,8 @@ impl Hook {
|
|||
pub(crate) async fn trash(&self, task: HookInOutTrash) {
|
||||
let intact = self.ongoing.lock().intact(task.id);
|
||||
if intact {
|
||||
TasksProxy::update_succeed(&task.target);
|
||||
Pump::push_trash(&task.target);
|
||||
TasksProxy::update_succeed([&task.target]);
|
||||
Pump::push_trash(task.target);
|
||||
}
|
||||
self.ops.out(task.id, FileOutTrash::Clean);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,28 @@
|
|||
use yazi_shared::{Id, url::UrlBuf};
|
||||
|
||||
use crate::{Task, TaskProg, file::FileInCut};
|
||||
use crate::{Task, TaskProg, file::{FileInCopy, FileInCut}};
|
||||
|
||||
// --- Copy
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct HookInOutCopy {
|
||||
pub(crate) id: Id,
|
||||
pub(crate) from: UrlBuf,
|
||||
pub(crate) to: UrlBuf,
|
||||
}
|
||||
|
||||
impl From<&FileInCopy> for HookInOutCopy {
|
||||
fn from(value: &FileInCopy) -> Self {
|
||||
Self { id: value.id, from: value.from.clone(), to: value.to.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
impl HookInOutCopy {
|
||||
pub(crate) fn reduce(self, task: &mut Task) {
|
||||
if let TaskProg::FileCopy(_) = &task.prog {
|
||||
task.hook = Some(self.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Cut
|
||||
#[derive(Debug)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use yazi_shared::Id;
|
||||
|
||||
use crate::{file::{FileInCopy, FileInCut, FileInDelete, FileInDownload, FileInHardlink, FileInLink, FileInTrash, FileInUpload}, hook::{HookInOutCut, HookInOutDelete, HookInOutDownload, HookInOutTrash}, impl_from_in, plugin::PluginInEntry, prework::{PreworkInFetch, PreworkInLoad, PreworkInSize}, process::{ProcessInBg, ProcessInBlock, ProcessInOrphan}};
|
||||
use crate::{file::{FileInCopy, FileInCut, FileInDelete, FileInDownload, FileInHardlink, FileInLink, FileInTrash, FileInUpload}, hook::{HookInOutCopy, HookInOutCut, HookInOutDelete, HookInOutDownload, HookInOutTrash}, impl_from_in, plugin::PluginInEntry, prework::{PreworkInFetch, PreworkInLoad, PreworkInSize}, process::{ProcessInBg, ProcessInBlock, ProcessInOrphan}};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum TaskIn {
|
||||
|
|
@ -24,6 +24,7 @@ pub(crate) enum TaskIn {
|
|||
ProcessOrphan(ProcessInOrphan),
|
||||
ProcessBg(ProcessInBg),
|
||||
// Hook
|
||||
HookCopy(HookInOutCopy),
|
||||
HookCut(HookInOutCut),
|
||||
HookDelete(HookInOutDelete),
|
||||
HookTrash(HookInOutTrash),
|
||||
|
|
@ -40,7 +41,7 @@ impl_from_in! {
|
|||
// Process
|
||||
ProcessBlock(ProcessInBlock), ProcessOrphan(ProcessInOrphan), ProcessBg(ProcessInBg),
|
||||
// Hook
|
||||
HookCut(HookInOutCut), HookDelete(HookInOutDelete), HookTrash(HookInOutTrash), HookDownload(HookInOutDownload),
|
||||
HookCopy(HookInOutCopy), HookCut(HookInOutCut), HookDelete(HookInOutDelete), HookTrash(HookInOutTrash), HookDownload(HookInOutDownload),
|
||||
}
|
||||
|
||||
impl TaskIn {
|
||||
|
|
@ -66,6 +67,7 @@ impl TaskIn {
|
|||
Self::ProcessOrphan(r#in) => r#in.id,
|
||||
Self::ProcessBg(r#in) => r#in.id,
|
||||
// Hook
|
||||
Self::HookCopy(r#in) => r#in.id,
|
||||
Self::HookCut(r#in) => r#in.id,
|
||||
Self::HookDelete(r#in) => r#in.id,
|
||||
Self::HookTrash(r#in) => r#in.id,
|
||||
|
|
@ -95,6 +97,7 @@ impl TaskIn {
|
|||
Self::ProcessOrphan(_) => false,
|
||||
Self::ProcessBg(_) => false,
|
||||
// Hook
|
||||
Self::HookCopy(_) => true,
|
||||
Self::HookCut(_) => true,
|
||||
Self::HookDelete(_) => true,
|
||||
Self::HookTrash(_) => true,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{Task, file::{FileOutCopy, FileOutCopyDo, FileOutCut, FileOutCutDo, FileOutDelete, FileOutDeleteDo, FileOutDownload, FileOutDownloadDo, FileOutHardlink, FileOutHardlinkDo, FileOutLink, FileOutTrash, FileOutUpload, FileOutUploadDo}, hook::{HookInOutCut, HookInOutDelete, HookInOutDownload, HookInOutTrash}, impl_from_out, plugin::PluginOutEntry, prework::{PreworkOutFetch, PreworkOutLoad, PreworkOutSize}, process::{ProcessOutBg, ProcessOutBlock, ProcessOutOrphan}};
|
||||
use crate::{Task, file::{FileOutCopy, FileOutCopyDo, FileOutCut, FileOutCutDo, FileOutDelete, FileOutDeleteDo, FileOutDownload, FileOutDownloadDo, FileOutHardlink, FileOutHardlinkDo, FileOutLink, FileOutTrash, FileOutUpload, FileOutUploadDo}, hook::{HookInOutCopy, HookInOutCut, HookInOutDelete, HookInOutDownload, HookInOutTrash}, impl_from_out, plugin::PluginOutEntry, prework::{PreworkOutFetch, PreworkOutLoad, PreworkOutSize}, process::{ProcessOutBg, ProcessOutBlock, ProcessOutOrphan}};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) enum TaskOut {
|
||||
|
|
@ -28,6 +28,7 @@ pub(super) enum TaskOut {
|
|||
ProcessOrphan(ProcessOutOrphan),
|
||||
ProcessBg(ProcessOutBg),
|
||||
// Hook
|
||||
HookCopy(HookInOutCopy),
|
||||
HookCut(HookInOutCut),
|
||||
HookDelete(HookInOutDelete),
|
||||
HookTrash(HookInOutTrash),
|
||||
|
|
@ -44,7 +45,7 @@ impl_from_out! {
|
|||
// Process
|
||||
ProcessBlock(ProcessOutBlock), ProcessOrphan(ProcessOutOrphan), ProcessBg(ProcessOutBg),
|
||||
// Hook
|
||||
HookCut(HookInOutCut), HookDelete(HookInOutDelete), HookTrash(HookInOutTrash), HookDownload(HookInOutDownload),
|
||||
HookCopy(HookInOutCopy), HookCut(HookInOutCut), HookDelete(HookInOutDelete), HookTrash(HookInOutTrash), HookDownload(HookInOutDownload),
|
||||
}
|
||||
|
||||
impl TaskOut {
|
||||
|
|
@ -76,6 +77,7 @@ impl TaskOut {
|
|||
Self::ProcessOrphan(out) => out.reduce(task),
|
||||
Self::ProcessBg(out) => out.reduce(task),
|
||||
// Hook
|
||||
Self::HookCopy(out) => out.reduce(task),
|
||||
Self::HookCut(out) => out.reduce(task),
|
||||
Self::HookDelete(out) => out.reduce(task),
|
||||
Self::HookTrash(out) => out.reduce(task),
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ impl Runner {
|
|||
TaskIn::ProcessOrphan(r#in) => self.process.orphan(r#in).await.map_err(Into::into),
|
||||
TaskIn::ProcessBg(r#in) => self.process.bg(r#in).await.map_err(Into::into),
|
||||
// Hook
|
||||
TaskIn::HookCopy(r#in) => Ok(self.hook.copy(r#in).await),
|
||||
TaskIn::HookCut(r#in) => Ok(self.hook.cut(r#in).await),
|
||||
TaskIn::HookDelete(r#in) => Ok(self.hook.delete(r#in).await),
|
||||
TaskIn::HookTrash(r#in) => Ok(self.hook.trash(r#in).await),
|
||||
|
|
@ -63,6 +64,7 @@ impl Runner {
|
|||
TaskIn::ProcessOrphan(_in) => unreachable!(),
|
||||
TaskIn::ProcessBg(_in) => unreachable!(),
|
||||
// Hook
|
||||
TaskIn::HookCopy(_in) => unreachable!(),
|
||||
TaskIn::HookCut(_in) => unreachable!(),
|
||||
TaskIn::HookDelete(_in) => unreachable!(),
|
||||
TaskIn::HookTrash(_in) => unreachable!(),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue