refactor: prepare for custom VFS provider

This commit is contained in:
sxyazi 2026-03-31 18:25:23 +08:00
parent 935eb6b298
commit 35ad31180f
No known key found for this signature in database
219 changed files with 2916 additions and 2414 deletions

421
Cargo.lock generated
View file

@ -35,7 +35,7 @@ checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cipher", "cipher",
"cpufeatures", "cpufeatures 0.2.17",
] ]
[[package]] [[package]]
@ -197,7 +197,7 @@ checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072"
dependencies = [ dependencies = [
"base64ct", "base64ct",
"blake2", "blake2",
"cpufeatures", "cpufeatures 0.2.17",
"password-hash", "password-hash",
] ]
@ -433,7 +433,7 @@ version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be"
dependencies = [ dependencies = [
"hybrid-array", "hybrid-array 0.4.8",
] ]
[[package]] [[package]]
@ -541,9 +541,9 @@ dependencies = [
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.2.57" version = "1.2.58"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1"
dependencies = [ dependencies = [
"find-msvc-tools", "find-msvc-tools",
"jobserver", "jobserver",
@ -571,7 +571,7 @@ checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cipher", "cipher",
"cpufeatures", "cpufeatures 0.2.17",
] ]
[[package]] [[package]]
@ -757,17 +757,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 = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "core-models"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0940496e5c83c54f3b753d5317daec82e8edac71c33aaa1f666d76f518de2444"
dependencies = [
"hax-lib",
"pastey",
"rand 0.9.2",
]
[[package]] [[package]]
name = "core2" name = "core2"
version = "0.4.0" version = "0.4.0"
@ -786,6 +775,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "cpufeatures"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "crc32fast" name = "crc32fast"
version = "1.5.0" version = "1.5.0"
@ -924,7 +922,7 @@ 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 = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710"
dependencies = [ dependencies = [
"hybrid-array", "hybrid-array 0.4.8",
] ]
[[package]] [[package]]
@ -973,7 +971,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures 0.2.17",
"curve25519-dalek-derive", "curve25519-dalek-derive",
"digest 0.10.7", "digest 0.10.7",
"fiat-crypto", "fiat-crypto",
@ -1800,43 +1798,6 @@ dependencies = [
"serde_core", "serde_core",
] ]
[[package]]
name = "hax-lib"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74d9ba66d1739c68e0219b2b2238b5c4145f491ebf181b9c6ab561a19352ae86"
dependencies = [
"hax-lib-macros",
"num-bigint",
"num-traits",
]
[[package]]
name = "hax-lib-macros"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24ba777a231a58d1bce1d68313fa6b6afcc7966adef23d60f45b8a2b9b688bf1"
dependencies = [
"hax-lib-macros-types",
"proc-macro-error2",
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "hax-lib-macros-types"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "867e19177d7425140b417cd27c2e05320e727ee682e98368f88b7194e80ad515"
dependencies = [
"proc-macro2",
"quote",
"serde",
"serde_json",
"uuid",
]
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.5.0" version = "0.5.0"
@ -1879,6 +1840,15 @@ dependencies = [
"digest 0.10.7", "digest 0.10.7",
] ]
[[package]]
name = "hybrid-array"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2d35805454dc9f8662a98d6d61886ffe26bd465f5960e0e55345c70d5c0d2a9"
dependencies = [
"typenum",
]
[[package]] [[package]]
name = "hybrid-array" name = "hybrid-array"
version = "0.4.8" version = "0.4.8"
@ -2059,7 +2029,7 @@ dependencies = [
"rsa", "rsa",
"sec1", "sec1",
"sha1 0.10.6", "sha1 0.10.6",
"sha1 0.11.0-rc.5", "sha1 0.11.0",
"sha2 0.10.9", "sha2 0.10.9",
"signature 2.2.0", "signature 2.2.0",
"signature 3.0.0-rc.6", "signature 3.0.0-rc.6",
@ -2113,10 +2083,12 @@ dependencies = [
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.91" version = "0.3.92"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" checksum = "cc4c90f45aa2e6eacbe8645f77fdea542ac97a494bcd117a67df9ff4d611f995"
dependencies = [ dependencies = [
"cfg-if",
"futures-util",
"once_cell", "once_cell",
"wasm-bindgen", "wasm-bindgen",
] ]
@ -2132,6 +2104,25 @@ dependencies = [
"thiserror 2.0.18", "thiserror 2.0.18",
] ]
[[package]]
name = "keccak"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653"
dependencies = [
"cpufeatures 0.2.17",
]
[[package]]
name = "kem"
version = "0.3.0-pre.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b8645470337db67b01a7f966decf7d0bafedbae74147d33e641c67a91df239f"
dependencies = [
"rand_core 0.6.4",
"zeroize",
]
[[package]] [[package]]
name = "kqueue" name = "kqueue"
version = "1.1.1" version = "1.1.1"
@ -2185,72 +2176,6 @@ version = "0.2.183"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
[[package]]
name = "libcrux-intrinsics"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc9ee7ef66569dd7516454fe26de4e401c0c62073929803486b96744594b9632"
dependencies = [
"core-models",
"hax-lib",
]
[[package]]
name = "libcrux-ml-kem"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bb6a88086bf11bd2ec90926c749c4a427f2e59841437dbdede8cde8a96334ab"
dependencies = [
"hax-lib",
"libcrux-intrinsics",
"libcrux-platform",
"libcrux-secrets",
"libcrux-sha3",
"libcrux-traits",
"rand 0.9.2",
"tls_codec",
]
[[package]]
name = "libcrux-platform"
version = "0.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db82d058aa76ea315a3b2092f69dfbd67ddb0e462038a206e1dcd73f058c0778"
dependencies = [
"libc",
]
[[package]]
name = "libcrux-secrets"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e4dbbf6bc9f2bc0f20dc3bea3e5c99adff3bdccf6d2a40488963da69e2ec307"
dependencies = [
"hax-lib",
]
[[package]]
name = "libcrux-sha3"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2400bec764d1c75b8a496d5747cffe32f1fb864a12577f0aca2f55a92021c962"
dependencies = [
"hax-lib",
"libcrux-intrinsics",
"libcrux-platform",
"libcrux-traits",
]
[[package]]
name = "libcrux-traits"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9adfd58e79d860f6b9e40e35127bfae9e5bd3ade33201d1347459011a2add034"
dependencies = [
"libcrux-secrets",
"rand 0.9.2",
]
[[package]] [[package]]
name = "libfuzzer-sys" name = "libfuzzer-sys"
version = "0.4.12" version = "0.4.12"
@ -2278,9 +2203,9 @@ dependencies = [
[[package]] [[package]]
name = "line-clipping" name = "line-clipping"
version = "0.3.5" version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f4de44e98ddbf09375cbf4d17714d18f39195f4f4894e8524501726fd9a8a4a" checksum = "3f50e8f47623268b5407192d26876c4d7f89d686ca130fdc53bced4814cd29f8"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
] ]
@ -2428,9 +2353,9 @@ dependencies = [
[[package]] [[package]]
name = "mio" name = "mio"
version = "1.1.1" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
dependencies = [ dependencies = [
"libc", "libc",
"log", "log",
@ -2438,6 +2363,18 @@ dependencies = [
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
[[package]]
name = "ml-kem"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de49b3df74c35498c0232031bb7e85f9389f913e2796169c8ab47a53993a18f"
dependencies = [
"hybrid-array 0.2.3",
"kem",
"rand_core 0.6.4",
"sha3",
]
[[package]] [[package]]
name = "mlua" name = "mlua"
version = "0.11.6" version = "0.11.6"
@ -2789,9 +2726,9 @@ dependencies = [
[[package]] [[package]]
name = "ordered-float" name = "ordered-float"
version = "5.1.0" version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d" checksum = "0218004a4aae742209bee9c3cef05672f6b2708be36a50add8eb613b1f2a4008"
dependencies = [ dependencies = [
"num-traits", "num-traits",
"rand 0.8.5", "rand 0.8.5",
@ -3151,7 +3088,7 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf"
dependencies = [ dependencies = [
"cpufeatures", "cpufeatures 0.2.17",
"opaque-debug", "opaque-debug",
"universal-hash", "universal-hash",
] ]
@ -3163,7 +3100,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures 0.2.17",
"opaque-debug", "opaque-debug",
"universal-hash", "universal-hash",
] ]
@ -3283,7 +3220,7 @@ dependencies = [
"bytemuck", "bytemuck",
"libm", "libm",
"num-traits", "num-traits",
"ordered-float 5.1.0", "ordered-float 5.2.0",
"palette", "palette",
"ref-cast", "ref-cast",
"wide", "wide",
@ -3428,7 +3365,7 @@ dependencies = [
"kasuari", "kasuari",
"lru", "lru",
"serde", "serde",
"strum", "strum 0.27.2",
"thiserror 2.0.18", "thiserror 2.0.18",
"unicode-segmentation", "unicode-segmentation",
"unicode-truncate", "unicode-truncate",
@ -3493,7 +3430,7 @@ dependencies = [
"line-clipping", "line-clipping",
"ratatui-core", "ratatui-core",
"serde", "serde",
"strum", "strum 0.27.2",
"time", "time",
"unicode-segmentation", "unicode-segmentation",
"unicode-width", "unicode-width",
@ -3680,7 +3617,7 @@ dependencies = [
"pkcs1", "pkcs1",
"pkcs8 0.11.0-rc.11", "pkcs8 0.11.0-rc.11",
"rand_core 0.10.0-rc-3", "rand_core 0.10.0-rc-3",
"sha2 0.11.0-rc.5", "sha2 0.11.0",
"signature 3.0.0-rc.6", "signature 3.0.0-rc.6",
"spki 0.8.0-rc.4", "spki 0.8.0-rc.4",
"zeroize", "zeroize",
@ -3688,9 +3625,9 @@ dependencies = [
[[package]] [[package]]
name = "russh" name = "russh"
version = "0.58.0" version = "0.58.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30f6ce4f5d5105b934cfb4b8b3028aab4d5dcdff863cb8dda9edd06d39b8c4e8" checksum = "68d53bd2e1d6c49e32ae183c09bdc710ace41e7c8c564cc8a2286aad3bffe10d"
dependencies = [ dependencies = [
"aes", "aes",
"bitflags 2.11.0", "bitflags 2.11.0",
@ -3715,9 +3652,9 @@ dependencies = [
"hmac", "hmac",
"inout", "inout",
"internal-russh-forked-ssh-key", "internal-russh-forked-ssh-key",
"libcrux-ml-kem",
"log", "log",
"md5", "md5",
"ml-kem",
"num-bigint", "num-bigint",
"p256", "p256",
"p384", "p384",
@ -4027,18 +3964,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures 0.2.17",
"digest 0.10.7", "digest 0.10.7",
] ]
[[package]] [[package]]
name = "sha1" name = "sha1"
version = "0.11.0-rc.5" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b167252f3c126be0d8926639c4c4706950f01445900c4b3db0fd7e89fcb750a" checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures 0.3.0",
"digest 0.11.2", "digest 0.11.2",
] ]
@ -4049,21 +3986,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures 0.2.17",
"digest 0.10.7", "digest 0.10.7",
] ]
[[package]] [[package]]
name = "sha2" name = "sha2"
version = "0.11.0-rc.5" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024" checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures 0.3.0",
"digest 0.11.2", "digest 0.11.2",
] ]
[[package]]
name = "sha3"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60"
dependencies = [
"digest 0.10.7",
"keccak",
]
[[package]] [[package]]
name = "sharded-slab" name = "sharded-slab"
version = "0.1.7" version = "0.1.7"
@ -4154,9 +4101,9 @@ dependencies = [
[[package]] [[package]]
name = "simd-adler32" name = "simd-adler32"
version = "0.3.8" version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
[[package]] [[package]]
name = "simd_helpers" name = "simd_helpers"
@ -4280,7 +4227,16 @@ version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
dependencies = [ dependencies = [
"strum_macros", "strum_macros 0.27.2",
]
[[package]]
name = "strum"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd"
dependencies = [
"strum_macros 0.28.0",
] ]
[[package]] [[package]]
@ -4295,6 +4251,18 @@ dependencies = [
"syn 2.0.117", "syn 2.0.117",
] ]
[[package]]
name = "strum_macros"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]] [[package]]
name = "subtle" name = "subtle"
version = "2.6.1" version = "2.6.1"
@ -4540,27 +4508,6 @@ dependencies = [
"time-core", "time-core",
] ]
[[package]]
name = "tls_codec"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0de2e01245e2bb89d6f05801c564fa27624dbd7b1846859876c7dad82e90bf6b"
dependencies = [
"tls_codec_derive",
"zeroize",
]
[[package]]
name = "tls_codec_derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d2e76690929402faae40aebdda620a2c0e25dd6d3b9afe48867dfd95991f4bd"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.50.0" version = "1.50.0"
@ -4784,9 +4731,9 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.13.1" version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da36089a805484bcccfffe0739803392c8298778a2d2f09febf76fac5ad9025b" checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c"
[[package]] [[package]]
name = "unicode-truncate" name = "unicode-truncate"
@ -4841,9 +4788,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "1.22.0" version = "1.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9"
dependencies = [ dependencies = [
"atomic", "atomic",
"getrandom 0.4.2", "getrandom 0.4.2",
@ -4969,9 +4916,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.114" version = "0.2.115"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" checksum = "6523d69017b7633e396a89c5efab138161ed5aafcbc8d3e5c5a42ae38f50495a"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"once_cell", "once_cell",
@ -4982,23 +4929,19 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-futures" name = "wasm-bindgen-futures"
version = "0.4.64" version = "0.4.65"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8" checksum = "2d1faf851e778dfa54db7cd438b70758eba9755cb47403f3496edd7c8fc212f0"
dependencies = [ dependencies = [
"cfg-if",
"futures-util",
"js-sys", "js-sys",
"once_cell",
"wasm-bindgen", "wasm-bindgen",
"web-sys",
] ]
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.114" version = "0.2.115"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" checksum = "4e3a6c758eb2f701ed3d052ff5737f5bfe6614326ea7f3bbac7156192dc32e67"
dependencies = [ dependencies = [
"quote", "quote",
"wasm-bindgen-macro-support", "wasm-bindgen-macro-support",
@ -5006,9 +4949,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro-support" name = "wasm-bindgen-macro-support"
version = "0.2.114" version = "0.2.115"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" checksum = "921de2737904886b52bcbb237301552d05969a6f9c40d261eb0533c8b055fedf"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"proc-macro2", "proc-macro2",
@ -5019,9 +4962,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-shared" name = "wasm-bindgen-shared"
version = "0.2.114" version = "0.2.115"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" checksum = "a93e946af942b58934c604527337bad9ae33ba1d5c6900bbb41c2c07c2364a93"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -5060,16 +5003,6 @@ dependencies = [
"semver", "semver",
] ]
[[package]]
name = "web-sys"
version = "0.3.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]] [[package]]
name = "weezl" name = "weezl"
version = "0.1.12" version = "0.1.12"
@ -5665,6 +5598,7 @@ dependencies = [
"yazi-parser", "yazi-parser",
"yazi-plugin", "yazi-plugin",
"yazi-proxy", "yazi-proxy",
"yazi-runner",
"yazi-scheduler", "yazi-scheduler",
"yazi-shared", "yazi-shared",
"yazi-term", "yazi-term",
@ -5814,10 +5748,17 @@ version = "26.2.2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"crossterm 0.29.0", "crossterm 0.29.0",
"dyn-clone",
"hashbrown 0.16.1", "hashbrown 0.16.1",
"indexmap 2.13.0", "indexmap 2.13.0",
"mlua",
"ordered-float 5.2.0",
"parking_lot", "parking_lot",
"ratatui", "ratatui",
"serde",
"serde_with",
"strum 0.28.0",
"syntect",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"tokio-util", "tokio-util",
@ -5830,11 +5771,11 @@ dependencies = [
"yazi-emulator", "yazi-emulator",
"yazi-fs", "yazi-fs",
"yazi-macro", "yazi-macro",
"yazi-parser", "yazi-prebuilt",
"yazi-plugin", "yazi-runner",
"yazi-proxy",
"yazi-scheduler", "yazi-scheduler",
"yazi-shared", "yazi-shared",
"yazi-shim",
"yazi-vfs", "yazi-vfs",
"yazi-watcher", "yazi-watcher",
"yazi-widgets", "yazi-widgets",
@ -5846,8 +5787,9 @@ version = "26.2.2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"hashbrown 0.16.1", "hashbrown 0.16.1",
"indexmap 2.13.0",
"mlua", "mlua",
"ordered-float 5.1.0", "ordered-float 5.2.0",
"parking_lot", "parking_lot",
"paste", "paste",
"serde", "serde",
@ -5861,7 +5803,6 @@ dependencies = [
"yazi-boot", "yazi-boot",
"yazi-fs", "yazi-fs",
"yazi-macro", "yazi-macro",
"yazi-parser",
"yazi-shared", "yazi-shared",
"yazi-widgets", "yazi-widgets",
] ]
@ -5926,6 +5867,8 @@ dependencies = [
"yazi-parser", "yazi-parser",
"yazi-plugin", "yazi-plugin",
"yazi-proxy", "yazi-proxy",
"yazi-runner",
"yazi-scheduler",
"yazi-shared", "yazi-shared",
"yazi-term", "yazi-term",
"yazi-tty", "yazi-tty",
@ -5983,8 +5926,10 @@ dependencies = [
"crossterm 0.29.0", "crossterm 0.29.0",
"dyn-clone", "dyn-clone",
"hashbrown 0.16.1", "hashbrown 0.16.1",
"indexmap 2.13.0",
"mlua", "mlua",
"ordered-float 5.1.0", "ordered-float 5.2.0",
"paste",
"ratatui", "ratatui",
"serde", "serde",
"serde_with", "serde_with",
@ -5992,8 +5937,12 @@ dependencies = [
"yazi-binding", "yazi-binding",
"yazi-boot", "yazi-boot",
"yazi-config", "yazi-config",
"yazi-core",
"yazi-dds",
"yazi-fs", "yazi-fs",
"yazi-macro", "yazi-macro",
"yazi-runner",
"yazi-scheduler",
"yazi-shared", "yazi-shared",
"yazi-vfs", "yazi-vfs",
"yazi-widgets", "yazi-widgets",
@ -6026,13 +5975,15 @@ dependencies = [
"yazi-binding", "yazi-binding",
"yazi-boot", "yazi-boot",
"yazi-config", "yazi-config",
"yazi-core",
"yazi-dds", "yazi-dds",
"yazi-emulator", "yazi-emulator",
"yazi-fs", "yazi-fs",
"yazi-macro", "yazi-macro",
"yazi-parser", "yazi-parser",
"yazi-prebuilt",
"yazi-proxy", "yazi-proxy",
"yazi-runner",
"yazi-scheduler",
"yazi-shared", "yazi-shared",
"yazi-shim", "yazi-shim",
"yazi-term", "yazi-term",
@ -6050,14 +6001,41 @@ checksum = "33232d9116df6415ddfcdf72701b1b7439ce87f240a14723e8dd5d17e7ed5f98"
name = "yazi-proxy" name = "yazi-proxy"
version = "26.2.2" version = "26.2.2"
dependencies = [ dependencies = [
"mlua",
"tokio", "tokio",
"yazi-binding",
"yazi-config", "yazi-config",
"yazi-core",
"yazi-macro", "yazi-macro",
"yazi-parser", "yazi-runner",
"yazi-scheduler",
"yazi-shared", "yazi-shared",
"yazi-widgets", "yazi-widgets",
] ]
[[package]]
name = "yazi-runner"
version = "26.2.2"
dependencies = [
"anyhow",
"dyn-clone",
"hashbrown 0.16.1",
"mlua",
"parking_lot",
"serde",
"thiserror 2.0.18",
"tokio",
"tokio-util",
"tracing",
"yazi-binding",
"yazi-boot",
"yazi-config",
"yazi-dds",
"yazi-fs",
"yazi-macro",
"yazi-shared",
]
[[package]] [[package]]
name = "yazi-scheduler" name = "yazi-scheduler"
version = "26.2.2" version = "26.2.2"
@ -6069,7 +6047,7 @@ dependencies = [
"libc", "libc",
"lru", "lru",
"mlua", "mlua",
"ordered-float 5.1.0", "ordered-float 5.2.0",
"parking_lot", "parking_lot",
"serde", "serde",
"tokio", "tokio",
@ -6080,9 +6058,7 @@ dependencies = [
"yazi-dds", "yazi-dds",
"yazi-fs", "yazi-fs",
"yazi-macro", "yazi-macro",
"yazi-parser", "yazi-runner",
"yazi-plugin",
"yazi-proxy",
"yazi-shared", "yazi-shared",
"yazi-term", "yazi-term",
"yazi-vfs", "yazi-vfs",
@ -6112,7 +6088,7 @@ dependencies = [
"hashbrown 0.16.1", "hashbrown 0.16.1",
"libc", "libc",
"memchr", "memchr",
"ordered-float 5.1.0", "ordered-float 5.2.0",
"parking_lot", "parking_lot",
"percent-encoding", "percent-encoding",
"serde", "serde",
@ -6202,7 +6178,6 @@ dependencies = [
"yazi-dds", "yazi-dds",
"yazi-fs", "yazi-fs",
"yazi-macro", "yazi-macro",
"yazi-proxy",
"yazi-shared", "yazi-shared",
"yazi-vfs", "yazi-vfs",
] ]
@ -6253,20 +6228,6 @@ name = "zeroize"
version = "1.8.2" version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
dependencies = [
"zeroize_derive",
]
[[package]]
name = "zeroize_derive"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]] [[package]]
name = "zmij" name = "zmij"
@ -6291,9 +6252,9 @@ dependencies = [
[[package]] [[package]]
name = "zune-jpeg" name = "zune-jpeg"
version = "0.5.14" version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7a1c0af6e5d8d1363f4994b7a091ccf963d8b694f7da5b0b9cceb82da2c0a6" checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296"
dependencies = [ dependencies = [
"zune-core", "zune-core",
] ]

View file

@ -55,18 +55,19 @@ libc = "0.2.183"
lru = "0.16.3" lru = "0.16.3"
mlua = { version = "0.11.6", features = [ "anyhow", "async", "error-send", "lua55", "macros", "serde" ] } mlua = { version = "0.11.6", features = [ "anyhow", "async", "error-send", "lua55", "macros", "serde" ] }
objc2 = "0.6.4" objc2 = "0.6.4"
ordered-float = { version = "5.1.0", features = [ "serde" ] } ordered-float = { version = "5.2.0", features = [ "serde" ] }
parking_lot = "0.12.5" parking_lot = "0.12.5"
paste = "1.0.15" paste = "1.0.15"
percent-encoding = "2.3.2" percent-encoding = "2.3.2"
rand = { version = "0.9.2", default-features = false, features = [ "os_rng", "small_rng", "std" ] } rand = { version = "0.9.2", default-features = false, features = [ "os_rng", "small_rng", "std" ] }
ratatui = { version = "0.30.0", features = [ "serde", "unstable-rendered-line-info", "unstable-widget-ref" ] } ratatui = { version = "0.30.0", features = [ "serde", "unstable-rendered-line-info", "unstable-widget-ref" ] }
regex = "1.12.3" regex = "1.12.3"
russh = { version = "0.58.0", default-features = false, features = [ "ring", "rsa" ] } russh = { version = "0.58.1", 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.149" serde_json = "1.0.149"
serde_with = "3.18.0" serde_with = "3.18.0"
strum = { version = "0.28.0", features = [ "derive" ] }
syntect = { version = "5.3.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] } syntect = { version = "5.3.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] }
thiserror = "2.0.18" thiserror = "2.0.18"
tokio = { version = "1.50.0", features = [ "full" ] } tokio = { version = "1.50.0", features = [ "full" ] }

View file

@ -1 +1 @@
{"language":"en","words":["Punct","KEYMAP","splitn","crossterm","YAZI","peekable","ratatui","syntect","pbpaste","pbcopy","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","Konsole","Überzug","pkgs","pdftoppm","poppler","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK","btime","nsec","codegen","gethostname","fchmod","fdfind","Rustc","rustc","ffprobe","vframes","luma","obase","outln","errln","tmtheme","twox","cfgs","fstype","objc","rdev","runloop","exfat","rclone","DECRQSS","DECSCUSR","libvterm","Uninit","lockin","rposition","resvg","foldhash","tilded","futs","chdir","hashbrown","JEMALLOC","RUSTFLAGS","RDONLY","GETPATH","fcntl","casefold","inodes","Splatable","casefied","thiserror","memchr","memmem","russh","deadpool","keepalive","nodelay","publickey","deadpool","initing","treelize","TOCTOU","fellback","watchee","Textlike"],"flagWords":[],"version":"0.2"} {"words":["Punct","KEYMAP","splitn","crossterm","YAZI","peekable","ratatui","syntect","pbpaste","pbcopy","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","Konsole","Überzug","pkgs","pdftoppm","poppler","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK","btime","nsec","codegen","gethostname","fchmod","fdfind","Rustc","rustc","ffprobe","vframes","luma","obase","outln","errln","tmtheme","twox","cfgs","fstype","objc","rdev","runloop","exfat","rclone","DECRQSS","DECSCUSR","libvterm","Uninit","lockin","rposition","resvg","foldhash","tilded","futs","chdir","hashbrown","JEMALLOC","RUSTFLAGS","RDONLY","GETPATH","fcntl","casefold","inodes","Splatable","casefied","thiserror","memchr","memmem","russh","deadpool","keepalive","nodelay","publickey","deadpool","initing","treelize","TOCTOU","fellback","watchee","Textlike","sstr"],"flagWords":[],"language":"en","version":"0.2"}

View file

@ -28,6 +28,7 @@ yazi-macro = { path = "../yazi-macro", version = "26.2.2" }
yazi-parser = { path = "../yazi-parser", version = "26.2.2" } yazi-parser = { path = "../yazi-parser", version = "26.2.2" }
yazi-plugin = { path = "../yazi-plugin", version = "26.2.2" } yazi-plugin = { path = "../yazi-plugin", version = "26.2.2" }
yazi-proxy = { path = "../yazi-proxy", version = "26.2.2" } yazi-proxy = { path = "../yazi-proxy", version = "26.2.2" }
yazi-runner = { path = "../yazi-runner", version = "26.2.2" }
yazi-scheduler = { path = "../yazi-scheduler", version = "26.2.2" } yazi-scheduler = { path = "../yazi-scheduler", version = "26.2.2" }
yazi-shared = { path = "../yazi-shared", version = "26.2.2" } yazi-shared = { path = "../yazi-shared", version = "26.2.2" }
yazi-term = { path = "../yazi-term", version = "26.2.2" } yazi-term = { path = "../yazi-term", version = "26.2.2" }

View file

@ -1,5 +1,5 @@
use anyhow::Result; use anyhow::Result;
use yazi_dds::spark::SparkKind; use yazi_parser::spark::SparkKind;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::Ctx; use crate::Ctx;

View file

@ -1,6 +1,7 @@
use anyhow::Result; use anyhow::Result;
use yazi_core::notify::{MessageLevel, MessageOpt};
use yazi_macro::act; use yazi_macro::act;
use yazi_parser::{app::DeprecateOpt, notify::{PushLevel, PushOpt}}; use yazi_parser::app::DeprecateOpt;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -13,10 +14,10 @@ impl Actor for Deprecate {
const NAME: &str = "deprecate"; const NAME: &str = "deprecate";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
act!(notify:push, cx, PushOpt { act!(notify:push, cx, MessageOpt {
title: "Deprecated API".to_owned(), title: "Deprecated API".to_owned(),
content: opt.content.into_owned(), content: opt.content.into_owned(),
level: PushLevel::Warn, level: MessageLevel::Warn,
timeout: std::time::Duration::from_secs(20), timeout: std::time::Duration::from_secs(20),
}) })
} }

View file

@ -1,8 +1,9 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, succ}; use yazi_macro::{act, succ};
use yazi_parser::app::{PluginMode, PluginOpt}; use yazi_parser::app::PluginForm;
use yazi_plugin::loader::LOADER; use yazi_proxy::AppProxy;
use yazi_proxy::{AppProxy, NotifyProxy}; use yazi_runner::{loader::LOADER, plugin::PluginMode};
use yazi_scheduler::NotifyProxy;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -10,11 +11,11 @@ use crate::{Actor, Ctx};
pub struct Plugin; pub struct Plugin;
impl Actor for Plugin { impl Actor for Plugin {
type Options = PluginOpt; type Options = PluginForm;
const NAME: &str = "plugin"; const NAME: &str = "plugin";
fn act(cx: &mut Ctx, mut opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, Self::Options { mut opt }: Self::Options) -> Result<Data> {
let mut hits = false; let mut hits = false;
if let Some(chunk) = LOADER.read().get(&*opt.id) { if let Some(chunk) = LOADER.read().get(&*opt.id) {
hits = true; hits = true;
@ -30,7 +31,7 @@ impl Actor for Plugin {
tokio::spawn(async move { tokio::spawn(async move {
match LOADER.ensure(&opt.id, |_| ()).await { match LOADER.ensure(&opt.id, |_| ()).await {
Ok(()) => AppProxy::plugin_do(opt), Ok(()) => AppProxy::plugin_do(opt),
Err(e) => NotifyProxy::push_error("Plugin load failed", e), Err(e) => NotifyProxy::push_error("Plugin load failed", e.to_string()),
} }
}); });
succ!(); succ!();

View file

@ -5,9 +5,10 @@ use tracing::{error, warn};
use yazi_binding::runtime_mut; use yazi_binding::runtime_mut;
use yazi_dds::Sendable; use yazi_dds::Sendable;
use yazi_macro::succ; use yazi_macro::succ;
use yazi_parser::app::{PluginMode, PluginOpt}; use yazi_parser::app::PluginForm;
use yazi_plugin::{LUA, loader::{LOADER, Loader}}; use yazi_plugin::LUA;
use yazi_proxy::NotifyProxy; use yazi_runner::{loader::{LOADER, Loader}, plugin::PluginMode};
use yazi_scheduler::NotifyProxy;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::{Actor, Ctx, lives::Lives}; use crate::{Actor, Ctx, lives::Lives};
@ -15,18 +16,18 @@ use crate::{Actor, Ctx, lives::Lives};
pub struct PluginDo; pub struct PluginDo;
impl Actor for PluginDo { impl Actor for PluginDo {
type Options = PluginOpt; type Options = PluginForm;
const NAME: &str = "plugin_do"; const NAME: &str = "plugin_do";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, Self::Options { opt }: Self::Options) -> Result<Data> {
let loader = LOADER.read(); let loader = LOADER.read();
let Some(chunk) = loader.get(&*opt.id) else { let Some(chunk) = loader.get(&*opt.id) else {
succ!(warn!("plugin `{}` not found", opt.id)); succ!(warn!("plugin `{}` not found", opt.id));
}; };
if let Err(e) = Loader::compatible_or_error(&opt.id, chunk) { if let Err(e) = Loader::compatible_or_error(&opt.id, chunk) {
succ!(NotifyProxy::push_error("Incompatible plugin", e)); succ!(NotifyProxy::push_error("Incompatible plugin", e.to_string()));
} }
if opt.mode.auto_then(chunk.sync_entry) != PluginMode::Sync { if opt.mode.auto_then(chunk.sync_entry) != PluginMode::Sync {

View file

@ -1,7 +1,7 @@
use anyhow::Result; use anyhow::Result;
use yazi_boot::ARGS; use yazi_boot::ARGS;
use yazi_fs::provider::{Provider, local::Local}; use yazi_fs::provider::{Provider, local::Local};
use yazi_parser::app::QuitOpt; use yazi_parser::app::QuitForm;
use yazi_shared::{data::Data, strand::{StrandBuf, StrandLike, ToStrand}}; use yazi_shared::{data::Data, strand::{StrandBuf, StrandLike, ToStrand}};
use yazi_term::Term; use yazi_term::Term;
@ -10,11 +10,11 @@ use crate::{Actor, Ctx};
pub struct Quit; pub struct Quit;
impl Actor for Quit { impl Actor for Quit {
type Options = QuitOpt; type Options = QuitForm;
const NAME: &str = "quit"; const NAME: &str = "quit";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, Self::Options { opt }: Self::Options) -> Result<Data> {
cx.tasks.shutdown(); cx.tasks.shutdown();
cx.mgr.shutdown(); cx.mgr.shutdown();

View file

@ -1,9 +1,8 @@
use anyhow::Result; use anyhow::Result;
use crossterm::{execute, terminal::SetTitle}; use crossterm::{execute, terminal::SetTitle};
use yazi_actor::Ctx; use yazi_actor::Ctx;
use yazi_dds::spark::SparkKind;
use yazi_macro::succ; use yazi_macro::succ;
use yazi_parser::app::TitleOpt; use yazi_parser::{app::TitleOpt, spark::SparkKind};
use yazi_shared::{Source, data::Data}; use yazi_shared::{Source, data::Data};
use yazi_term::TermState; use yazi_term::TermState;
use yazi_tty::TTY; use yazi_tty::TTY;

View file

@ -1,8 +1,9 @@
use std::{mem, ops::ControlFlow}; use std::{mem, ops::ControlFlow};
use anyhow::Result; use anyhow::Result;
use yazi_core::cmp::CmpItem;
use yazi_macro::{render, succ}; use yazi_macro::{render, succ};
use yazi_parser::cmp::{CmpItem, ShowOpt}; use yazi_parser::cmp::ShowForm;
use yazi_shared::{data::Data, path::{AsPath, PathDyn}, strand::StrandLike}; use yazi_shared::{data::Data, path::{AsPath, PathDyn}, strand::StrandLike};
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -12,11 +13,11 @@ const LIMIT: usize = 30;
pub struct Show; pub struct Show;
impl Actor for Show { impl Actor for Show {
type Options = ShowOpt; type Options = ShowForm;
const NAME: &str = "show"; const NAME: &str = "show";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, Self::Options { opt }: Self::Options) -> Result<Data> {
let cmp = &mut cx.cmp; let cmp = &mut cx.cmp;
if cmp.ticket != opt.ticket { if cmp.ticket != opt.ticket {
succ!(); succ!();

View file

@ -1,9 +1,10 @@
use std::{io, mem}; use std::{io, mem};
use anyhow::Result; use anyhow::Result;
use yazi_core::cmp::{CmpItem, CmpOpt};
use yazi_fs::{path::clean_url, provider::{DirReader, FileHolder}}; use yazi_fs::{path::clean_url, provider::{DirReader, FileHolder}};
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::cmp::{CmpItem, ShowOpt, TriggerOpt}; use yazi_parser::cmp::TriggerOpt;
use yazi_proxy::CmpProxy; use yazi_proxy::CmpProxy;
use yazi_shared::{AnyAsciiChar, BytePredictor, data::Data, natsort, path::{AsPath, PathBufDyn, PathLike}, scheme::{SchemeCow, SchemeLike}, strand::{AsStrand, StrandLike}, url::{UrlBuf, UrlCow, UrlLike}}; use yazi_shared::{AnyAsciiChar, BytePredictor, data::Data, natsort, path::{AsPath, PathBufDyn, PathLike}, scheme::{SchemeCow, SchemeLike}, strand::{AsStrand, StrandLike}, url::{UrlBuf, UrlCow, UrlLike}};
use yazi_vfs::provider; use yazi_vfs::provider;
@ -31,7 +32,7 @@ impl Actor for Trigger {
let ticket = cx.cmp.ticket; let ticket = cx.cmp.ticket;
if cx.cmp.caches.contains_key(&parent) { if cx.cmp.caches.contains_key(&parent) {
return act!(cmp:show, cx, ShowOpt { cache: vec![], cache_name: parent, word, ticket }); return act!(cmp:show, cx, CmpOpt { cache: vec![], cache_name: parent, word, ticket });
} }
cx.cmp.handle = Some(tokio::spawn(async move { cx.cmp.handle = Some(tokio::spawn(async move {
@ -53,7 +54,7 @@ impl Actor for Trigger {
if !cache.is_empty() { if !cache.is_empty() {
cache cache
.sort_unstable_by(|a, b| natsort(a.name.encoded_bytes(), b.name.encoded_bytes(), false)); .sort_unstable_by(|a, b| natsort(a.name.encoded_bytes(), b.name.encoded_bytes(), false));
CmpProxy::show(ShowOpt { cache, cache_name: parent, word, ticket }); CmpProxy::show(CmpOpt { cache, cache_name: parent, word, ticket });
} }
Ok::<_, io::Error>(()) Ok::<_, io::Error>(())

View file

@ -1,7 +1,7 @@
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use anyhow::{Result, anyhow}; use anyhow::{Result, anyhow};
use yazi_core::{Core, mgr::Tabs, tab::{Folder, Tab}, tasks::Tasks}; use yazi_core::{Core, mgr::Tabs, tab::{Folder, Tab}};
use yazi_fs::File; use yazi_fs::File;
use yazi_shared::{Id, Source, event::Action, url::UrlBuf}; use yazi_shared::{Id, Source, event::Action, url::UrlBuf};
use yazi_term::Term; use yazi_term::Term;
@ -119,9 +119,6 @@ impl<'a> Ctx<'a> {
self.tab_mut().hovered_folder_mut() self.tab_mut().hovered_folder_mut()
} }
#[inline]
pub fn tasks(&self) -> &Tasks { &self.tasks }
#[inline] #[inline]
pub fn source(&self) -> Source { if self.level != 1 { Source::Ind } else { self.source } } pub fn source(&self) -> Source { if self.level != 1 { Source::Ind } else { self.source } }
} }

View file

@ -1,7 +1,8 @@
use anyhow::Result; use anyhow::Result;
use mlua::{ErrorContext, ExternalError, IntoLua, Value}; use mlua::{ErrorContext, ExternalError, IntoLua, Value};
use yazi_binding::runtime_scope; use yazi_binding::runtime_scope;
use yazi_dds::{LOCAL, spark::{Spark, SparkKind}}; use yazi_dds::LOCAL;
use yazi_parser::spark::{Spark, SparkKind};
use yazi_plugin::LUA; use yazi_plugin::LUA;
use crate::{Ctx, lives::Lives}; use crate::{Ctx, lives::Lives};

View file

@ -28,6 +28,7 @@ impl Actor for Arrow {
act!(mgr:peek, cx)?; act!(mgr:peek, cx)?;
act!(mgr:watch, cx)?; act!(mgr:watch, cx)?;
// cx.tasks.scheduler.batch.next(); // FIXME: clear user action
succ!(render!()); succ!(render!());
} }
} }

View file

@ -11,7 +11,8 @@ use yazi_dds::Pubsub;
use yazi_fs::{File, FilesOp, Splatter, max_common_root, path::skip_url, provider::{FileBuilder, Provider, local::{Gate, Local}}}; use yazi_fs::{File, FilesOp, Splatter, max_common_root, path::skip_url, provider::{FileBuilder, Provider, local::{Gate, Local}}};
use yazi_macro::{err, succ}; use yazi_macro::{err, succ};
use yazi_parser::VoidOpt; use yazi_parser::VoidOpt;
use yazi_proxy::{AppProxy, NotifyProxy, TasksProxy}; use yazi_proxy::TasksProxy;
use yazi_scheduler::{AppProxy, NotifyProxy};
use yazi_shared::{data::Data, path::PathDyn, strand::{AsStrand, AsStrandJoin, Strand, StrandBuf, StrandLike}, terminal_clear, url::{AsUrl, UrlBuf, UrlCow, UrlLike}}; use yazi_shared::{data::Data, path::PathDyn, strand::{AsStrand, AsStrandJoin, Strand, StrandBuf, StrandLike}, terminal_clear, url::{AsUrl, UrlBuf, UrlCow, UrlLike}};
use yazi_term::YIELD_TO_SUBPROCESS; use yazi_term::YIELD_TO_SUBPROCESS;
use yazi_tty::TTY; use yazi_tty::TTY;

View file

@ -1,6 +1,6 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::act; use yazi_macro::act;
use yazi_parser::mgr::CloseOpt; use yazi_parser::mgr::CloseForm;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -8,15 +8,15 @@ use crate::{Actor, Ctx};
pub struct Close; pub struct Close;
impl Actor for Close { impl Actor for Close {
type Options = CloseOpt; type Options = CloseForm;
const NAME: &str = "close"; const NAME: &str = "close";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, Self::Options { opt }: Self::Options) -> Result<Data> {
if cx.tabs().len() > 1 { if cx.tabs().len() > 1 {
act!(mgr:tab_close, cx, cx.tabs().cursor) act!(mgr:tab_close, cx, cx.tabs().cursor)
} else { } else {
act!(mgr:quit, cx, opt.0) act!(mgr:quit, cx, opt)
} }
} }
} }

View file

@ -1,6 +1,7 @@
use anyhow::Result; use anyhow::Result;
use yazi_core::mgr::DisplaceOpt;
use yazi_macro::succ; use yazi_macro::succ;
use yazi_parser::{VoidOpt, mgr::DisplaceDoOpt}; use yazi_parser::VoidOpt;
use yazi_proxy::MgrProxy; use yazi_proxy::MgrProxy;
use yazi_shared::{data::Data, url::UrlLike}; use yazi_shared::{data::Data, url::UrlLike};
use yazi_vfs::provider; use yazi_vfs::provider;
@ -22,7 +23,7 @@ impl Actor for Displace {
let tab = cx.tab().id; let tab = cx.tab().id;
let from = cx.cwd().to_owned(); let from = cx.cwd().to_owned();
tokio::spawn(async move { tokio::spawn(async move {
MgrProxy::displace_do(tab, DisplaceDoOpt { MgrProxy::displace_do(tab, DisplaceOpt {
to: provider::canonicalize(&from).await.map_err(Into::into), to: provider::canonicalize(&from).await.map_err(Into::into),
from, from,
}); });

View file

@ -1,7 +1,7 @@
use anyhow::{Result, bail}; use anyhow::{Result, bail};
use yazi_fs::FilesOp; use yazi_fs::FilesOp;
use yazi_macro::{act, succ}; use yazi_macro::{act, succ};
use yazi_parser::mgr::{CdSource, DisplaceDoOpt}; use yazi_parser::mgr::{CdSource, DisplaceDoForm};
use yazi_shared::{data::Data, url::UrlLike}; use yazi_shared::{data::Data, url::UrlLike};
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -9,11 +9,11 @@ use crate::{Actor, Ctx};
pub struct DisplaceDo; pub struct DisplaceDo;
impl Actor for DisplaceDo { impl Actor for DisplaceDo {
type Options = DisplaceDoOpt; type Options = DisplaceDoForm;
const NAME: &str = "displace_do"; const NAME: &str = "displace_do";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, Self::Options { opt }: Self::Options) -> Result<Data> {
if cx.cwd() != opt.from { if cx.cwd() != opt.from {
succ!() succ!()
} }

View file

@ -3,9 +3,10 @@ use std::{mem, time::{Duration, Instant}};
use anyhow::Result; use anyhow::Result;
use futures::{StreamExt, stream::FuturesUnordered}; use futures::{StreamExt, stream::FuturesUnordered};
use hashbrown::HashSet; use hashbrown::HashSet;
use yazi_core::mgr::OpenOpt;
use yazi_fs::{File, FsScheme, provider::{Provider, local::Local}}; use yazi_fs::{File, FsScheme, provider::{Provider, local::Local}};
use yazi_macro::succ; use yazi_macro::succ;
use yazi_parser::mgr::{DownloadOpt, OpenOpt}; use yazi_parser::mgr::DownloadOpt;
use yazi_proxy::MgrProxy; use yazi_proxy::MgrProxy;
use yazi_shared::{data::Data, url::{UrlCow, UrlLike}}; use yazi_shared::{data::Data, url::{UrlCow, UrlLike}};
use yazi_vfs::VfsFile; use yazi_vfs::VfsFile;

View file

@ -1,7 +1,7 @@
use anyhow::{Result, bail}; use anyhow::{Result, bail};
use yazi_macro::{act, render, render_and, succ}; use yazi_macro::{act, render, render_and, succ};
use yazi_parser::{VoidOpt, mgr::EscapeOpt}; use yazi_parser::{VoidOpt, mgr::EscapeOpt};
use yazi_proxy::NotifyProxy; use yazi_scheduler::NotifyProxy;
use yazi_shared::{data::Data, url::UrlLike}; use yazi_shared::{data::Data, url::UrlLike};
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};

View file

@ -4,8 +4,9 @@ use anyhow::Result;
use tokio::pin; use tokio::pin;
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream}; use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
use yazi_config::popup::InputCfg; use yazi_config::popup::InputCfg;
use yazi_core::mgr::FilterOpt;
use yazi_macro::succ; use yazi_macro::succ;
use yazi_parser::mgr::FilterOpt; use yazi_parser::mgr::FilterForm;
use yazi_proxy::{InputProxy, MgrProxy}; use yazi_proxy::{InputProxy, MgrProxy};
use yazi_shared::{Debounce, data::Data}; use yazi_shared::{Debounce, data::Data};
use yazi_widgets::input::InputEvent; use yazi_widgets::input::InputEvent;
@ -15,11 +16,11 @@ use crate::{Actor, Ctx};
pub struct Filter; pub struct Filter;
impl Actor for Filter { impl Actor for Filter {
type Options = FilterOpt; type Options = FilterForm;
const NAME: &str = "filter"; const NAME: &str = "filter";
fn act(_: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(_: &mut Ctx, Self::Options { opt }: Self::Options) -> Result<Data> {
let input = InputProxy::show(InputCfg::filter()); let input = InputProxy::show(InputCfg::filter());
tokio::spawn(async move { tokio::spawn(async move {

View file

@ -1,7 +1,7 @@
use anyhow::Result; use anyhow::Result;
use yazi_fs::Filter; use yazi_fs::Filter;
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::mgr::FilterOpt; use yazi_parser::mgr::FilterForm;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -9,11 +9,11 @@ use crate::{Actor, Ctx};
pub struct FilterDo; pub struct FilterDo;
impl Actor for FilterDo { impl Actor for FilterDo {
type Options = FilterOpt; type Options = FilterForm;
const NAME: &str = "filter_do"; const NAME: &str = "filter_do";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, Self::Options { opt }: Self::Options) -> Result<Data> {
let filter = if opt.query.is_empty() { None } else { Some(Filter::new(&opt.query, opt.case)?) }; let filter = if opt.query.is_empty() { None } else { Some(Filter::new(&opt.query, opt.case)?) };
let hovered = cx.hovered().map(|f| f.urn().into()); let hovered = cx.hovered().map(|f| f.urn().into());

View file

@ -4,8 +4,9 @@ use anyhow::Result;
use tokio::pin; use tokio::pin;
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream}; use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
use yazi_config::popup::InputCfg; use yazi_config::popup::InputCfg;
use yazi_core::mgr::FindDoOpt;
use yazi_macro::succ; use yazi_macro::succ;
use yazi_parser::mgr::{FindDoOpt, FindOpt}; use yazi_parser::mgr::FindOpt;
use yazi_proxy::{InputProxy, MgrProxy}; use yazi_proxy::{InputProxy, MgrProxy};
use yazi_shared::{Debounce, data::Data}; use yazi_shared::{Debounce, data::Data};
use yazi_widgets::input::InputEvent; use yazi_widgets::input::InputEvent;

View file

@ -1,7 +1,7 @@
use anyhow::Result; use anyhow::Result;
use yazi_core::tab::Finder; use yazi_core::tab::Finder;
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::mgr::FindDoOpt; use yazi_parser::mgr::FindDoForm;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -9,11 +9,11 @@ use crate::{Actor, Ctx};
pub struct FindDo; pub struct FindDo;
impl Actor for FindDo { impl Actor for FindDo {
type Options = FindDoOpt; type Options = FindDoForm;
const NAME: &str = "find_do"; const NAME: &str = "find_do";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, Self::Options { opt }: Self::Options) -> Result<Data> {
if opt.query.is_empty() { if opt.query.is_empty() {
return act!(mgr:escape_find, cx); return act!(mgr:escape_find, cx);
} }

View file

@ -1,9 +1,8 @@
use anyhow::Result; use anyhow::Result;
use yazi_core::tab::Folder; use yazi_core::tab::Folder;
use yazi_dds::spark::SparkKind;
use yazi_fs::FolderStage; use yazi_fs::FolderStage;
use yazi_macro::{act, render, render_and, succ}; use yazi_macro::{act, render, render_and, succ};
use yazi_parser::mgr::HiddenOpt; use yazi_parser::{mgr::HiddenOpt, spark::SparkKind};
use yazi_shared::{Source, data::Data}; use yazi_shared::{Source, data::Data};
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};

View file

@ -22,18 +22,20 @@ impl Actor for Hover {
} }
// Repos CWD // Repos CWD
tab.current.repos(opt.urn.as_ref().map(Into::into)); render!(tab.current.repos(opt.urn.as_ref().map(Into::into)));
// Turn on tracing // Turn on tracing
if let (Some(h), Some(u)) = (tab.hovered(), opt.urn) if let (Some(h), Some(u)) = (tab.hovered(), opt.urn)
&& h.urn() == u && h.urn() == u
{ {
// `hover(Some)` occurs after user actions, such as create, rename, reveal, etc. // `hover(Some)` occurs after user actions, such as create, rename, reveal, etc.
// At this point, it's intuitive to track the location of the file regardless. // At this point, it's intuitive to track the file location regardless.
tab.current.trace = Some(u.clone()); tab.current.trace = Some(u.clone());
// cx.tasks.scheduler.batch.next();// FIXME: clear user action
} }
// Publish through DDS // Publish through DDS
let tab = tab!(cx);
err!(Pubsub::pub_after_hover(tab.id, tab.hovered().map(|h| &h.url))); err!(Pubsub::pub_after_hover(tab.id, tab.hovered().map(|h| &h.url)));
succ!(); succ!();
} }

View file

@ -1,8 +1,9 @@
use anyhow::Result; use anyhow::Result;
use yazi_boot::ARGS; use yazi_boot::ARGS;
use yazi_core::mgr::OpenDoOpt;
use yazi_fs::File; use yazi_fs::File;
use yazi_macro::{act, succ}; use yazi_macro::{act, succ};
use yazi_parser::mgr::{OpenDoOpt, OpenOpt}; use yazi_parser::mgr::OpenForm;
use yazi_proxy::MgrProxy; use yazi_proxy::MgrProxy;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use yazi_vfs::VfsFile; use yazi_vfs::VfsFile;
@ -12,11 +13,11 @@ use crate::{Actor, Ctx, mgr::Quit};
pub struct Open; pub struct Open;
impl Actor for Open { impl Actor for Open {
type Options = OpenOpt; type Options = OpenForm;
const NAME: &str = "open"; const NAME: &str = "open";
fn act(cx: &mut Ctx, mut opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, Self::Options { mut opt }: Self::Options) -> Result<Data> {
if !opt.interactive && ARGS.chooser_file.is_some() { if !opt.interactive && ARGS.chooser_file.is_some() {
succ!(if !opt.targets.is_empty() { succ!(if !opt.targets.is_empty() {
Quit::with_selected(opt.targets) Quit::with_selected(opt.targets)

View file

@ -2,8 +2,9 @@ use anyhow::Result;
use hashbrown::HashMap; use hashbrown::HashMap;
use yazi_config::{YAZI, popup::PickCfg}; use yazi_config::{YAZI, popup::PickCfg};
use yazi_macro::succ; use yazi_macro::succ;
use yazi_parser::{mgr::OpenDoOpt, tasks::ProcessOpenOpt}; use yazi_parser::mgr::OpenDoForm;
use yazi_proxy::{PickProxy, TasksProxy}; use yazi_proxy::{PickProxy, TasksProxy};
use yazi_scheduler::process::ProcessOpt;
use yazi_shared::{data::Data, url::UrlCow}; use yazi_shared::{data::Data, url::UrlCow};
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -11,11 +12,11 @@ use crate::{Actor, Ctx};
pub struct OpenDo; pub struct OpenDo;
impl Actor for OpenDo { impl Actor for OpenDo {
type Options = OpenDoOpt; type Options = OpenDoForm;
const NAME: &str = "open_do"; const NAME: &str = "open_do";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, Self::Options { opt }: Self::Options) -> Result<Data> {
let targets: Vec<_> = opt let targets: Vec<_> = opt
.targets .targets
.into_iter() .into_iter()
@ -42,13 +43,12 @@ impl Actor for OpenDo {
[UrlCow::default()].into_iter().chain(targets.into_iter().map(|(u, _)| u)).collect(); [UrlCow::default()].into_iter().chain(targets.into_iter().map(|(u, _)| u)).collect();
tokio::spawn(async move { tokio::spawn(async move {
if let Some(choice) = pick.await { if let Some(choice) = pick.await {
TasksProxy::open_shell_compat(ProcessOpenOpt { TasksProxy::open_shell_compat(ProcessOpt {
cwd: opt.cwd, cwd: opt.cwd,
cmd: openers[choice].run.clone().into(), cmd: openers[choice].run.clone().into(),
args: urls, args: urls,
block: openers[choice].block, block: openers[choice].block,
orphan: openers[choice].orphan, orphan: openers[choice].orphan,
done: None,
spread: openers[choice].spread, spread: openers[choice].spread,
}); });
} }
@ -67,13 +67,12 @@ impl OpenDo {
} }
} }
for (opener, args) in openers { for (opener, args) in openers {
cx.tasks.open_shell_compat(ProcessOpenOpt { cx.tasks.open_shell_compat(ProcessOpt {
cwd: cwd.clone(), cwd: cwd.clone(),
cmd: opener.run.clone().into(), cmd: opener.run.clone().into(),
args, args,
block: opener.block, block: opener.block,
orphan: opener.orphan, orphan: opener.orphan,
done: None,
spread: opener.spread, spread: opener.spread,
}); });
} }

View file

@ -20,7 +20,7 @@ impl Actor for Paste {
if mgr.yanked.cut { if mgr.yanked.cut {
cx.core.tasks.file_cut(&mgr.yanked, dest, opt.force); cx.core.tasks.file_cut(&mgr.yanked, dest, opt.force);
mgr.tabs.iter_mut().for_each(|t| _ = t.selected.remove_many(mgr.yanked.iter())); mgr.tabs.iter_mut().for_each(|t| _ = t.selected.remove_many(&*mgr.yanked));
act!(mgr:unyank, cx) act!(mgr:unyank, cx)
} else { } else {
succ!(cx.core.tasks.file_copy(&mgr.yanked, dest, opt.force, opt.follow)); succ!(cx.core.tasks.file_copy(&mgr.yanked, dest, opt.force, opt.follow));

View file

@ -3,9 +3,9 @@ use std::time::Duration;
use anyhow::Result; use anyhow::Result;
use tokio::{select, time}; use tokio::{select, time};
use yazi_config::popup::ConfirmCfg; use yazi_config::popup::ConfirmCfg;
use yazi_dds::spark::SparkKind; use yazi_core::app::QuitOpt;
use yazi_macro::{act, succ}; use yazi_macro::{act, succ};
use yazi_parser::app::QuitOpt; use yazi_parser::{app::QuitForm, spark::SparkKind};
use yazi_proxy::{AppProxy, ConfirmProxy}; use yazi_proxy::{AppProxy, ConfirmProxy};
use yazi_shared::{data::Data, strand::{Strand, StrandLike, ToStrandJoin}, url::AsUrl}; use yazi_shared::{data::Data, strand::{Strand, StrandLike, ToStrandJoin}, url::AsUrl};
@ -14,12 +14,12 @@ use crate::{Actor, Ctx};
pub struct Quit; pub struct Quit;
impl Actor for Quit { impl Actor for Quit {
type Options = QuitOpt; type Options = QuitForm;
const NAME: &str = "quit"; const NAME: &str = "quit";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, Self::Options { opt }: Self::Options) -> Result<Data> {
let ongoing = cx.tasks().ongoing().clone(); let ongoing = cx.tasks.scheduler.ongoing.clone();
let (left, left_names) = { let (left, left_names) = {
let ongoing = ongoing.lock(); let ongoing = ongoing.lock();
(ongoing.len(), ongoing.values().take(11).map(|t| t.name.clone()).collect()) (ongoing.len(), ongoing.values().take(11).map(|t| t.name.clone()).collect())

View file

@ -3,9 +3,9 @@ use yazi_core::tab::Folder;
use yazi_fs::{CWD, Files, FilesOp, cha::Cha}; use yazi_fs::{CWD, Files, FilesOp, cha::Cha};
use yazi_macro::{act, succ}; use yazi_macro::{act, succ};
use yazi_parser::VoidOpt; use yazi_parser::VoidOpt;
use yazi_proxy::MgrProxy;
use yazi_shared::{data::Data, url::{UrlBuf, UrlLike}}; use yazi_shared::{data::Data, url::{UrlBuf, UrlLike}};
use yazi_vfs::{VfsFiles, VfsFilesOp}; use yazi_vfs::{VfsFiles, VfsFilesOp};
use yazi_watcher::MgrProxy;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -29,7 +29,7 @@ impl Actor for Refresh {
act!(mgr:watch, cx)?; act!(mgr:watch, cx)?;
act!(mgr:update_paged, cx)?; act!(mgr:update_paged, cx)?;
cx.tasks().prework_sorted(&cx.current().files); cx.tasks.prework_sorted(&cx.current().files);
succ!(); succ!();
} }
} }

View file

@ -59,11 +59,9 @@ impl Actor for RemoveDo {
t.selected.remove_many(&opt.targets); t.selected.remove_many(&opt.targets);
}); });
for u in &opt.targets { mgr.yanked.remove_many(&opt.targets);
mgr.yanked.remove(u);
}
mgr.yanked.catchup_revision(false); mgr.yanked.catchup_revision(false);
cx.tasks.file_remove(opt.targets, opt.permanently); cx.tasks.file_remove(opt.targets, opt.permanently);
succ!(); succ!();
} }

View file

@ -4,11 +4,13 @@ use anyhow::Result;
use tokio::pin; use tokio::pin;
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream}; use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
use yazi_config::popup::InputCfg; use yazi_config::popup::InputCfg;
use yazi_core::mgr::SearchVia;
use yazi_fs::{FilesOp, cha::Cha}; use yazi_fs::{FilesOp, cha::Cha};
use yazi_macro::{act, succ}; use yazi_macro::{act, succ};
use yazi_parser::{VoidOpt, mgr::{CdSource, SearchOpt, SearchOptVia}}; use yazi_parser::{VoidOpt, mgr::{CdSource, SearchForm}};
use yazi_plugin::external; use yazi_plugin::external;
use yazi_proxy::{InputProxy, MgrProxy, NotifyProxy}; use yazi_proxy::{InputProxy, MgrProxy};
use yazi_scheduler::NotifyProxy;
use yazi_shared::{data::Data, url::{AsUrl, UrlLike}}; use yazi_shared::{data::Data, url::{AsUrl, UrlLike}};
use yazi_widgets::input::InputEvent; use yazi_widgets::input::InputEvent;
@ -17,11 +19,11 @@ use crate::{Actor, Ctx};
pub struct Search; pub struct Search;
impl Actor for Search { impl Actor for Search {
type Options = SearchOpt; type Options = SearchForm;
const NAME: &str = "search"; const NAME: &str = "search";
fn act(cx: &mut Ctx, mut opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, Self::Options { mut opt }: Self::Options) -> Result<Data> {
if let Some(handle) = cx.tab_mut().search.take() { if let Some(handle) = cx.tab_mut().search.take() {
handle.abort(); handle.abort();
} }
@ -43,11 +45,11 @@ impl Actor for Search {
pub struct SearchDo; pub struct SearchDo;
impl Actor for SearchDo { impl Actor for SearchDo {
type Options = SearchOpt; type Options = SearchForm;
const NAME: &str = "search_do"; const NAME: &str = "search_do";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, Self::Options { opt }: Self::Options) -> Result<Data> {
let tab = cx.tab_mut(); let tab = cx.tab_mut();
if let Some(handle) = tab.search.take() { if let Some(handle) = tab.search.take() {
handle.abort(); handle.abort();
@ -61,19 +63,19 @@ impl Actor for SearchDo {
tab.search = Some(tokio::spawn(async move { tab.search = Some(tokio::spawn(async move {
let rx = match opt.via { let rx = match opt.via {
SearchOptVia::Rg => external::rg(external::RgOpt { SearchVia::Rg => external::rg(external::RgOpt {
cwd: cwd.clone(), cwd: cwd.clone(),
hidden, hidden,
subject: opt.subject.into_owned(), subject: opt.subject.into_owned(),
args: opt.args, args: opt.args,
}), }),
SearchOptVia::Rga => external::rga(external::RgaOpt { SearchVia::Rga => external::rga(external::RgaOpt {
cwd: cwd.clone(), cwd: cwd.clone(),
hidden, hidden,
subject: opt.subject.into_owned(), subject: opt.subject.into_owned(),
args: opt.args, args: opt.args,
}), }),
SearchOptVia::Fd => external::fd(external::FdOpt { SearchVia::Fd => external::fd(external::FdOpt {
cwd: cwd.clone(), cwd: cwd.clone(),
hidden, hidden,
subject: opt.subject.into_owned(), subject: opt.subject.into_owned(),

View file

@ -1,8 +1,9 @@
use anyhow::Result; use anyhow::Result;
use mlua::ObjectLike;
use yazi_config::YAZI; use yazi_config::YAZI;
use yazi_macro::succ; use yazi_macro::{act, succ};
use yazi_parser::mgr::SeekOpt; use yazi_parser::mgr::SeekOpt;
use yazi_plugin::isolate; use yazi_runner::{plugin::PluginOpt, previewer::SeekJob};
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -27,7 +28,10 @@ impl Actor for Seek {
succ!(cx.tab_mut().preview.reset()); succ!(cx.tab_mut().preview.reset());
}; };
isolate::seek_sync(&previewer.run, hovered.clone(), opt.units); let job = SeekJob { file: hovered.clone(), units: opt.units };
succ!(); let opt = PluginOpt::new_callback(&*previewer.run.name, move |_, plugin| {
plugin.call_method("seek", job)
});
act!(app:plugin, cx, opt)
} }
} }

View file

@ -3,8 +3,9 @@ use std::borrow::Cow;
use anyhow::Result; use anyhow::Result;
use yazi_config::popup::InputCfg; use yazi_config::popup::InputCfg;
use yazi_macro::{act, succ}; use yazi_macro::{act, succ};
use yazi_parser::{mgr::ShellOpt, tasks::ProcessOpenOpt}; use yazi_parser::mgr::ShellOpt;
use yazi_proxy::{InputProxy, TasksProxy}; use yazi_proxy::{InputProxy, TasksProxy};
use yazi_scheduler::process::ProcessOpt;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use yazi_widgets::input::InputEvent; use yazi_widgets::input::InputEvent;
@ -38,13 +39,12 @@ impl Actor for Shell {
return; return;
} }
TasksProxy::open_shell_compat(ProcessOpenOpt { TasksProxy::open_shell_compat(ProcessOpt {
cwd: cwd.into(), cwd: cwd.into(),
cmd: opt.run.to_string().into(), cmd: opt.run.to_string().into(),
args: selected, args: selected,
block: opt.block, block: opt.block,
orphan: opt.orphan, orphan: opt.orphan,
done: None,
spread: true, spread: true,
}); });
}); });

View file

@ -1,9 +1,8 @@
use anyhow::Result; use anyhow::Result;
use yazi_core::tab::Folder; use yazi_core::tab::Folder;
use yazi_dds::spark::SparkKind;
use yazi_fs::{FilesSorter, FolderStage}; use yazi_fs::{FilesSorter, FolderStage};
use yazi_macro::{act, render, render_and, succ}; use yazi_macro::{act, render, render_and, succ};
use yazi_parser::mgr::SortOpt; use yazi_parser::{mgr::SortOpt, spark::SparkKind};
use yazi_shared::{Source, data::Data}; use yazi_shared::{Source, data::Data};
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};

View file

@ -1,7 +1,6 @@
use anyhow::Result; use anyhow::Result;
use yazi_dds::spark::SparkKind;
use yazi_macro::succ; use yazi_macro::succ;
use yazi_parser::mgr::StashOpt; use yazi_parser::{mgr::StashOpt, spark::SparkKind};
use yazi_shared::{Source, data::Data, url::{AsUrl, UrlLike}}; use yazi_shared::{Source, data::Data, url::{AsUrl, UrlLike}};
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};

View file

@ -2,7 +2,7 @@ use anyhow::Result;
use yazi_core::tab::Tab; use yazi_core::tab::Tab;
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::mgr::{CdSource, TabCreateOpt}; use yazi_parser::mgr::{CdSource, TabCreateOpt};
use yazi_proxy::NotifyProxy; use yazi_scheduler::NotifyProxy;
use yazi_shared::{data::Data, url::UrlLike}; use yazi_shared::{data::Data, url::UrlLike};
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};

View file

@ -1,7 +1,7 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{render_and, succ}; use yazi_macro::{render_and, succ};
use yazi_parser::mgr::ToggleOpt; use yazi_parser::mgr::ToggleOpt;
use yazi_proxy::NotifyProxy; use yazi_scheduler::NotifyProxy;
use yazi_shared::{data::Data, url::UrlCow}; use yazi_shared::{data::Data, url::UrlCow};
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};

View file

@ -1,7 +1,7 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{render, succ}; use yazi_macro::{render, succ};
use yazi_parser::mgr::ToggleAllOpt; use yazi_parser::mgr::ToggleAllOpt;
use yazi_proxy::NotifyProxy; use yazi_scheduler::NotifyProxy;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};

View file

@ -19,7 +19,7 @@ impl Actor for UpdateMimes {
let updates = opt let updates = opt
.updates .updates
.into_iter() .into_iter()
.flat_map(|(key, value)| key.into_url().zip(value.into_string())) .flat_map(|(key, value)| key.into_url().zip(value.into_sstr()))
.filter(|(url, mime)| cx.mgr.mimetype.get(url) != Some(mime)) .filter(|(url, mime)| cx.mgr.mimetype.get(url) != Some(mime))
.fold(HashMap::new(), |mut map, (u, m)| { .fold(HashMap::new(), |mut map, (u, m)| {
for u in linked.from_file(u.as_url()) { for u in linked.from_file(u.as_url()) {

View file

@ -19,8 +19,8 @@ impl Actor for UpdatePaged {
let targets = cx.current().paginate(opt.page.unwrap_or(cx.current().page)); let targets = cx.current().paginate(opt.page.unwrap_or(cx.current().page));
if !targets.is_empty() { if !targets.is_empty() {
cx.tasks().fetch_paged(targets, &cx.mgr.mimetype); cx.tasks.fetch_paged(targets, &cx.mgr.mimetype);
cx.tasks().preload_paged(targets, &cx.mgr.mimetype); cx.tasks.preload_paged(targets, &cx.mgr.mimetype);
} }
succ!(); succ!();
} }

View file

@ -1,6 +1,6 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{render, succ}; use yazi_macro::{render, succ};
use yazi_parser::mgr::UpdatePeekedOpt; use yazi_parser::mgr::UpdatePeekedForm;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -8,17 +8,17 @@ use crate::{Actor, Ctx};
pub struct UpdatePeeked; pub struct UpdatePeeked;
impl Actor for UpdatePeeked { impl Actor for UpdatePeeked {
type Options = UpdatePeekedOpt; type Options = UpdatePeekedForm;
const NAME: &str = "update_peeked"; const NAME: &str = "update_peeked";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, form: Self::Options) -> Result<Data> {
let Some(hovered) = cx.hovered().map(|h| &h.url) else { let Some(hovered) = cx.hovered().map(|h| &h.url) else {
succ!(cx.tab_mut().preview.reset()); succ!(cx.tab_mut().preview.reset());
}; };
if opt.lock.url == *hovered { if form.lock.url == *hovered {
cx.tab_mut().preview.lock = Some(opt.lock); cx.tab_mut().preview.lock = Some(form.lock);
render!(); render!();
} }

View file

@ -1,6 +1,6 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{render, succ}; use yazi_macro::{render, succ};
use yazi_parser::mgr::UpdateSpottedOpt; use yazi_parser::mgr::UpdateSpottedForm;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -8,29 +8,29 @@ use crate::{Actor, Ctx};
pub struct UpdateSpotted; pub struct UpdateSpotted;
impl Actor for UpdateSpotted { impl Actor for UpdateSpotted {
type Options = UpdateSpottedOpt; type Options = UpdateSpottedForm;
const NAME: &str = "update_spotted"; const NAME: &str = "update_spotted";
fn act(cx: &mut Ctx, mut opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, mut form: Self::Options) -> Result<Data> {
let tab = cx.tab_mut(); let tab = cx.tab_mut();
let Some(hovered) = tab.hovered().map(|h| &h.url) else { let Some(hovered) = tab.hovered().map(|h| &h.url) else {
succ!(tab.spot.reset()); succ!(tab.spot.reset());
}; };
if opt.lock.url != *hovered { if form.lock.url != *hovered {
succ!(); succ!();
} }
if tab.spot.lock.as_ref().is_none_or(|l| l.id != opt.lock.id) { if tab.spot.lock.as_ref().is_none_or(|l| l.id != form.lock.id) {
tab.spot.skip = opt.lock.selected().unwrap_or_default(); tab.spot.skip = form.lock.selected().unwrap_or_default();
} else if let Some(s) = opt.lock.selected() { } else if let Some(s) = form.lock.selected() {
tab.spot.skip = s; tab.spot.skip = s;
} else { } else {
opt.lock.select(Some(tab.spot.skip)); form.lock.select(Some(tab.spot.skip));
} }
tab.spot.lock = Some(opt.lock); tab.spot.lock = Some(form.lock);
succ!(render!()); succ!(render!());
} }
} }

View file

@ -18,7 +18,7 @@ impl Actor for UpdateYanked {
succ!(); succ!();
} }
cx.mgr.yanked = Yanked::new(opt.cut, opt.urls.into_owned()); cx.mgr.yanked = Yanked::new(opt.cut, opt.0.urls.into_owned());
succ!(render!()); succ!(render!());
} }
} }

View file

@ -2,9 +2,8 @@ use std::time::Instant;
use anyhow::Result; use anyhow::Result;
use yazi_core::notify::Message; use yazi_core::notify::Message;
use yazi_dds::spark::SparkKind;
use yazi_macro::{act, succ}; use yazi_macro::{act, succ};
use yazi_parser::notify::PushOpt; use yazi_parser::{notify::PushForm, spark::SparkKind};
use yazi_shared::{Source, data::Data}; use yazi_shared::{Source, data::Data};
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -12,14 +11,14 @@ use crate::{Actor, Ctx};
pub struct Push; pub struct Push;
impl Actor for Push { impl Actor for Push {
type Options = PushOpt; type Options = PushForm;
const NAME: &str = "push"; const NAME: &str = "push";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, form: Self::Options) -> Result<Data> {
let instant = Instant::now(); let instant = Instant::now();
let mut msg = Message::from(opt); let mut msg = Message::from(form.opt);
msg.timeout += instant - cx.notify.messages.first().map_or(instant, |m| m.instant); msg.timeout += instant - cx.notify.messages.first().map_or(instant, |m| m.instant);
if cx.notify.messages.iter().all(|m| m != &msg) { if cx.notify.messages.iter().all(|m| m != &msg) {

View file

@ -19,7 +19,7 @@ impl Actor for Tick {
const NAME: &str = "tick"; const NAME: &str = "tick";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
cx.notify.tick_handle.take().map(|h| h.abort()); cx.notify.ticker.take().map(|h| h.abort());
let Dimension { rows, columns, .. } = Dimension::available(); let Dimension { rows, columns, .. } = Dimension::available();
let area = Notify::available(Rect { x: 0, y: 0, width: columns, height: rows }); let area = Notify::available(Rect { x: 0, y: 0, width: columns, height: rows });
@ -55,7 +55,7 @@ impl Actor for Tick {
succ!(render!()); succ!(render!());
}; };
cx.notify.tick_handle = Some(tokio::spawn(async move { cx.notify.ticker = Some(tokio::spawn(async move {
tokio::time::sleep(interval).await; tokio::time::sleep(interval).await;
NotifyProxy::tick(interval); NotifyProxy::tick(interval);
})); }));

View file

@ -15,7 +15,7 @@ impl Actor for Cancel {
fn act(cx: &mut Ctx, _: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, _: Self::Options) -> Result<Data> {
let tasks = &mut cx.tasks; let tasks = &mut cx.tasks;
let id = tasks.ongoing().lock().get_id(tasks.cursor); let id = tasks.scheduler.ongoing.lock().get_id(tasks.cursor);
if id.map(|id| tasks.scheduler.cancel(id)) != Some(true) { if id.map(|id| tasks.scheduler.cancel(id)) != Some(true) {
succ!(); succ!();
} }

View file

@ -7,7 +7,7 @@ use tokio::{io::{AsyncReadExt, stdin}, select, sync::mpsc, time};
use yazi_binding::Permit; use yazi_binding::Permit;
use yazi_macro::succ; use yazi_macro::succ;
use yazi_parser::VoidOpt; use yazi_parser::VoidOpt;
use yazi_proxy::AppProxy; use yazi_scheduler::AppProxy;
use yazi_shared::{data::Data, terminal_clear}; use yazi_shared::{data::Data, terminal_clear};
use yazi_term::YIELD_TO_SUBPROCESS; use yazi_term::YIELD_TO_SUBPROCESS;
use yazi_tty::TTY; use yazi_tty::TTY;
@ -22,7 +22,7 @@ impl Actor for Inspect {
const NAME: &str = "inspect"; const NAME: &str = "inspect";
fn act(cx: &mut Ctx, _: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, _: Self::Options) -> Result<Data> {
let ongoing = cx.tasks.ongoing().clone(); let ongoing = cx.tasks.scheduler.ongoing.clone();
let Some(id) = ongoing.lock().get_id(cx.tasks.cursor) else { let Some(id) = ongoing.lock().get_id(cx.tasks.cursor) else {
succ!(); succ!();
}; };

View file

@ -1,6 +1,6 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::succ; use yazi_macro::succ;
use yazi_parser::tasks::ProcessOpenOpt; use yazi_parser::tasks::ProcessOpenForm;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -9,11 +9,11 @@ pub struct OpenShellCompat;
// TODO: remove // TODO: remove
impl Actor for OpenShellCompat { impl Actor for OpenShellCompat {
type Options = ProcessOpenOpt; type Options = ProcessOpenForm;
const NAME: &str = "open_shell_compat"; const NAME: &str = "open_shell_compat";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, Self::Options { opt, .. }: Self::Options) -> Result<Data> {
succ!(cx.tasks.open_shell_compat(opt)); succ!(cx.tasks.open_shell_compat(opt));
} }
} }

View file

@ -1,6 +1,6 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::succ; use yazi_macro::succ;
use yazi_parser::tasks::ProcessOpenOpt; use yazi_parser::tasks::ProcessOpenForm;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -8,11 +8,19 @@ use crate::{Actor, Ctx};
pub struct ProcessOpen; pub struct ProcessOpen;
impl Actor for ProcessOpen { impl Actor for ProcessOpen {
type Options = ProcessOpenOpt; type Options = ProcessOpenForm;
const NAME: &str = "process_open"; const NAME: &str = "process_open";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, form: Self::Options) -> Result<Data> {
succ!(cx.tasks.scheduler.process_open(opt)); let done = cx.tasks.scheduler.process_open(form.opt);
if let Some(replier) = form.replier {
tokio::spawn(async move {
replier.send(Ok(done.future().await.into())).ok();
});
}
succ!();
} }
} }

View file

@ -13,6 +13,21 @@ impl Actor for UpdateSucceed {
const NAME: &str = "update_succeed"; const NAME: &str = "update_succeed";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
if opt.urls.is_empty() {
succ!();
}
// FIXME: todo!();
// if opt.track
// && opt.batch == cx.tasks.scheduler.batch.current()
// && let Some((parent, urn)) = opt.urls[0].pair()
// && parent == *cx.cwd()
// {
// cx.tasks.scheduler.batch.next();
// cx.current_mut().trace = Some(urn.into());
// act!(mgr:hover, cx)?;
// }
cx.mgr.watcher.report(opt.urls); cx.mgr.watcher.report(opt.urls);
succ!(); succ!();
} }

View file

@ -1,8 +1,7 @@
use anyhow::Result; use anyhow::Result;
use yazi_core::which::WhichSorter; use yazi_core::which::WhichSorter;
use yazi_dds::spark::SparkKind;
use yazi_macro::{render, succ}; use yazi_macro::{render, succ};
use yazi_parser::which::ActivateOpt; use yazi_parser::{spark::SparkKind, which::ActivateForm};
use yazi_shared::{Source, data::Data}; use yazi_shared::{Source, data::Data};
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -10,11 +9,11 @@ use crate::{Actor, Ctx};
pub struct Activate; pub struct Activate;
impl Actor for Activate { impl Actor for Activate {
type Options = ActivateOpt; type Options = ActivateForm;
const NAME: &str = "activate"; const NAME: &str = "activate";
fn act(cx: &mut Ctx, mut opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, Self::Options { mut opt }: Self::Options) -> Result<Data> {
opt.cands.retain(|c| c.on.len() > opt.times); opt.cands.retain(|c| c.on.len() > opt.times);
WhichSorter::default().sort(&mut opt.cands); WhichSorter::default().sort(&mut opt.cands);

View file

@ -57,13 +57,13 @@ impl Dds {
pub(super) fn ensure_ability(peers: &HashMap<Id, Peer>, kind: &str, receiver: Id) -> Result<()> { pub(super) fn ensure_ability(peers: &HashMap<Id, Peer>, kind: &str, receiver: Id) -> Result<()> {
match (receiver, peers.get(&receiver).map(|p| p.able(kind))) { match (receiver, peers.get(&receiver).map(|p| p.able(kind))) {
// Send to all receivers // Send to all receivers
(Id(0), _) if peers.is_empty() => { (Id::ZERO, _) if peers.is_empty() => {
bail!("No receiver found. Check if any receivers are running.") bail!("No receiver found. Check if any receivers are running.")
} }
(Id(0), _) if peers.values().all(|p| !p.able(kind)) => { (Id::ZERO, _) if peers.values().all(|p| !p.able(kind)) => {
bail!("No receiver has the ability to receive `{kind}` messages.") bail!("No receiver has the ability to receive `{kind}` messages.")
} }
(Id(0), _) => Ok(()), (Id::ZERO, _) => Ok(()),
// Send to a specific receiver // Send to a specific receiver
(_, Some(true)) => Ok(()), (_, Some(true)) => Ok(()),

View file

@ -20,11 +20,10 @@ yazi-dds = { path = "../yazi-dds", version = "26.2.2" }
yazi-emulator = { path = "../yazi-emulator", version = "26.2.2" } yazi-emulator = { path = "../yazi-emulator", version = "26.2.2" }
yazi-fs = { path = "../yazi-fs", version = "26.2.2" } yazi-fs = { path = "../yazi-fs", version = "26.2.2" }
yazi-macro = { path = "../yazi-macro", version = "26.2.2" } yazi-macro = { path = "../yazi-macro", version = "26.2.2" }
yazi-parser = { path = "../yazi-parser", version = "26.2.2" } yazi-runner = { path = "../yazi-runner", version = "26.2.2" }
yazi-plugin = { path = "../yazi-plugin", version = "26.2.2" }
yazi-proxy = { path = "../yazi-proxy", version = "26.2.2" }
yazi-scheduler = { path = "../yazi-scheduler", version = "26.2.2" } yazi-scheduler = { path = "../yazi-scheduler", version = "26.2.2" }
yazi-shared = { path = "../yazi-shared", version = "26.2.2" } yazi-shared = { path = "../yazi-shared", version = "26.2.2" }
yazi-shim = { path = "../yazi-shim", version = "26.2.2" }
yazi-vfs = { path = "../yazi-vfs", version = "26.2.2" } yazi-vfs = { path = "../yazi-vfs", version = "26.2.2" }
yazi-watcher = { path = "../yazi-watcher", version = "26.2.2" } yazi-watcher = { path = "../yazi-watcher", version = "26.2.2" }
yazi-widgets = { path = "../yazi-widgets", version = "26.2.2" } yazi-widgets = { path = "../yazi-widgets", version = "26.2.2" }
@ -32,15 +31,23 @@ yazi-widgets = { path = "../yazi-widgets", version = "26.2.2" }
# External dependencies # External dependencies
anyhow = { workspace = true } anyhow = { workspace = true }
crossterm = { workspace = true } crossterm = { workspace = true }
dyn-clone = { workspace = true }
hashbrown = { workspace = true } hashbrown = { workspace = true }
indexmap = { workspace = true } indexmap = { workspace = true }
mlua = { workspace = true }
ordered-float = { workspace = true }
parking_lot = { workspace = true } parking_lot = { workspace = true }
ratatui = { workspace = true } ratatui = { workspace = true }
serde = { workspace = true }
serde_with = { workspace = true }
strum = { workspace = true }
syntect = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }
tokio-stream = { workspace = true } tokio-stream = { workspace = true }
tokio-util = { workspace = true } tokio-util = { workspace = true }
tracing = { workspace = true } tracing = { workspace = true }
unicode-width = { workspace = true } unicode-width = { workspace = true }
yazi-prebuilt = "0.1.0"
[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" ] }

1
yazi-core/src/app/mod.rs Normal file
View file

@ -0,0 +1 @@
yazi_macro::mod_flat!(quit);

32
yazi-core/src/app/quit.rs Normal file
View file

@ -0,0 +1,32 @@
use mlua::{FromLua, IntoLua, Lua, LuaSerdeExt, Value};
use serde::{Deserialize, Serialize};
use yazi_binding::SER_OPT;
use yazi_shared::{event::ActionCow, strand::StrandBuf};
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct QuitOpt {
pub code: i32,
#[serde(skip)]
pub selected: Option<StrandBuf>,
pub no_cwd_file: bool,
}
impl TryFrom<ActionCow> for QuitOpt {
type Error = anyhow::Error;
fn try_from(a: ActionCow) -> Result<Self, Self::Error> {
Ok(Self {
code: a.get("code").unwrap_or_default(),
selected: None,
no_cwd_file: a.bool("no-cwd-file"),
})
}
}
impl FromLua for QuitOpt {
fn from_lua(value: Value, lua: &Lua) -> mlua::Result<Self> { lua.from_value(value) }
}
impl IntoLua for QuitOpt {
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> { lua.to_value_with(&self, SER_OPT) }
}

View file

@ -2,10 +2,11 @@ use std::io;
use hashbrown::HashMap; use hashbrown::HashMap;
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
use yazi_parser::cmp::CmpItem;
use yazi_shared::{Id, url::UrlBuf}; use yazi_shared::{Id, url::UrlBuf};
use yazi_widgets::Scrollable; use yazi_widgets::Scrollable;
use crate::cmp::CmpItem;
#[derive(Default)] #[derive(Default)]
pub struct Cmp { pub struct Cmp {
pub caches: HashMap<UrlBuf, Vec<CmpItem>>, pub caches: HashMap<UrlBuf, Vec<CmpItem>>,

View file

@ -0,0 +1,7 @@
use yazi_shared::strand::StrandBuf;
#[derive(Debug, Clone)]
pub struct CmpItem {
pub name: StrandBuf,
pub is_dir: bool,
}

View file

@ -1 +1 @@
yazi_macro::mod_flat!(cmp); yazi_macro::mod_flat!(cmp item opt);

11
yazi-core/src/cmp/opt.rs Normal file
View file

@ -0,0 +1,11 @@
use yazi_shared::{Id, path::PathBufDyn, url::UrlBuf};
use crate::cmp::CmpItem;
#[derive(Clone, Debug)]
pub struct CmpOpt {
pub cache: Vec<CmpItem>,
pub cache_name: UrlBuf,
pub word: PathBufDyn,
pub ticket: Id,
}

View file

@ -1,10 +1,11 @@
use std::{io::{BufRead, BufReader, Cursor, Seek}, path::PathBuf, sync::OnceLock}; use std::{io::{BufRead, BufReader, Cursor, Seek}, path::PathBuf, sync::OnceLock};
use anyhow::{Result, bail}; use anyhow::{Result, anyhow, bail};
use ratatui::{layout::Size, text::{Line, Span, Text}}; use ratatui::{layout::Size, text::{Line, Span, Text}};
use syntect::{LoadingError, dumps, easy::HighlightLines, highlighting::{self, Theme, ThemeSet}, parsing::{SyntaxReference, SyntaxSet}}; use syntect::{LoadingError, dumps, easy::HighlightLines, highlighting::{self, Theme, ThemeSet}, parsing::{SyntaxReference, SyntaxSet}};
use yazi_config::{THEME, YAZI}; use yazi_config::{THEME, YAZI};
use yazi_shared::{Id, Ids, errors::PeekError, replace_to_printable}; use yazi_runner::previewer::PeekError;
use yazi_shared::{Id, Ids, replace_to_printable};
use yazi_shim::ratatui::LineIter; use yazi_shim::ratatui::LineIter;
static INCR: Ids = Ids::new(); static INCR: Ids = Ids::new();
@ -68,7 +69,7 @@ impl Highlighter {
let mut inspected = 0u16; let mut inspected = 0u16;
while self.reader.read_until(b'\n', &mut buf).is_ok_and(|n| n > 0) { while self.reader.read_until(b'\n', &mut buf).is_ok_and(|n| n > 0) {
if Self::is_binary(&buf, &mut inspected) { if Self::is_binary(&buf, &mut inspected) {
return Err("Binary file".into()); Err(anyhow!("Binary file"))?;
} }
let remaining = Self::normalize_control_chars(&mut buf); let remaining = Self::normalize_control_chars(&mut buf);
@ -86,7 +87,7 @@ impl Highlighter {
} }
if self.skip > 0 && i < self.skip + self.size.height as usize { if self.skip > 0 && i < self.skip + self.size.height as usize {
return Err(PeekError::Exceed(i.saturating_sub(self.size.height as _))); return Err(PeekError::Exceeded(i.saturating_sub(self.size.height as _)));
} }
Ok(Text::from(lines)) Ok(Text::from(lines))
@ -139,7 +140,7 @@ impl Highlighter {
#[inline] #[inline]
fn ensure_not_cancelled(&self) -> Result<(), PeekError> { fn ensure_not_cancelled(&self) -> Result<(), PeekError> {
if self.ticket != INCR.current() { Err("Highlighting cancelled".into()) } else { Ok(()) } if self.ticket != INCR.current() { Err(anyhow!("Highlighting cancelled"))? } else { Ok(()) }
} }
fn load() -> (Theme, SyntaxSet) { fn load() -> (Theme, SyntaxSet) {

View file

@ -1,3 +1,3 @@
yazi_macro::mod_pub!(cmp confirm help input mgr notify pick spot tab tasks which); yazi_macro::mod_pub!(app cmp confirm help input mgr notify pick spot tab tasks which);
yazi_macro::mod_flat!(core); yazi_macro::mod_flat!(core highlighter proxy);

View file

@ -0,0 +1,7 @@
use yazi_shared::url::UrlBuf;
#[derive(Clone, Debug)]
pub struct DisplaceOpt {
pub to: Result<UrlBuf, yazi_fs::error::Error>,
pub from: UrlBuf,
}

View file

@ -0,0 +1,21 @@
use yazi_fs::FilterCase;
use yazi_shared::{SStr, event::ActionCow};
#[derive(Clone, Debug, Default)]
pub struct FilterOpt {
pub query: SStr,
pub case: FilterCase,
pub done: bool,
}
impl TryFrom<ActionCow> for FilterOpt {
type Error = anyhow::Error;
fn try_from(mut a: ActionCow) -> Result<Self, Self::Error> {
Ok(Self {
query: a.take_first().unwrap_or_default(),
case: FilterCase::from(&*a),
done: a.bool("done"),
})
}
}

22
yazi-core/src/mgr/find.rs Normal file
View file

@ -0,0 +1,22 @@
use anyhow::bail;
use yazi_fs::FilterCase;
use yazi_shared::{SStr, event::ActionCow};
#[derive(Clone, Debug)]
pub struct FindDoOpt {
pub query: SStr,
pub prev: bool,
pub case: FilterCase,
}
impl TryFrom<ActionCow> for FindDoOpt {
type Error = anyhow::Error;
fn try_from(mut a: ActionCow) -> Result<Self, Self::Error> {
let Ok(query) = a.take_first() else {
bail!("Invalid 'query' in FindDoOpt");
};
Ok(Self { query, prev: a.bool("previous"), case: FilterCase::from(&*a) })
}
}

View file

@ -1 +1 @@
yazi_macro::mod_flat!(batcher mgr mimetype tabs yanked); yazi_macro::mod_flat!(batcher displace filter find mgr mimetype open search tabs yanked);

30
yazi-core/src/mgr/open.rs Normal file
View file

@ -0,0 +1,30 @@
use yazi_shared::{event::ActionCow, url::UrlCow};
#[derive(Clone, Debug)]
pub struct OpenOpt {
pub cwd: Option<UrlCow<'static>>,
pub targets: Vec<UrlCow<'static>>,
pub interactive: bool,
pub hovered: bool,
}
impl TryFrom<ActionCow> for OpenOpt {
type Error = anyhow::Error;
fn try_from(mut a: ActionCow) -> Result<Self, Self::Error> {
Ok(Self {
cwd: a.take("cwd").ok(),
targets: a.take_seq(),
interactive: a.bool("interactive"),
hovered: a.bool("hovered"),
})
}
}
// OpenDoOpt
#[derive(Clone, Debug, Default)]
pub struct OpenDoOpt {
pub cwd: UrlCow<'static>,
pub targets: Vec<UrlCow<'static>>,
pub interactive: bool,
}

View file

@ -0,0 +1,66 @@
use std::str::FromStr;
use anyhow::bail;
use serde::Deserialize;
use yazi_shared::{SStr, event::ActionCow, url::{UrlCow, UrlLike}};
#[derive(Clone, Debug)]
pub struct SearchOpt {
pub via: SearchVia,
pub subject: SStr,
pub args: Vec<String>,
pub args_raw: SStr,
pub r#in: Option<UrlCow<'static>>,
}
impl TryFrom<ActionCow> for SearchOpt {
type Error = anyhow::Error;
fn try_from(mut a: ActionCow) -> Result<Self, Self::Error> {
let r#in = a.take::<UrlCow>("in").ok();
if let Some(u) = &r#in
&& (!u.is_absolute() || u.is_search())
{
bail!("invalid 'in' in SearchOpt");
}
let Ok(args) = yazi_shared::shell::unix::split(a.str("args"), false) else {
bail!("invalid 'args' in SearchOpt");
};
Ok(Self {
via: a.str("via").parse()?,
subject: a.take_first().unwrap_or_default(),
args: args.0,
args_raw: a.take("args").unwrap_or_default(),
r#in,
})
}
}
// Via
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq)]
#[serde(rename_all = "kebab-case")]
pub enum SearchVia {
Rg,
Rga,
Fd,
}
impl FromStr for SearchVia {
type Err = serde::de::value::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::deserialize(serde::de::value::StrDeserializer::new(s))
}
}
impl SearchVia {
pub fn into_str(self) -> &'static str {
match self {
Self::Rg => "rg",
Self::Rga => "rga",
Self::Fd => "fd",
}
}
}

View file

@ -1,6 +1,7 @@
use std::ops::Deref; use std::ops::Deref;
use hashbrown::HashSet; use hashbrown::HashSet;
use indexmap::IndexSet;
use yazi_dds::Pubsub; use yazi_dds::Pubsub;
use yazi_fs::FilesOp; use yazi_fs::FilesOp;
use yazi_macro::err; use yazi_macro::err;
@ -9,27 +10,36 @@ use yazi_shared::url::{Url, UrlBuf, UrlBufCov, UrlCov, UrlLike};
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct Yanked { pub struct Yanked {
pub cut: bool, pub cut: bool,
urls: HashSet<UrlBufCov>, urls: IndexSet<UrlBufCov>,
version: u64, version: u64,
revision: u64, revision: u64,
} }
impl Deref for Yanked { impl Deref for Yanked {
type Target = HashSet<UrlBufCov>; type Target = IndexSet<UrlBufCov>;
fn deref(&self) -> &Self::Target { &self.urls } fn deref(&self) -> &Self::Target { &self.urls }
} }
impl Yanked { impl Yanked {
pub fn new(cut: bool, urls: HashSet<UrlBufCov>) -> Self { pub fn new(cut: bool, urls: IndexSet<UrlBufCov>) -> Self {
Self { cut, urls, ..Default::default() } Self { cut, urls, ..Default::default() }
} }
pub fn remove<'a>(&mut self, url: impl Into<Url<'a>>) { pub fn remove_many<'a, I, T>(&mut self, urls: I)
if self.urls.remove(&UrlCov::new(url)) { where
self.revision += 1; I: IntoIterator<Item = T>,
T: Into<UrlCov<'a>>,
{
let urls: HashSet<_> = urls.into_iter().map(Into::into).collect();
if urls.is_empty() {
return;
} }
let old = self.urls.len();
self.urls.retain(|u| !urls.contains(&UrlCov::new(u)));
self.revision += (old != self.urls.len()) as u64;
} }
pub fn clear(&mut self) { pub fn clear(&mut self) {

View file

@ -0,0 +1,29 @@
use serde::{Deserialize, Serialize};
use yazi_config::{Style, THEME};
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum MessageLevel {
#[default]
Info,
Warn,
Error,
}
impl MessageLevel {
pub fn icon(self) -> &'static str {
match self {
Self::Info => &THEME.notify.icon_info,
Self::Warn => &THEME.notify.icon_warn,
Self::Error => &THEME.notify.icon_error,
}
}
pub fn style(self) -> Style {
match self {
Self::Info => THEME.notify.title_info,
Self::Warn => THEME.notify.title_warn,
Self::Error => THEME.notify.title_error,
}
}
}

View file

@ -1,14 +1,14 @@
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
use yazi_parser::notify::{PushLevel, PushOpt};
use super::NOTIFY_BORDER; use super::NOTIFY_BORDER;
use crate::notify::{MessageLevel, MessageOpt};
pub struct Message { pub struct Message {
pub title: String, pub title: String,
pub content: String, pub content: String,
pub level: PushLevel, pub level: MessageLevel,
pub timeout: Duration, pub timeout: Duration,
pub instant: Instant, pub instant: Instant,
@ -16,8 +16,8 @@ pub struct Message {
pub max_width: usize, pub max_width: usize,
} }
impl From<PushOpt> for Message { impl From<MessageOpt> for Message {
fn from(opt: PushOpt) -> Self { fn from(opt: MessageOpt) -> Self {
let title = opt.title.lines().next().unwrap_or_default(); let title = opt.title.lines().next().unwrap_or_default();
let title_width = title.width() + (opt.level.icon().width() + /* Space */ 1); let title_width = title.width() + (opt.level.icon().width() + /* Space */ 1);
@ -36,6 +36,12 @@ impl From<PushOpt> for Message {
} }
} }
impl PartialEq for Message {
fn eq(&self, other: &Self) -> bool {
self.level == other.level && self.content == other.content && self.title == other.title
}
}
impl Message { impl Message {
pub fn height(&self, width: u16) -> usize { pub fn height(&self, width: u16) -> usize {
let lines = ratatui::widgets::Paragraph::new(self.content.as_str()) let lines = ratatui::widgets::Paragraph::new(self.content.as_str())
@ -45,9 +51,3 @@ impl Message {
lines + NOTIFY_BORDER as usize lines + NOTIFY_BORDER as usize
} }
} }
impl PartialEq for Message {
fn eq(&self, other: &Self) -> bool {
self.level == other.level && self.content == other.content && self.title == other.title
}
}

View file

@ -1,4 +1,4 @@
yazi_macro::mod_flat!(message notify); yazi_macro::mod_flat!(level message notify opt);
pub const NOTIFY_BORDER: u16 = 2; pub const NOTIFY_BORDER: u16 = 2;
pub const NOTIFY_SPACING: u16 = 1; pub const NOTIFY_SPACING: u16 = 1;

View file

@ -7,7 +7,7 @@ use super::{Message, NOTIFY_SPACING};
#[derive(Default)] #[derive(Default)]
pub struct Notify { pub struct Notify {
pub tick_handle: Option<JoinHandle<()>>, pub ticker: Option<JoinHandle<()>>,
pub messages: Vec<Message>, pub messages: Vec<Message>,
} }

View file

@ -0,0 +1,41 @@
use std::time::Duration;
use mlua::{FromLua, IntoLua, Lua, LuaSerdeExt, Value};
use serde::{Deserialize, Serialize};
use serde_with::{DurationSecondsWithFrac, serde_as};
use yazi_binding::SER_OPT;
use yazi_shared::{data::Data, event::ActionCow};
use crate::notify::MessageLevel;
#[serde_as]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct MessageOpt {
pub title: String,
pub content: String,
#[serde(default)]
pub level: MessageLevel,
#[serde_as(as = "DurationSecondsWithFrac<f64>")]
pub timeout: Duration,
}
impl TryFrom<ActionCow> for MessageOpt {
type Error = anyhow::Error;
fn try_from(mut a: ActionCow) -> Result<Self, Self::Error> {
Ok(Self {
title: a.take_second()?,
content: a.take_first()?,
level: <_>::deserialize(a.get::<&Data>("level")?)?,
timeout: <_>::deserialize(a.get::<&Data>("timeout")?)?,
})
}
}
impl FromLua for MessageOpt {
fn from_lua(value: Value, lua: &Lua) -> mlua::Result<Self> { lua.from_value(value) }
}
impl IntoLua for MessageOpt {
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> { lua.to_value_with(&self, SER_OPT) }
}

59
yazi-core/src/proxy.rs Normal file
View file

@ -0,0 +1,59 @@
use mlua::ObjectLike;
use yazi_binding::{Error, elements::Renderable};
use yazi_config::LAYOUT;
use yazi_macro::{emit, relay};
use yazi_runner::{plugin::PluginOpt, previewer::PeekJob};
use yazi_scheduler::TaskSummary;
use yazi_shared::url::AsUrl;
use crate::tab::PreviewLock;
pub struct AppProxy;
impl AppProxy {
pub fn plugin(opt: PluginOpt) {
emit!(Call(relay!(app:plugin).with_any("opt", opt)));
}
pub fn plugin_peek(job: PeekJob) {
Self::plugin(PluginOpt::new_callback(&*job.action.name, move |_, plugin| {
plugin.call_method("peek", job)
}));
}
pub fn update_progress(summary: TaskSummary) {
emit!(Call(relay!(app:update_progress).with_any("summary", summary)));
}
}
// --- Mgr
pub struct MgrProxy;
impl MgrProxy {
pub fn update_paged_by<U>(page: usize, only_if: U)
where
U: AsUrl,
{
emit!(Call(relay!(mgr:update_paged, [page]).with("only-if", only_if.as_url())));
}
pub fn update_peeked(lock: PreviewLock) {
emit!(Call(relay!(mgr:update_peeked).with_any("lock", lock)));
}
pub fn update_peeked_error(job: PeekJob, error: String) {
let area = LAYOUT.get().preview;
Self::update_peeked(PreviewLock {
url: job.file.url,
cha: job.file.cha,
mime: job.mime,
skip: job.skip,
area: area.into(),
data: vec![
Renderable::Clear(yazi_binding::elements::Clear { area: area.into() }),
Renderable::from(Error::custom(error)).with_area(area),
],
});
}
}

View file

@ -0,0 +1,57 @@
use mlua::Table;
use yazi_binding::{FileRef, elements::Renderable};
use yazi_shared::Id;
#[derive(Clone, Debug)]
pub struct SpotLock {
pub url: yazi_shared::url::UrlBuf,
pub cha: yazi_fs::cha::Cha,
pub mime: String,
pub id: Id,
pub skip: usize,
pub data: Vec<Renderable>,
}
impl TryFrom<Table> for SpotLock {
type Error = mlua::Error;
fn try_from(t: Table) -> Result<Self, Self::Error> {
let file: FileRef = t.raw_get("file")?;
Ok(Self {
url: file.url_owned(),
cha: file.cha,
mime: t.raw_get("mime")?,
id: *t.raw_get::<yazi_binding::Id>("id")?,
skip: t.raw_get("skip")?,
data: Default::default(),
})
}
}
impl SpotLock {
pub fn len(&self) -> Option<usize> { Some(self.table()?.len()) }
pub fn select(&mut self, idx: Option<usize>) {
if let Some(t) = self.table_mut() {
t.select(idx);
}
}
pub fn selected(&self) -> Option<usize> { self.table()?.selected() }
pub fn table(&self) -> Option<&yazi_binding::elements::Table> {
self.data.iter().rev().find_map(|r| match r {
Renderable::Table(t) => Some(t.as_ref()),
_ => None,
})
}
pub fn table_mut(&mut self) -> Option<&mut yazi_binding::elements::Table> {
self.data.iter_mut().rev().find_map(|r| match r {
Renderable::Table(t) => Some(t.as_mut()),
_ => None,
})
}
}

View file

@ -1 +1 @@
yazi_macro::mod_flat!(spot); yazi_macro::mod_flat!(lock spot);

View file

@ -2,10 +2,11 @@ use tokio_util::sync::CancellationToken;
use yazi_config::YAZI; use yazi_config::YAZI;
use yazi_fs::File; use yazi_fs::File;
use yazi_macro::render; use yazi_macro::render;
use yazi_parser::mgr::SpotLock; use yazi_runner::RUNNER;
use yazi_plugin::isolate;
use yazi_shared::{pool::Symbol, url::UrlBuf}; use yazi_shared::{pool::Symbol, url::UrlBuf};
use crate::spot::SpotLock;
#[derive(Default)] #[derive(Default)]
pub struct Spot { pub struct Spot {
pub lock: Option<SpotLock>, pub lock: Option<SpotLock>,
@ -27,7 +28,7 @@ impl Spot {
}; };
self.abort(); self.abort();
self.ct = Some(isolate::spot(&spotter.run, file, mime, self.skip)); self.ct = Some(RUNNER.spot(&spotter.run, file, mime, self.skip));
} }
pub fn visible(&self) -> bool { self.lock.is_some() } pub fn visible(&self) -> bool { self.lock.is_some() }

View file

@ -4,10 +4,11 @@ use yazi_config::{LAYOUT, YAZI};
use yazi_dds::Pubsub; use yazi_dds::Pubsub;
use yazi_fs::{File, Files, FilesOp, FolderStage, cha::Cha}; use yazi_fs::{File, Files, FilesOp, FolderStage, cha::Cha};
use yazi_macro::err; use yazi_macro::err;
use yazi_proxy::MgrProxy;
use yazi_shared::{Id, path::{AsPath, PathBufDyn, PathDyn}, url::UrlBuf}; use yazi_shared::{Id, path::{AsPath, PathBufDyn, PathDyn}, url::UrlBuf};
use yazi_widgets::{Scrollable, Step}; use yazi_widgets::{Scrollable, Step};
use crate::MgrProxy;
pub struct Folder { pub struct Folder {
pub url: UrlBuf, pub url: UrlBuf,
pub cha: Cha, pub cha: Cha,
@ -79,7 +80,7 @@ impl Folder {
FilesOp::Upserting(_, files) => self.files.update_upserting(files), FilesOp::Upserting(_, files) => self.files.update_upserting(files),
} }
self.trace = self.trace.take_if(|_| !self.files.is_empty() || self.stage.is_loading()); self.trace.take_if(|_| self.files.is_empty() && !self.stage.is_loading());
self.repos(None); self.repos(None);
(&stage, revision) != (&self.stage, self.files.revision) (&stage, revision) != (&self.stage, self.files.revision)

View file

@ -1 +1 @@
yazi_macro::mod_flat!(backstack finder folder history mode preference preview selected tab); yazi_macro::mod_flat!(backstack finder folder history mode preference preview preview_lock selected tab);

View file

@ -2,22 +2,22 @@ use std::time::Duration;
use tokio::{pin, task::JoinHandle}; use tokio::{pin, task::JoinHandle};
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream}; use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
use tokio_util::sync::CancellationToken;
use yazi_adapter::ADAPTOR; use yazi_adapter::ADAPTOR;
use yazi_config::{LAYOUT, YAZI}; use yazi_config::{LAYOUT, YAZI};
use yazi_fs::{File, Files, FilesOp, cha::Cha}; use yazi_fs::{File, Files, FilesOp, cha::Cha};
use yazi_macro::render; use yazi_macro::render;
use yazi_parser::mgr::PreviewLock; use yazi_runner::{RUNNER, previewer::{PeekError, PeekJob}};
use yazi_plugin::{external::Highlighter, isolate};
use yazi_shared::{pool::Symbol, url::{UrlBuf, UrlLike}}; use yazi_shared::{pool::Symbol, url::{UrlBuf, UrlLike}};
use yazi_vfs::{VfsFiles, VfsFilesOp}; use yazi_vfs::{VfsFiles, VfsFilesOp};
use crate::{AppProxy, Highlighter, MgrProxy, tab::PreviewLock};
#[derive(Default)] #[derive(Default)]
pub struct Preview { pub struct Preview {
pub lock: Option<PreviewLock>, pub lock: Option<PreviewLock>,
pub skip: usize, pub skip: usize,
previewer_ct: Option<CancellationToken>, handle: Option<JoinHandle<()>>,
pub folder_lock: Option<UrlBuf>, pub folder_lock: Option<UrlBuf>,
folder_loader: Option<JoinHandle<()>>, folder_loader: Option<JoinHandle<()>>,
} }
@ -35,7 +35,16 @@ impl Preview {
}; };
self.abort(); self.abort();
self.previewer_ct = isolate::peek(&previewer.run, file, mime, self.skip); let job = PeekJob { action: &previewer.run, file, mime, skip: self.skip };
self.handle = Some(tokio::spawn(async move {
let mut rx = RUNNER.peek(&job).await;
match rx.recv().await.unwrap_or(Err(PeekError::Cancelled)) {
Ok(()) | Err(PeekError::Cancelled) => {}
Err(PeekError::ShouldSync) => AppProxy::plugin_peek(job),
Err(e) => MgrProxy::update_peeked_error(job, e.to_string()),
}
}));
} }
pub fn go_folder(&mut self, file: File, dir: Option<Cha>, mime: Symbol<str>, force: bool) { pub fn go_folder(&mut self, file: File, dir: Option<Cha>, mime: Symbol<str>, force: bool) {
@ -71,7 +80,7 @@ impl Preview {
} }
pub fn abort(&mut self) { pub fn abort(&mut self) {
self.previewer_ct.take().map(|ct| ct.cancel()); self.handle.take().map(|ct| ct.abort());
Highlighter::abort(); Highlighter::abort();
} }

View file

@ -0,0 +1,31 @@
use mlua::Table;
use yazi_binding::{FileRef, elements::{Rect, Renderable}};
use yazi_shared::pool::{InternStr, Symbol};
#[derive(Clone, Debug, Default)]
pub struct PreviewLock {
pub url: yazi_shared::url::UrlBuf,
pub cha: yazi_fs::cha::Cha,
pub mime: Symbol<str>,
pub skip: usize,
pub area: Rect,
pub data: Vec<Renderable>,
}
impl TryFrom<Table> for PreviewLock {
type Error = mlua::Error;
fn try_from(t: Table) -> Result<Self, Self::Error> {
let file: FileRef = t.raw_get("file")?;
Ok(Self {
url: file.url_owned(),
cha: file.cha,
mime: t.raw_get::<mlua::String>("mime")?.to_str()?.intern(),
skip: t.raw_get("skip")?,
area: t.raw_get("area")?,
data: Default::default(),
})
}
}

View file

@ -1,4 +1,4 @@
use hashbrown::HashSet; use indexmap::IndexSet;
use tracing::debug; use tracing::debug;
use yazi_shared::url::{UrlBuf, UrlBufCov, UrlLike}; use yazi_shared::url::{UrlBuf, UrlBufCov, UrlLike};
@ -34,7 +34,7 @@ impl Tasks {
} }
} }
pub fn file_link(&self, src: &HashSet<UrlBufCov>, dest: &UrlBuf, relative: bool, force: bool) { pub fn file_link(&self, src: &IndexSet<UrlBufCov>, dest: &UrlBuf, relative: bool, force: bool) {
for u in src { for u in src {
let Some(Ok(to)) = u.name().map(|n| dest.try_join(n)) else { let Some(Ok(to)) = u.name().map(|n| dest.try_join(n)) else {
debug!("file_link: cannot join {u:?} with {dest:?}"); debug!("file_link: cannot join {u:?} with {dest:?}");
@ -48,7 +48,7 @@ impl Tasks {
} }
} }
pub fn file_hardlink(&self, src: &HashSet<UrlBufCov>, dest: &UrlBuf, force: bool, follow: bool) { pub fn file_hardlink(&self, src: &IndexSet<UrlBufCov>, dest: &UrlBuf, force: bool, follow: bool) {
for u in src { for u in src {
let Some(Ok(to)) = u.name().map(|n| dest.try_join(n)) else { let Some(Ok(to)) = u.name().map(|n| dest.try_join(n)) else {
debug!("file_hardlink: cannot join {u:?} with {dest:?}"); debug!("file_hardlink: cannot join {u:?} with {dest:?}");

View file

@ -1,13 +1,13 @@
use std::mem; use std::mem;
use yazi_fs::Splatter; use yazi_fs::Splatter;
use yazi_parser::tasks::ProcessOpenOpt; use yazi_scheduler::process::ProcessOpt;
use super::Tasks; use super::Tasks;
impl Tasks { impl Tasks {
// TODO: remove // TODO: remove
pub fn open_shell_compat(&self, mut opt: ProcessOpenOpt) { pub fn open_shell_compat(&self, mut opt: ProcessOpt) {
if opt.spread { if opt.spread {
opt.cmd = Splatter::new(&opt.args).splat(opt.cmd); opt.cmd = Splatter::new(&opt.args).splat(opt.cmd);
self.scheduler.process_open(opt); self.scheduler.process_open(opt);
@ -24,13 +24,12 @@ impl Tasks {
let hovered = mem::take(&mut opt.args[0]); let hovered = mem::take(&mut opt.args[0]);
for target in opt.args.into_iter().skip(1) { for target in opt.args.into_iter().skip(1) {
let args = vec![hovered.clone(), target]; let args = vec![hovered.clone(), target];
self.scheduler.process_open(ProcessOpenOpt { self.scheduler.process_open(ProcessOpt {
cwd: opt.cwd.clone(), cwd: opt.cwd.clone(),
cmd: Splatter::new(&args).splat(&opt.cmd), cmd: Splatter::new(&args).splat(&opt.cmd),
args, args,
block: opt.block, block: opt.block,
orphan: opt.orphan, orphan: opt.orphan,
done: None,
spread: opt.spread, spread: opt.spread,
}); });
} }

View file

@ -1,13 +1,11 @@
use std::{sync::Arc, time::Duration}; use std::{sync::Arc, time::Duration};
use parking_lot::Mutex;
use tokio::{task::JoinHandle, time::sleep}; use tokio::{task::JoinHandle, time::sleep};
use yazi_emulator::Dimension; use yazi_emulator::Dimension;
use yazi_parser::app::TaskSummary; use yazi_scheduler::{Scheduler, TaskSnap, TaskSummary};
use yazi_proxy::AppProxy;
use yazi_scheduler::{Ongoing, Scheduler, TaskSnap};
use super::{TASKS_BORDER, TASKS_PADDING, TASKS_PERCENT}; use super::{TASKS_BORDER, TASKS_PADDING, TASKS_PERCENT};
use crate::AppProxy;
pub struct Tasks { pub struct Tasks {
pub scheduler: Arc<Scheduler>, pub scheduler: Arc<Scheduler>,
@ -29,7 +27,7 @@ impl Tasks {
loop { loop {
sleep(Duration::from_millis(500)).await; sleep(Duration::from_millis(500)).await;
let new = ongoing.lock().summary(); let new = TaskSummary::from(&*ongoing.lock());
if last != new { if last != new {
last = new; last = new;
AppProxy::update_progress(new); AppProxy::update_progress(new);
@ -60,8 +58,6 @@ impl Tasks {
} }
pub fn paginate(&self) -> Vec<TaskSnap> { pub fn paginate(&self) -> Vec<TaskSnap> {
self.ongoing().lock().values().take(Self::limit()).map(Into::into).collect() self.scheduler.ongoing.lock().values().take(Self::limit()).map(Into::into).collect()
} }
pub fn ongoing(&self) -> &Arc<Mutex<Ongoing>> { &self.scheduler.ongoing }
} }

View file

@ -1 +1 @@
yazi_macro::mod_flat!(sorter which); yazi_macro::mod_flat!(opt sorter which);

View file

@ -0,0 +1,78 @@
use mlua::{ExternalError, FromLua, IntoLua, Lua, Table, Value};
use tokio::sync::mpsc;
use yazi_config::{KEYMAP, keymap::{ChordCow, Key}};
use yazi_shared::{Layer, event::ActionCow};
#[derive(Clone, Debug)]
pub struct WhichOpt {
pub tx: Option<mpsc::UnboundedSender<Option<yazi_binding::ChordCow>>>,
pub cands: Vec<ChordCow>,
pub silent: bool,
pub times: usize,
}
impl TryFrom<ActionCow> for WhichOpt {
type Error = anyhow::Error;
fn try_from(mut a: ActionCow) -> Result<Self, Self::Error> {
if let Some(opt) = a.take_any2("opt") {
return opt;
}
Ok(Self {
tx: a.take_any2("tx").transpose()?,
cands: a.take_any_iter::<yazi_binding::ChordCow>().map(Into::into).collect(),
silent: a.bool("silent"),
times: a.get("times").unwrap_or(0),
})
}
}
impl From<(Layer, Key)> for WhichOpt {
fn from((layer, key): (Layer, Key)) -> Self {
Self {
tx: None,
cands: KEYMAP
.get(layer)
.iter()
.filter(|c| c.on.len() > 1 && c.on[0] == key)
.map(Into::into)
.collect(),
times: 1,
silent: false,
}
}
}
impl FromLua for WhichOpt {
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
let Value::Table(t) = value else {
return Err("expected a table".into_lua_err());
};
Ok(Self {
tx: t.raw_get::<yazi_binding::MpscUnboundedTx<_>>("tx").ok().map(|t| t.0),
cands: t
.raw_get::<Table>("cands")?
.sequence_values::<yazi_binding::ChordCow>()
.map(|c| c.map(Into::into))
.collect::<mlua::Result<Vec<_>>>()?,
times: t.raw_get("times").unwrap_or_default(),
silent: t.raw_get("silent")?,
})
}
}
impl IntoLua for WhichOpt {
#[rustfmt::skip]
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
lua
.create_table_from([
("tx", self.tx.map(yazi_binding::MpscUnboundedTx).into_lua(lua)?),
("cands", lua.create_sequence_from(self.cands.into_iter().map(yazi_binding::ChordCow))?.into_lua(lua)?),
("times", self.times.into_lua(lua)?),
("silent", self.silent.into_lua(lua)?),
])?
.into_lua(lua)
}
}

View file

@ -21,13 +21,13 @@ yazi-binding = { path = "../yazi-binding", version = "26.2.2" }
yazi-boot = { path = "../yazi-boot", version = "26.2.2" } yazi-boot = { path = "../yazi-boot", version = "26.2.2" }
yazi-fs = { path = "../yazi-fs", version = "26.2.2" } yazi-fs = { path = "../yazi-fs", version = "26.2.2" }
yazi-macro = { path = "../yazi-macro", version = "26.2.2" } yazi-macro = { path = "../yazi-macro", version = "26.2.2" }
yazi-parser = { path = "../yazi-parser", version = "26.2.2" }
yazi-shared = { path = "../yazi-shared", version = "26.2.2" } yazi-shared = { path = "../yazi-shared", version = "26.2.2" }
yazi-widgets = { path = "../yazi-widgets", version = "26.2.2" } yazi-widgets = { path = "../yazi-widgets", version = "26.2.2" }
# External dependencies # External dependencies
anyhow = { workspace = true } anyhow = { workspace = true }
hashbrown = { workspace = true } hashbrown = { workspace = true }
indexmap = { workspace = true }
mlua = { workspace = true } mlua = { workspace = true }
ordered-float = { workspace = true } ordered-float = { workspace = true }
parking_lot = { workspace = true } parking_lot = { workspace = true }

View file

@ -1,25 +1,33 @@
use std::borrow::Cow; use std::borrow::Cow;
use hashbrown::HashSet; use indexmap::IndexSet;
use mlua::{IntoLua, Lua, Value}; use mlua::{AnyUserData, IntoLua, Lua, MetaMethod, MultiValue, ObjectLike, UserData, UserDataFields, UserDataMethods, Value};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use yazi_parser::mgr::UpdateYankedOpt; use yazi_binding::get_metatable;
use yazi_shared::url::UrlBufCov; use yazi_shared::url::UrlBufCov;
use super::Ember; use super::Ember;
type Iter = yazi_binding::Iter<
std::iter::Map<indexmap::set::IntoIter<UrlBufCov>, fn(UrlBufCov) -> yazi_binding::Url>,
yazi_binding::Url,
>;
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
pub struct EmberYank<'a>(UpdateYankedOpt<'a>); pub struct EmberYank<'a> {
pub cut: bool,
pub urls: Cow<'a, IndexSet<UrlBufCov>>,
}
impl<'a> EmberYank<'a> { impl<'a> EmberYank<'a> {
pub fn borrowed(cut: bool, urls: &'a HashSet<UrlBufCov>) -> Ember<'a> { pub fn borrowed(cut: bool, urls: &'a IndexSet<UrlBufCov>) -> Ember<'a> {
Self(UpdateYankedOpt { cut, urls: Cow::Borrowed(urls) }).into() Self { cut, urls: Cow::Borrowed(urls) }.into()
} }
} }
impl EmberYank<'static> { impl EmberYank<'static> {
pub fn owned(cut: bool, _: &HashSet<UrlBufCov>) -> Ember<'static> { pub fn owned(cut: bool, _: &IndexSet<UrlBufCov>) -> Ember<'static> {
Self(UpdateYankedOpt { cut, urls: Default::default() }).into() Self { cut, urls: Default::default() }.into()
} }
} }
@ -28,5 +36,47 @@ impl<'a> From<EmberYank<'a>> for Ember<'a> {
} }
impl IntoLua for EmberYank<'_> { impl IntoLua for EmberYank<'_> {
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> { self.0.into_lua(lua) } fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
let len = self.urls.len();
let iter = Iter::new(self.urls.into_owned().into_iter().map(yazi_binding::Url::new), Some(len));
EmberYankIter { cut: self.cut, len, inner: lua.create_userdata(iter)? }.into_lua(lua)
}
}
// --- Iter
pub struct EmberYankIter {
cut: bool,
len: usize,
inner: AnyUserData,
}
impl EmberYankIter {
pub fn collect(self, lua: &Lua) -> mlua::Result<EmberYank<'static>> {
Ok(EmberYank {
cut: self.cut,
urls: Cow::Owned(
self
.inner
.take::<Iter>()?
.into_iter(lua)
.map(|result| result.map(Into::into))
.collect::<mlua::Result<_>>()?,
),
})
}
}
impl UserData for EmberYankIter {
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("cut", |_, me| Ok(me.cut));
}
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.len));
methods.add_meta_method(MetaMethod::Pairs, |lua, me, ()| {
get_metatable(lua, &me.inner)?
.call_function::<MultiValue>(MetaMethod::Pairs.name(), me.inner.clone())
});
}
} }

View file

@ -1,6 +1,4 @@
mod macros; yazi_macro::mod_pub!(ember);
yazi_macro::mod_pub!(ember spark);
yazi_macro::mod_flat!(client payload pubsub pump sendable server state stream); yazi_macro::mod_flat!(client payload pubsub pump sendable server state stream);

View file

@ -6,7 +6,7 @@ use yazi_boot::BOOT;
use yazi_macro::{emit, relay}; use yazi_macro::{emit, relay};
use yazi_shared::{Id, event::ActionCow}; use yazi_shared::{Id, event::ActionCow};
use crate::{ID, ember::Ember, spark::Spark}; use crate::{ID, ember::Ember};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Payload<'a> { pub struct Payload<'a> {
@ -16,7 +16,7 @@ pub struct Payload<'a> {
} }
impl<'a> Payload<'a> { impl<'a> Payload<'a> {
pub fn new(body: Ember<'a>) -> Self { Self { receiver: Id(0), sender: *ID, body } } pub fn new(body: Ember<'a>) -> Self { Self { receiver: Id::ZERO, sender: *ID, body } }
pub(super) fn flush(&self) -> Result<()> { pub(super) fn flush(&self) -> Result<()> {
writeln!(std::io::stdout(), "{self}")?; writeln!(std::io::stdout(), "{self}")?;
@ -75,17 +75,6 @@ impl<'a> From<Ember<'a>> for Payload<'a> {
fn from(value: Ember<'a>) -> Self { Self::new(value) } fn from(value: Ember<'a>) -> Self { Self::new(value) }
} }
impl<'a> TryFrom<Spark<'a>> for Payload<'a> {
type Error = ();
fn try_from(value: Spark<'a>) -> Result<Self, Self::Error> {
match value {
Spark::AppAcceptPayload(payload) => Ok(payload),
_ => Err(()),
}
}
}
impl TryFrom<ActionCow> for Payload<'_> { impl TryFrom<ActionCow> for Payload<'_> {
type Error = anyhow::Error; type Error = anyhow::Error;

View file

@ -1,5 +1,6 @@
use anyhow::Result; use anyhow::Result;
use hashbrown::{HashMap, HashSet}; use hashbrown::HashMap;
use indexmap::IndexSet;
use mlua::Function; use mlua::Function;
use parking_lot::RwLock; use parking_lot::RwLock;
use yazi_boot::BOOT; use yazi_boot::BOOT;
@ -160,7 +161,7 @@ impl Pubsub {
pub_after!(rename(tab: Id, from: &UrlBuf, to: &UrlBuf), (tab, from, to)); pub_after!(rename(tab: Id, from: &UrlBuf, to: &UrlBuf), (tab, from, to));
pub_after!(@yank(cut: bool, urls: &HashSet<UrlBufCov>), (cut, urls)); pub_after!(@yank(cut: bool, urls: &IndexSet<UrlBufCov>), (cut, urls));
pub_after!(duplicate(items: Vec<EmberDuplicateItem>), (&items), (items)); pub_after!(duplicate(items: Vec<EmberDuplicateItem>), (&items), (items));

View file

@ -5,6 +5,8 @@ use mlua::{ExternalError, IntoLua, Lua, MultiValue, Table, Value};
use ordered_float::OrderedFloat; use ordered_float::OrderedFloat;
use yazi_shared::{data::{Data, DataKey}, replace_cow}; use yazi_shared::{data::{Data, DataKey}, replace_cow};
use crate::ember;
pub struct Sendable; pub struct Sendable;
impl Sendable { impl Sendable {
@ -55,8 +57,8 @@ impl Sendable {
Some(t) if t == TypeId::of::<yazi_fs::FilesOp>() => { Some(t) if t == TypeId::of::<yazi_fs::FilesOp>() => {
Data::Any(Box::new(ud.take::<yazi_fs::FilesOp>()?)) Data::Any(Box::new(ud.take::<yazi_fs::FilesOp>()?))
} }
Some(t) if t == TypeId::of::<yazi_parser::mgr::UpdateYankedIter>() => { Some(t) if t == TypeId::of::<ember::EmberYankIter>() => {
Data::Any(Box::new(ud.take::<yazi_parser::mgr::UpdateYankedIter>()?.into_opt(lua)?)) Data::Any(Box::new(ud.take::<ember::EmberYankIter>()?.collect(lua)?))
} }
Some(t) if t == TypeId::of::<yazi_binding::ChordCow>() => { Some(t) if t == TypeId::of::<yazi_binding::ChordCow>() => {
Data::Any(Box::new(ud.take::<yazi_binding::ChordCow>()?)) Data::Any(Box::new(ud.take::<yazi_binding::ChordCow>()?))
@ -102,7 +104,7 @@ impl Sendable {
} }
try_cast!(|v: yazi_fs::FilesOp| lua.create_any_userdata(v)); try_cast!(|v: yazi_fs::FilesOp| lua.create_any_userdata(v));
try_cast!(|v: yazi_parser::mgr::UpdateYankedOpt| v.into_lua(lua)); try_cast!(|v: ember::EmberYank| v.into_lua(lua));
try_cast!(|v: yazi_binding::ChordCow| v.into_lua(lua)); try_cast!(|v: yazi_binding::ChordCow| v.into_lua(lua));
Err("unsupported DataAny included".into_lua_err())? Err("unsupported DataAny included".into_lua_err())?
} }
@ -146,7 +148,7 @@ impl Sendable {
} }
try_cast!(|v: yazi_fs::FilesOp| lua.create_any_userdata(v)); try_cast!(|v: yazi_fs::FilesOp| lua.create_any_userdata(v));
try_cast!(|v: yazi_parser::mgr::UpdateYankedOpt| v.into_lua(lua)); try_cast!(|v: ember::EmberYank| v.into_lua(lua));
try_cast!(|v: yazi_binding::ChordCow| v.into_lua(lua)); try_cast!(|v: yazi_binding::ChordCow| v.into_lua(lua));
Err("unsupported DataAny included".into_lua_err())? Err("unsupported DataAny included".into_lua_err())?
} }

View file

@ -125,7 +125,7 @@ impl Server {
} }
} }
let bye = EmberBye::borrowed().with_receiver(id).with_sender(Id(0)); let bye = EmberBye::borrowed().with_receiver(id).with_sender(Id::ZERO);
if let Ok(s) = try_format!("{bye}") { if let Ok(s) = try_format!("{bye}") {
writer.write_all(s.as_bytes()).await.ok(); writer.write_all(s.as_bytes()).await.ok();
writer.flush().await.ok(); writer.flush().await.ok();

View file

@ -1,447 +0,0 @@
use mlua::{FromLua, IntoLua, Lua, Value};
use crate::{spark::SparkKind, try_from_spark};
#[derive(Debug)]
pub enum Spark<'a> {
// Void
Void(yazi_parser::VoidOpt),
// App
AppAcceptPayload(crate::Payload<'a>),
AppBootstrap(yazi_parser::VoidOpt),
AppDeprecate(yazi_parser::app::DeprecateOpt),
AppFocus(yazi_parser::VoidOpt),
AppLua(yazi_parser::app::LuaOpt),
AppMouse(yazi_parser::app::MouseOpt),
AppPlugin(yazi_parser::app::PluginOpt),
AppPluginDo(yazi_parser::app::PluginOpt),
AppQuit(yazi_parser::app::QuitOpt),
AppReflow(yazi_parser::app::ReflowOpt),
AppResize(yazi_parser::app::ReflowOpt),
AppResume(yazi_parser::app::ResumeOpt),
AppStop(yazi_parser::app::StopOpt),
AppTitle(yazi_parser::app::TitleOpt),
AppUpdateProgress(yazi_parser::app::UpdateProgressOpt),
// Mgr
Arrow(yazi_parser::ArrowOpt),
Back(yazi_parser::VoidOpt),
BulkExit(yazi_parser::mgr::BulkExitOpt),
BulkRename(yazi_parser::VoidOpt),
Cd(yazi_parser::mgr::CdOpt),
Close(yazi_parser::mgr::CloseOpt),
Copy(yazi_parser::mgr::CopyOpt),
Create(yazi_parser::mgr::CreateOpt),
Displace(yazi_parser::VoidOpt),
DisplaceDo(yazi_parser::mgr::DisplaceDoOpt),
Download(yazi_parser::mgr::DownloadOpt),
Enter(yazi_parser::VoidOpt),
Escape(yazi_parser::mgr::EscapeOpt),
EscapeFilter(yazi_parser::VoidOpt),
EscapeFind(yazi_parser::VoidOpt),
EscapeSearch(yazi_parser::VoidOpt),
EscapeSelect(yazi_parser::VoidOpt),
EscapeVisual(yazi_parser::VoidOpt),
Filter(yazi_parser::mgr::FilterOpt),
FilterDo(yazi_parser::mgr::FilterOpt),
Find(yazi_parser::mgr::FindOpt),
FindArrow(yazi_parser::mgr::FindArrowOpt),
FindDo(yazi_parser::mgr::FindDoOpt),
Follow(yazi_parser::VoidOpt),
Forward(yazi_parser::VoidOpt),
Hardlink(yazi_parser::mgr::HardlinkOpt),
Hidden(yazi_parser::mgr::HiddenOpt),
Hover(yazi_parser::mgr::HoverOpt),
Leave(yazi_parser::VoidOpt),
Linemode(yazi_parser::mgr::LinemodeOpt),
Link(yazi_parser::mgr::LinkOpt),
Open(yazi_parser::mgr::OpenOpt),
OpenDo(yazi_parser::mgr::OpenDoOpt),
Paste(yazi_parser::mgr::PasteOpt),
Peek(yazi_parser::mgr::PeekOpt),
Quit(yazi_parser::app::QuitOpt),
Refresh(yazi_parser::VoidOpt),
Remove(yazi_parser::mgr::RemoveOpt),
RemoveDo(yazi_parser::mgr::RemoveOpt),
Rename(yazi_parser::mgr::RenameOpt),
Reveal(yazi_parser::mgr::RevealOpt),
Search(yazi_parser::mgr::SearchOpt),
SearchDo(yazi_parser::mgr::SearchOpt),
SearchStop(yazi_parser::VoidOpt),
Seek(yazi_parser::mgr::SeekOpt),
Shell(yazi_parser::mgr::ShellOpt),
Sort(yazi_parser::mgr::SortOpt),
Spot(yazi_parser::mgr::SpotOpt),
Stash(yazi_parser::mgr::StashOpt),
Suspend(yazi_parser::VoidOpt),
TabClose(yazi_parser::mgr::TabCloseOpt),
TabCreate(yazi_parser::mgr::TabCreateOpt),
TabRename(yazi_parser::mgr::TabRenameOpt),
TabSwap(yazi_parser::ArrowOpt),
TabSwitch(yazi_parser::mgr::TabSwitchOpt),
Toggle(yazi_parser::mgr::ToggleOpt),
ToggleAll(yazi_parser::mgr::ToggleAllOpt),
Unyank(yazi_parser::VoidOpt),
UpdateFiles(yazi_parser::mgr::UpdateFilesOpt),
UpdateMimes(yazi_parser::mgr::UpdateMimesOpt),
UpdatePaged(yazi_parser::mgr::UpdatePagedOpt),
UpdatePeeked(yazi_parser::mgr::UpdatePeekedOpt),
UpdateSpotted(yazi_parser::mgr::UpdateSpottedOpt),
UpdateYanked(yazi_parser::mgr::UpdateYankedOpt<'a>),
Upload(yazi_parser::mgr::UploadOpt),
VisualMode(yazi_parser::mgr::VisualModeOpt),
Watch(yazi_parser::VoidOpt),
Yank(yazi_parser::mgr::YankOpt),
// Cmp
CmpArrow(yazi_parser::ArrowOpt),
CmpClose(yazi_parser::cmp::CloseOpt),
CmpShow(yazi_parser::cmp::ShowOpt),
CmpTrigger(yazi_parser::cmp::TriggerOpt),
// Confirm
ConfirmArrow(yazi_parser::ArrowOpt),
ConfirmClose(yazi_parser::confirm::CloseOpt),
ConfirmShow(Box<yazi_parser::confirm::ShowOpt>),
// Help
HelpArrow(yazi_parser::ArrowOpt),
HelpEscape(yazi_parser::VoidOpt),
HelpFilter(yazi_parser::VoidOpt),
HelpToggle(yazi_parser::help::ToggleOpt),
// Input
InputBackspace(yazi_widgets::input::parser::BackspaceOpt),
InputBackward(yazi_widgets::input::parser::BackwardOpt),
InputClose(yazi_parser::input::CloseOpt),
InputComplete(yazi_widgets::input::parser::CompleteOpt),
InputDelete(yazi_widgets::input::parser::DeleteOpt),
InputEscape(yazi_parser::VoidOpt),
InputForward(yazi_widgets::input::parser::ForwardOpt),
InputInsert(yazi_widgets::input::parser::InsertOpt),
InputKill(yazi_widgets::input::parser::KillOpt),
InputMove(yazi_widgets::input::parser::MoveOpt),
InputPaste(yazi_widgets::input::parser::PasteOpt),
InputShow(yazi_widgets::input::InputOpt),
// Notify
NotifyPush(yazi_parser::notify::PushOpt),
NotifyTick(yazi_parser::notify::TickOpt),
// Pick
PickArrow(yazi_parser::ArrowOpt),
PickClose(yazi_parser::pick::CloseOpt),
PickShow(yazi_parser::pick::ShowOpt),
// Spot
SpotArrow(yazi_parser::ArrowOpt),
SpotClose(yazi_parser::VoidOpt),
SpotCopy(yazi_parser::spot::CopyOpt),
SpotSwipe(yazi_parser::ArrowOpt),
// Tasks
TasksArrow(yazi_parser::ArrowOpt),
TasksCancel(yazi_parser::VoidOpt),
TasksClose(yazi_parser::VoidOpt),
TasksInspect(yazi_parser::VoidOpt),
TasksOpenShellCompat(yazi_parser::tasks::ProcessOpenOpt),
TasksProcessOpen(yazi_parser::tasks::ProcessOpenOpt),
TasksShow(yazi_parser::VoidOpt),
TasksUpdateSucceed(yazi_parser::tasks::UpdateSucceedOpt),
// Which
WhichActivate(yazi_parser::which::ActivateOpt),
WhichDismiss(yazi_parser::VoidOpt),
}
impl<'a> Spark<'a> {
pub fn from_lua(lua: &Lua, kind: SparkKind, value: Value) -> mlua::Result<Self> {
use SparkKind::*;
Ok(match kind {
// app:title
IndAppTitle => Self::AppTitle(<_>::from_lua(value, lua)?),
// mgr:hidden
KeyHidden => Self::Hidden(<_>::from_lua(value, lua)?),
IndHidden => Self::Hidden(<_>::from_lua(value, lua)?),
// mgr:sort
KeySort => Self::Sort(<_>::from_lua(value, lua)?),
IndSort => Self::Sort(<_>::from_lua(value, lua)?),
// mgr:stash
IndStash => Self::Stash(<_>::from_lua(value, lua)?),
RelayStash => Self::Stash(<_>::from_lua(value, lua)?),
// mgr:quit
KeyQuit => Self::Quit(<_>::from_lua(value, lua)?),
// which:activate
IndWhichActivate => Self::WhichActivate(<_>::from_lua(value, lua)?),
// notify:push
RelayNotifyPush => Self::NotifyPush(<_>::from_lua(value, lua)?),
})
}
}
impl<'a> IntoLua for Spark<'a> {
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
match self {
// Void
Self::Void(b) => b.into_lua(lua),
// App
Self::AppAcceptPayload(b) => b.into_lua(lua),
Self::AppBootstrap(b) => b.into_lua(lua),
Self::AppDeprecate(b) => b.into_lua(lua),
Self::AppFocus(b) => b.into_lua(lua),
Self::AppLua(b) => b.into_lua(lua),
Self::AppMouse(b) => b.into_lua(lua),
Self::AppPlugin(b) => b.into_lua(lua),
Self::AppPluginDo(b) => b.into_lua(lua),
Self::AppQuit(b) => b.into_lua(lua),
Self::AppReflow(b) => b.into_lua(lua),
Self::AppResize(b) => b.into_lua(lua),
Self::AppResume(b) => b.into_lua(lua),
Self::AppStop(b) => b.into_lua(lua),
Self::AppTitle(b) => b.into_lua(lua),
Self::AppUpdateProgress(b) => b.into_lua(lua),
// Mgr
Self::Arrow(b) => b.into_lua(lua),
Self::Back(b) => b.into_lua(lua),
Self::BulkExit(b) => b.into_lua(lua),
Self::BulkRename(b) => b.into_lua(lua),
Self::Cd(b) => b.into_lua(lua),
Self::Close(b) => b.into_lua(lua),
Self::Copy(b) => b.into_lua(lua),
Self::Create(b) => b.into_lua(lua),
Self::Displace(b) => b.into_lua(lua),
Self::DisplaceDo(b) => b.into_lua(lua),
Self::Download(b) => b.into_lua(lua),
Self::Enter(b) => b.into_lua(lua),
Self::Escape(b) => b.into_lua(lua),
Self::EscapeFilter(b) => b.into_lua(lua),
Self::EscapeFind(b) => b.into_lua(lua),
Self::EscapeSearch(b) => b.into_lua(lua),
Self::EscapeSelect(b) => b.into_lua(lua),
Self::EscapeVisual(b) => b.into_lua(lua),
Self::Filter(b) => b.into_lua(lua),
Self::FilterDo(b) => b.into_lua(lua),
Self::Find(b) => b.into_lua(lua),
Self::FindArrow(b) => b.into_lua(lua),
Self::FindDo(b) => b.into_lua(lua),
Self::Follow(b) => b.into_lua(lua),
Self::Forward(b) => b.into_lua(lua),
Self::Hardlink(b) => b.into_lua(lua),
Self::Hidden(b) => b.into_lua(lua),
Self::Hover(b) => b.into_lua(lua),
Self::Leave(b) => b.into_lua(lua),
Self::Linemode(b) => b.into_lua(lua),
Self::Link(b) => b.into_lua(lua),
Self::Open(b) => b.into_lua(lua),
Self::OpenDo(b) => b.into_lua(lua),
Self::Paste(b) => b.into_lua(lua),
Self::Peek(b) => b.into_lua(lua),
Self::Quit(b) => b.into_lua(lua),
Self::Refresh(b) => b.into_lua(lua),
Self::Remove(b) => b.into_lua(lua),
Self::RemoveDo(b) => b.into_lua(lua),
Self::Rename(b) => b.into_lua(lua),
Self::Reveal(b) => b.into_lua(lua),
Self::Search(b) => b.into_lua(lua),
Self::SearchDo(b) => b.into_lua(lua),
Self::SearchStop(b) => b.into_lua(lua),
Self::Seek(b) => b.into_lua(lua),
Self::Shell(b) => b.into_lua(lua),
Self::Sort(b) => b.into_lua(lua),
Self::Spot(b) => b.into_lua(lua),
Self::Stash(b) => b.into_lua(lua),
Self::Suspend(b) => b.into_lua(lua),
Self::TabClose(b) => b.into_lua(lua),
Self::TabCreate(b) => b.into_lua(lua),
Self::TabRename(b) => b.into_lua(lua),
Self::TabSwap(b) => b.into_lua(lua),
Self::TabSwitch(b) => b.into_lua(lua),
Self::Toggle(b) => b.into_lua(lua),
Self::ToggleAll(b) => b.into_lua(lua),
Self::Unyank(b) => b.into_lua(lua),
Self::UpdateFiles(b) => b.into_lua(lua),
Self::UpdateMimes(b) => b.into_lua(lua),
Self::UpdatePaged(b) => b.into_lua(lua),
Self::UpdatePeeked(b) => b.into_lua(lua),
Self::UpdateSpotted(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::Watch(b) => b.into_lua(lua),
Self::Yank(b) => b.into_lua(lua),
// Cmp
Self::CmpArrow(b) => b.into_lua(lua),
Self::CmpClose(b) => b.into_lua(lua),
Self::CmpShow(b) => b.into_lua(lua),
Self::CmpTrigger(b) => b.into_lua(lua),
// Confirm
Self::ConfirmArrow(b) => b.into_lua(lua),
Self::ConfirmClose(b) => b.into_lua(lua),
Self::ConfirmShow(b) => b.into_lua(lua),
// Help
Self::HelpArrow(b) => b.into_lua(lua),
Self::HelpEscape(b) => b.into_lua(lua),
Self::HelpFilter(b) => b.into_lua(lua),
Self::HelpToggle(b) => b.into_lua(lua),
// Input
Self::InputBackspace(b) => b.into_lua(lua),
Self::InputBackward(b) => b.into_lua(lua),
Self::InputClose(b) => b.into_lua(lua),
Self::InputComplete(b) => b.into_lua(lua),
Self::InputDelete(b) => b.into_lua(lua),
Self::InputEscape(b) => b.into_lua(lua),
Self::InputForward(b) => b.into_lua(lua),
Self::InputInsert(b) => b.into_lua(lua),
Self::InputKill(b) => b.into_lua(lua),
Self::InputMove(b) => b.into_lua(lua),
Self::InputPaste(b) => b.into_lua(lua),
Self::InputShow(b) => b.into_lua(lua),
// Notify
Self::NotifyPush(b) => b.into_lua(lua),
Self::NotifyTick(b) => b.into_lua(lua),
// Pick
Self::PickArrow(b) => b.into_lua(lua),
Self::PickClose(b) => b.into_lua(lua),
Self::PickShow(b) => b.into_lua(lua),
// Spot
Self::SpotArrow(b) => b.into_lua(lua),
Self::SpotClose(b) => b.into_lua(lua),
Self::SpotCopy(b) => b.into_lua(lua),
Self::SpotSwipe(b) => b.into_lua(lua),
// Tasks
Self::TasksArrow(b) => b.into_lua(lua),
Self::TasksCancel(b) => b.into_lua(lua),
Self::TasksClose(b) => b.into_lua(lua),
Self::TasksInspect(b) => b.into_lua(lua),
Self::TasksOpenShellCompat(b) => b.into_lua(lua),
Self::TasksProcessOpen(b) => b.into_lua(lua),
Self::TasksShow(b) => b.into_lua(lua),
Self::TasksUpdateSucceed(b) => b.into_lua(lua),
// Which
Self::WhichActivate(b) => b.into_lua(lua),
Self::WhichDismiss(b) => b.into_lua(lua),
}
}
}
try_from_spark!(
yazi_parser::VoidOpt,
app:bootstrap,
app:focus,
mgr:back,
mgr:bulk_rename,
mgr:enter,
mgr:escape_filter,
mgr:escape_find,
mgr:escape_search,
mgr:escape_select,
mgr:escape_visual,
mgr:follow,
mgr:forward,
mgr:leave,
mgr:refresh,
mgr:search_stop,
mgr:suspend,
mgr:unyank,
mgr:watch,
which:dismiss
);
// App
try_from_spark!(yazi_parser::ArrowOpt, mgr:arrow, mgr:tab_swap);
try_from_spark!(yazi_parser::app::DeprecateOpt, app:deprecate);
try_from_spark!(yazi_parser::app::LuaOpt, app:lua);
try_from_spark!(yazi_parser::app::MouseOpt, app:mouse);
try_from_spark!(yazi_parser::app::PluginOpt, app:plugin, app:plugin_do);
try_from_spark!(yazi_parser::app::QuitOpt, app:quit, mgr:quit);
try_from_spark!(yazi_parser::app::ReflowOpt, app:reflow, app:resize);
try_from_spark!(yazi_parser::app::ResumeOpt, app:resume);
try_from_spark!(yazi_parser::app::StopOpt, app:stop);
try_from_spark!(yazi_parser::app::TitleOpt, app:title);
try_from_spark!(yazi_parser::app::UpdateProgressOpt, app:update_progress);
try_from_spark!(yazi_parser::cmp::CloseOpt, cmp:close);
try_from_spark!(yazi_parser::cmp::ShowOpt, cmp:show);
try_from_spark!(yazi_parser::cmp::TriggerOpt, cmp:trigger);
try_from_spark!(yazi_parser::confirm::CloseOpt, confirm:close);
try_from_spark!(yazi_parser::confirm::ShowOpt, confirm:show);
try_from_spark!(yazi_parser::help::ToggleOpt, help:toggle);
try_from_spark!(yazi_parser::input::CloseOpt, input:close);
try_from_spark!(yazi_widgets::input::InputOpt, input:show);
try_from_spark!(yazi_parser::mgr::BulkExitOpt, mgr:bulk_exit);
try_from_spark!(yazi_parser::mgr::CdOpt, mgr:cd);
try_from_spark!(yazi_parser::mgr::CloseOpt, mgr:close);
try_from_spark!(yazi_parser::mgr::CopyOpt, mgr:copy);
try_from_spark!(yazi_parser::mgr::CreateOpt, mgr:create);
try_from_spark!(yazi_parser::mgr::DisplaceDoOpt, mgr:displace_do);
try_from_spark!(yazi_parser::mgr::DownloadOpt, mgr:download);
try_from_spark!(yazi_parser::mgr::EscapeOpt, mgr:escape);
try_from_spark!(yazi_parser::mgr::FilterOpt, mgr:filter, mgr:filter_do);
try_from_spark!(yazi_parser::mgr::FindArrowOpt, mgr:find_arrow);
try_from_spark!(yazi_parser::mgr::FindDoOpt, mgr:find_do);
try_from_spark!(yazi_parser::mgr::FindOpt, mgr:find);
try_from_spark!(yazi_parser::mgr::HardlinkOpt, mgr:hardlink);
try_from_spark!(yazi_parser::mgr::HiddenOpt, mgr:hidden);
try_from_spark!(yazi_parser::mgr::HoverOpt, mgr:hover);
try_from_spark!(yazi_parser::mgr::LinemodeOpt, mgr:linemode);
try_from_spark!(yazi_parser::mgr::LinkOpt, mgr:link);
try_from_spark!(yazi_parser::mgr::OpenDoOpt, mgr:open_do);
try_from_spark!(yazi_parser::mgr::OpenOpt, mgr:open);
try_from_spark!(yazi_parser::mgr::PasteOpt, mgr:paste);
try_from_spark!(yazi_parser::mgr::PeekOpt, mgr:peek);
try_from_spark!(yazi_parser::mgr::RemoveOpt, mgr:remove, mgr:remove_do);
try_from_spark!(yazi_parser::mgr::RenameOpt, mgr:rename);
try_from_spark!(yazi_parser::mgr::RevealOpt, mgr:reveal);
try_from_spark!(yazi_parser::mgr::SearchOpt, mgr:search, mgr:search_do);
try_from_spark!(yazi_parser::mgr::SeekOpt, mgr:seek);
try_from_spark!(yazi_parser::mgr::ShellOpt, mgr:shell);
try_from_spark!(yazi_parser::mgr::SortOpt, mgr:sort);
try_from_spark!(yazi_parser::mgr::SpotOpt, mgr:spot);
try_from_spark!(yazi_parser::mgr::StashOpt, mgr:stash);
try_from_spark!(yazi_parser::mgr::TabCloseOpt, mgr:tab_close);
try_from_spark!(yazi_parser::mgr::TabCreateOpt, mgr:tab_create);
try_from_spark!(yazi_parser::mgr::TabRenameOpt, mgr:tab_rename);
try_from_spark!(yazi_parser::mgr::TabSwitchOpt, mgr:tab_switch);
try_from_spark!(yazi_parser::mgr::ToggleAllOpt, mgr:toggle_all);
try_from_spark!(yazi_parser::mgr::ToggleOpt, mgr:toggle);
try_from_spark!(yazi_parser::mgr::UpdateFilesOpt, mgr:update_files);
try_from_spark!(yazi_parser::mgr::UpdateMimesOpt, mgr:update_mimes);
try_from_spark!(yazi_parser::mgr::UpdatePagedOpt, mgr:update_paged);
try_from_spark!(yazi_parser::mgr::UpdatePeekedOpt, mgr:update_peeked);
try_from_spark!(yazi_parser::mgr::UpdateSpottedOpt, mgr:update_spotted);
try_from_spark!(yazi_parser::mgr::UpdateYankedOpt<'a>, mgr:update_yanked);
try_from_spark!(yazi_parser::mgr::UploadOpt, mgr:upload);
try_from_spark!(yazi_parser::mgr::VisualModeOpt, mgr:visual_mode);
try_from_spark!(yazi_parser::mgr::YankOpt, mgr:yank);
try_from_spark!(yazi_parser::notify::PushOpt, notify:push);
try_from_spark!(yazi_parser::notify::TickOpt, notify:tick);
try_from_spark!(yazi_parser::pick::CloseOpt, pick:close);
try_from_spark!(yazi_parser::pick::ShowOpt, pick:show);
try_from_spark!(yazi_parser::spot::CopyOpt, spot:copy);
try_from_spark!(yazi_parser::tasks::ProcessOpenOpt, tasks:process_open);
try_from_spark!(yazi_parser::tasks::UpdateSucceedOpt, tasks:update_succeed);
try_from_spark!(yazi_parser::which::ActivateOpt, which:activate);
try_from_spark!(yazi_widgets::input::parser::BackspaceOpt, input:backspace);
try_from_spark!(yazi_widgets::input::parser::BackwardOpt, input:backward);
try_from_spark!(yazi_widgets::input::parser::CompleteOpt, input:complete);
try_from_spark!(yazi_widgets::input::parser::DeleteOpt, input:delete);
try_from_spark!(yazi_widgets::input::parser::ForwardOpt, input:forward);
try_from_spark!(yazi_widgets::input::parser::InsertOpt, input:insert);
try_from_spark!(yazi_widgets::input::parser::KillOpt, input:kill);
try_from_spark!(yazi_widgets::input::parser::MoveOpt, input:move);
try_from_spark!(yazi_widgets::input::parser::PasteOpt, input:paste);

View file

@ -40,6 +40,8 @@ yazi-macro = { path = "../yazi-macro", version = "26.2.2" }
yazi-parser = { path = "../yazi-parser", version = "26.2.2" } yazi-parser = { path = "../yazi-parser", version = "26.2.2" }
yazi-plugin = { path = "../yazi-plugin", version = "26.2.2" } yazi-plugin = { path = "../yazi-plugin", version = "26.2.2" }
yazi-proxy = { path = "../yazi-proxy", version = "26.2.2" } yazi-proxy = { path = "../yazi-proxy", version = "26.2.2" }
yazi-runner = { path = "../yazi-runner", version = "26.2.2" }
yazi-scheduler = { path = "../yazi-scheduler", version = "26.2.2" }
yazi-shared = { path = "../yazi-shared", version = "26.2.2" } yazi-shared = { path = "../yazi-shared", version = "26.2.2" }
yazi-term = { path = "../yazi-term", version = "26.2.2" } yazi-term = { path = "../yazi-term", version = "26.2.2" }
yazi-tty = { path = "../yazi-tty", version = "26.2.2" } yazi-tty = { path = "../yazi-tty", version = "26.2.2" }

View file

@ -2,12 +2,11 @@ use std::sync::atomic::Ordering;
use anyhow::Result; use anyhow::Result;
use crossterm::event::{KeyEvent, MouseEvent}; use crossterm::event::{KeyEvent, MouseEvent};
use tokio::sync::mpsc;
use tracing::warn; use tracing::warn;
use yazi_actor::Ctx; use yazi_actor::Ctx;
use yazi_config::keymap::Key; use yazi_config::keymap::Key;
use yazi_macro::{act, emit}; use yazi_macro::{act, emit};
use yazi_shared::{data::Data, event::{ActionCow, Event, NEED_RENDER}}; use yazi_shared::event::{ActionCow, Event, NEED_RENDER};
use yazi_widgets::input::InputMode; use yazi_widgets::input::InputMode;
use crate::{Executor, Router, app::App}; use crate::{Executor, Router, app::App};
@ -39,7 +38,7 @@ impl<'a> Dispatcher<'a> {
} }
fn dispatch_call(&mut self, action: ActionCow) -> Result<()> { fn dispatch_call(&mut self, action: ActionCow) -> Result<()> {
let tx = action.any::<mpsc::UnboundedSender<Result<Data>>>("__reply").cloned(); let tx = action.replier().cloned();
let result = Executor::new(self.app).execute(action); let result = Executor::new(self.app).execute(action);
if let Err(e) = &result { if let Err(e) = &result {

View file

@ -34,6 +34,8 @@ async fn main() -> anyhow::Result<()> {
yazi_watcher::init(); yazi_watcher::init();
yazi_runner::init(yazi_plugin::slim_lua);
yazi_plugin::init()?; yazi_plugin::init()?;
yazi_dds::serve(); yazi_dds::serve();

Some files were not shown because too many files have changed in this diff Show more