diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 3d363578..b8d5da24 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -51,7 +51,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v6
- - uses: JohnnyMorganz/stylua-action@v4
+ - uses: JohnnyMorganz/stylua-action@v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
version: latest
diff --git a/.github/workflows/draft.yml b/.github/workflows/draft.yml
index f518914e..448ad1fb 100644
--- a/.github/workflows/draft.yml
+++ b/.github/workflows/draft.yml
@@ -210,7 +210,7 @@ jobs:
merge-multiple: true
- name: Draft
- uses: softprops/action-gh-release@v2
+ uses: softprops/action-gh-release@v3
with:
draft: true
files: |
@@ -246,7 +246,7 @@ jobs:
git tag --force nightly && git push --force origin tag nightly
- name: Nightly
- uses: softprops/action-gh-release@v2
+ uses: softprops/action-gh-release@v3
with:
tag_name: nightly
prerelease: true
diff --git a/.github/workflows/validate-form.yml b/.github/workflows/validate-form.yml
index b9416d4b..bd8d9764 100644
--- a/.github/workflows/validate-form.yml
+++ b/.github/workflows/validate-form.yml
@@ -25,7 +25,7 @@ jobs:
npm ci
- name: Validate Form
- uses: actions/github-script@v8
+ uses: actions/github-script@v9
with:
script: |
const script = require('./scripts/validate-form/main.js')
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6bf1272f..40ff9a3b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
- New `--in` for `search` action to set search directory ([#3696])
- Hover cursor over the new file after copying/cutting/linking/hardlinking/extracting ([#3846], [#3854])
- Multi-file spotter ([#3733])
+- Dynamic previewer Lua API ([#3891])
- Vim-like `lua` action that runs an inline Lua snippet ([#3813])
- Certificate authentication for SFTP VFS provider ([#3716])
- New `hovered` condition specifying different icons for hovered files ([#3728])
@@ -1699,3 +1700,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
[#3846]: https://github.com/sxyazi/yazi/pull/3846
[#3854]: https://github.com/sxyazi/yazi/pull/3854
[#3862]: https://github.com/sxyazi/yazi/pull/3862
+[#3891]: https://github.com/sxyazi/yazi/pull/3891
diff --git a/Cargo.lock b/Cargo.lock
index 7c8669dc..e0b5c110 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -211,6 +211,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207"
dependencies = [
"rustversion",
+ "serde",
]
[[package]]
@@ -410,20 +411,20 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
-version = "2.11.0"
+version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
+checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
dependencies = [
"serde_core",
]
[[package]]
name = "bitstream-io"
-version = "4.9.0"
+version = "4.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60d4bd9d1db2c6bdf285e223a7fa369d5ce98ec767dec949c6ca62863ce61757"
+checksum = "7eff00be299a18769011411c9def0d827e8f2d7bf0c3dbf53633147a8867fd1f"
dependencies = [
- "core2",
+ "no_std_io2",
]
[[package]]
@@ -629,7 +630,7 @@ checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
dependencies = [
"cfg-if",
"cpufeatures 0.3.0",
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
]
[[package]]
@@ -669,9 +670,9 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.6.0"
+version = "4.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351"
+checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51"
dependencies = [
"clap_builder",
"clap_derive",
@@ -691,9 +692,9 @@ dependencies = [
[[package]]
name = "clap_complete"
-version = "4.6.1"
+version = "4.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "406e68b4de5c59cfb8f750a7cbd4d31ae153788b8352167c1e5f4fc26e8c91e9"
+checksum = "3ff7a1dccbdd8b078c2bdebff47e404615151534d5043da397ec50286816f9cb"
dependencies = [
"clap",
]
@@ -720,9 +721,9 @@ dependencies = [
[[package]]
name = "clap_derive"
-version = "4.6.0"
+version = "4.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a"
+checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9"
dependencies = [
"heck",
"proc-macro2",
@@ -826,15 +827,6 @@ version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
-[[package]]
-name = "core2"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505"
-dependencies = [
- "memchr",
-]
-
[[package]]
name = "cpubits"
version = "0.1.0"
@@ -908,7 +900,7 @@ version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"crossterm_winapi",
"mio",
"parking_lot",
@@ -925,7 +917,7 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"crossterm_winapi",
"derive_more",
"document-features",
@@ -967,7 +959,7 @@ dependencies = [
"getrandom 0.4.2",
"hybrid-array",
"num-traits",
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
"serdect",
"subtle",
"zeroize",
@@ -991,7 +983,7 @@ checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710"
dependencies = [
"getrandom 0.4.2",
"hybrid-array",
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
]
[[package]]
@@ -1002,7 +994,7 @@ checksum = "21f41f23de7d24cdbda7f0c4d9c0351f99a4ceb258ef30e5c1927af8987ffe5a"
dependencies = [
"crypto-bigint",
"libm",
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
]
[[package]]
@@ -1349,7 +1341,7 @@ checksum = "053618a4c3d3bc24f188aa660ae75a46eeab74ef07fb415c61431e5e7cd4749b"
dependencies = [
"curve25519-dalek",
"ed25519",
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
"serde",
"sha2 0.11.0",
"signature",
@@ -1378,7 +1370,7 @@ dependencies = [
"once_cell",
"pem-rfc7468 1.0.0",
"pkcs8",
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
"rustcrypto-ff",
"rustcrypto-group",
"sec1",
@@ -1767,7 +1759,7 @@ dependencies = [
"cfg-if",
"libc",
"r-efi 6.0.0",
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
"wasip2",
"wasip3",
]
@@ -2046,7 +2038,7 @@ version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd5b3eaf1a28b758ac0faa5a4254e8ab2705605496f1b1f3fbbc3988ad73d199"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"inotify-sys",
"libc",
]
@@ -2110,7 +2102,7 @@ dependencies = [
"p256",
"p384",
"p521",
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
"rsa",
"sec1",
"sha1 0.11.0",
@@ -2130,8 +2122,8 @@ checksum = "ae8e22120c32fb4d19ec55fba35015f57095cd95a2e3b732e44457f5915b2ee8"
dependencies = [
"num-integer",
"num-traits",
- "rand 0.10.0",
- "rand_core 0.10.0",
+ "rand 0.10.1",
+ "rand_core 0.10.1",
]
[[package]]
@@ -2216,7 +2208,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01737161ba802849cfd486b5bd209d38ba4943494c249a8126005170c7621edd"
dependencies = [
"crypto-common 0.2.1",
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
]
[[package]]
@@ -2268,9 +2260,9 @@ checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8"
[[package]]
name = "libc"
-version = "0.2.184"
+version = "0.2.185"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
+checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
[[package]]
name = "libfuzzer-sys"
@@ -2303,7 +2295,7 @@ version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f50e8f47623268b5407192d26876c4d7f89d686ca130fdc53bced4814cd29f8"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
]
[[package]]
@@ -2350,13 +2342,22 @@ dependencies = [
[[package]]
name = "lru"
-version = "0.16.3"
+version = "0.16.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593"
+checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39"
dependencies = [
"hashbrown 0.16.1",
]
+[[package]]
+name = "lru"
+version = "0.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e0b564323a0fb6d54b864f625ae139de9612e27edb944dda37c109f05aac531"
+dependencies = [
+ "hashbrown 0.17.0",
+]
+
[[package]]
name = "lua-src"
version = "550.0.0"
@@ -2468,7 +2469,7 @@ dependencies = [
"hybrid-array",
"kem",
"module-lattice",
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
"sha3",
]
@@ -2556,7 +2557,7 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"cfg-if",
"cfg_aliases",
"libc",
@@ -2569,12 +2570,21 @@ version = "0.31.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"cfg-if",
"cfg_aliases",
"libc",
]
+[[package]]
+name = "no_std_io2"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b51ed7824b6e07d354605f4abb3d9d300350701299da96642ee084f5ce631550"
+dependencies = [
+ "memchr",
+]
+
[[package]]
name = "nom"
version = "7.1.3"
@@ -2606,7 +2616,7 @@ version = "8.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"fsevent-sys",
"inotify",
"kqueue",
@@ -2624,7 +2634,7 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
]
[[package]]
@@ -2766,7 +2776,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"objc2",
]
@@ -2797,7 +2807,7 @@ version = "6.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"libc",
"once_cell",
"onig_sys",
@@ -3156,7 +3166,7 @@ dependencies = [
"cbc 0.2.0",
"der",
"pbkdf2 0.13.0-rc.10",
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
"scrypt",
"sha2 0.11.0",
"spki",
@@ -3170,15 +3180,15 @@ checksum = "12922b6296c06eb741b02d7b5161e3aaa22864af38dfa025a1a3ba3f68c84577"
dependencies = [
"der",
"pkcs5",
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
"spki",
]
[[package]]
name = "pkg-config"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
+checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e"
[[package]]
name = "plist"
@@ -3199,7 +3209,7 @@ version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"crc32fast",
"fdeflate",
"flate2",
@@ -3279,7 +3289,7 @@ checksum = "c6543f5eec854fbf74ba5ef651fbdc9408919b47c3e1526623687135c16d12e9"
dependencies = [
"crypto-bigint",
"crypto-common 0.2.1",
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
"rustcrypto-ff",
"subtle",
"zeroize",
@@ -3431,9 +3441,9 @@ dependencies = [
[[package]]
name = "rand"
-version = "0.9.2"
+version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
+checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.5",
@@ -3441,13 +3451,13 @@ dependencies = [
[[package]]
name = "rand"
-version = "0.10.0"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8"
+checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
dependencies = [
"chacha20 0.10.0",
"getrandom 0.4.2",
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
]
[[package]]
@@ -3491,9 +3501,9 @@ dependencies = [
[[package]]
name = "rand_core"
-version = "0.10.0"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba"
+checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
[[package]]
name = "ratatui"
@@ -3517,13 +3527,13 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ef8dea09a92caaf73bff7adb70b76162e5937524058a7e5bff37869cbbec293"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"compact_str",
"hashbrown 0.16.1",
"indoc",
"itertools",
"kasuari",
- "lru",
+ "lru 0.16.4",
"serde",
"strum 0.27.2",
"thiserror 2.0.18",
@@ -3582,7 +3592,7 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7dbfa023cd4e604c2553483820c5fe8aa9d71a42eea5aa77c6e7f35756612db"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"hashbrown 0.16.1",
"indoc",
"instability",
@@ -3623,7 +3633,7 @@ dependencies = [
"num-traits",
"paste",
"profiling",
- "rand 0.9.2",
+ "rand 0.9.4",
"rand_chacha 0.9.0",
"simd_helpers",
"thiserror 2.0.18",
@@ -3647,9 +3657,9 @@ dependencies = [
[[package]]
name = "rayon"
-version = "1.11.0"
+version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
+checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d"
dependencies = [
"either",
"rayon-core",
@@ -3671,7 +3681,7 @@ version = "0.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
]
[[package]]
@@ -3776,7 +3786,7 @@ dependencies = [
"digest 0.11.2",
"pkcs1",
"pkcs8",
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
"sha2 0.11.0",
"signature",
"spki",
@@ -3790,7 +3800,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b530252dc3ff163b73a7e48c97b925450d2ca53edcb466a46ad0a231e45f998"
dependencies = [
"aes 0.8.4",
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"block-padding 0.3.3",
"byteorder",
"bytes",
@@ -3828,8 +3838,8 @@ dependencies = [
"pkcs5",
"pkcs8",
"polyval 0.7.1",
- "rand 0.10.0",
- "rand_core 0.10.0",
+ "rand 0.10.1",
+ "rand_core 0.10.1",
"ring",
"rsa",
"russh-cryptovec",
@@ -3899,7 +3909,7 @@ version = "0.14.0-rc.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd2a8adb347447693cd2ba0d218c4b66c62da9b0a5672b17b981e4291ec65ff6"
dependencies = [
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
"subtle",
]
@@ -3909,7 +3919,7 @@ version = "0.14.0-rc.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "369f9b61aa45933c062c9f6b5c3c50ab710687eca83dd3802653b140b43f85ed"
dependencies = [
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
"rustcrypto-ff",
"subtle",
]
@@ -3920,7 +3930,7 @@ version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"errno",
"libc",
"linux-raw-sys 0.4.15",
@@ -3933,7 +3943,7 @@ version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"errno",
"libc",
"linux-raw-sys 0.12.1",
@@ -4274,7 +4284,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f1880df446116126965eeec169136b2e0251dba37c6223bcc819569550edea3"
dependencies = [
"digest 0.11.2",
- "rand_core 0.10.0",
+ "rand_core 0.10.1",
]
[[package]]
@@ -4525,7 +4535,7 @@ checksum = "4676b37242ccbd1aabf56edb093a4827dc49086c0ffd764a5705899e0f35f8f7"
dependencies = [
"anyhow",
"base64",
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"fancy-regex",
"filedescriptor",
"finl_unicode",
@@ -4678,9 +4688,9 @@ dependencies = [
[[package]]
name = "tokio"
-version = "1.51.1"
+version = "1.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c"
+checksum = "a91135f59b1cbf38c91e73cf3386fca9bb77915c45ce2771460c9d92f0f3d776"
dependencies = [
"bytes",
"libc",
@@ -4864,7 +4874,7 @@ version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c"
dependencies = [
- "rand 0.9.2",
+ "rand 0.9.4",
]
[[package]]
@@ -4966,9 +4976,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
-version = "1.23.0"
+version = "1.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9"
+checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76"
dependencies = [
"atomic",
"getrandom 0.4.2",
@@ -5175,7 +5185,7 @@ version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"hashbrown 0.15.5",
"indexmap 2.14.0",
"semver",
@@ -5703,7 +5713,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
dependencies = [
"anyhow",
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"indexmap 2.14.0",
"log",
"serde",
@@ -5908,7 +5918,8 @@ name = "yazi-config"
version = "26.2.2"
dependencies = [
"anyhow",
- "bitflags 2.11.0",
+ "arc-swap",
+ "bitflags 2.11.1",
"crossterm 0.29.0",
"globset",
"hashbrown 0.17.0",
@@ -5916,6 +5927,7 @@ dependencies = [
"ratatui",
"regex",
"serde",
+ "serde_with",
"strum 0.28.0",
"tokio",
"toml",
@@ -5924,6 +5936,7 @@ dependencies = [
"yazi-fs",
"yazi-macro",
"yazi-shared",
+ "yazi-shim",
"yazi-tty",
]
@@ -6066,7 +6079,7 @@ version = "26.2.2"
dependencies = [
"anyhow",
"arc-swap",
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"core-foundation-sys",
"dirs",
"either",
@@ -6076,7 +6089,7 @@ dependencies = [
"objc2",
"parking_lot",
"percent-encoding",
- "rand 0.10.0",
+ "rand 0.10.1",
"regex",
"scopeguard",
"serde",
@@ -6106,7 +6119,7 @@ name = "yazi-parser"
version = "26.2.2"
dependencies = [
"anyhow",
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"crossterm 0.29.0",
"hashbrown 0.17.0",
"mlua",
@@ -6217,7 +6230,7 @@ dependencies = [
"foldhash 0.2.0",
"hashbrown 0.17.0",
"libc",
- "lru",
+ "lru 0.17.0",
"mlua",
"ordered-float 5.3.0",
"parking_lot",
@@ -6240,7 +6253,7 @@ dependencies = [
name = "yazi-sftp"
version = "26.2.2"
dependencies = [
- "bitflags 2.11.0",
+ "bitflags 2.11.1",
"parking_lot",
"russh",
"serde",
@@ -6278,8 +6291,12 @@ dependencies = [
name = "yazi-shim"
version = "26.2.2"
dependencies = [
+ "arc-swap",
"crossterm 0.29.0",
"ratatui",
+ "serde",
+ "thiserror 2.0.18",
+ "toml",
"twox-hash",
"unicode-segmentation",
"unicode-width",
diff --git a/Cargo.toml b/Cargo.toml
index 6acc8042..d66c7f49 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -37,11 +37,11 @@ debug = false
[workspace.dependencies]
ansi-to-tui = "8.0.1"
anyhow = "1.0.102"
-arc-swap = "1.9.1"
+arc-swap = { version = "1.9.1", features = [ "serde" ] }
base64 = "0.22.1"
-bitflags = { version = "2.11.0", features = [ "serde" ] }
+bitflags = { version = "2.11.1", features = [ "serde" ] }
chrono = "0.4.44"
-clap = { version = "4.6.0", features = [ "derive" ] }
+clap = { version = "4.6.1", features = [ "derive" ] }
core-foundation-sys = "0.8.7"
crossterm = { version = "0.29.0", features = [ "event-stream" ] }
dirs = "6.0.0"
@@ -52,15 +52,15 @@ futures = "0.3.32"
globset = "0.4.18"
hashbrown = { version = "0.17.0", features = [ "serde" ] }
indexmap = { version = "2.14.0", features = [ "serde" ] }
-libc = "0.2.184"
-lru = "0.16.3"
+libc = "0.2.185"
+lru = "0.17.0"
mlua = { version = "0.11.6", features = [ "anyhow", "async", "error-send", "lua55", "macros", "serde" ] }
objc2 = "0.6.4"
ordered-float = { version = "5.3.0", features = [ "serde" ] }
parking_lot = "0.12.5"
paste = "1.0.15"
percent-encoding = "2.3.2"
-rand = { version = "0.10.0", default-features = false, features = [ "std", "sys_rng" ] }
+rand = { version = "0.10.1", default-features = false, features = [ "std", "sys_rng" ] }
ratatui = { version = "0.30.0", features = [ "serde", "unstable-rendered-line-info", "unstable-widget-ref" ] }
regex = "1.12.3"
russh = { version = "0.60.0", default-features = false, features = [ "ring", "rsa" ] }
@@ -71,7 +71,7 @@ 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" ] }
thiserror = "2.0.18"
-tokio = { version = "1.51.1", features = [ "full" ] }
+tokio = { version = "1.52.0", features = [ "full" ] }
tokio-stream = "0.1.18"
tokio-util = "0.7.18"
toml = { version = "1.1.2" }
diff --git a/README.md b/README.md
index e1f46cea..63e6513a 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
@@ -47,24 +47,24 @@ Yazi is currently in heavy development, expect breaking changes.
## Image Preview
-| Platform | Protocol | Support |
-| ---------------------------------------------------------------------------- | -------------------------------------- | ---------------------------------------- |
-| [kitty](https://github.com/kovidgoyal/kitty) (>= 0.28.0) | [Kitty unicode placeholders][kgp] | ✅ Built-in |
-| [iTerm2](https://iterm2.com) | [Inline images protocol][iip] | ✅ Built-in |
-| [WezTerm](https://github.com/wez/wezterm) | [Inline images protocol][iip] | ✅ Built-in |
-| [Konsole](https://invent.kde.org/utilities/konsole) | [Kitty old protocol][kgp-old] | ✅ Built-in |
-| [foot](https://codeberg.org/dnkl/foot) | [Sixel graphics format][sixel] | ✅ Built-in |
-| [Ghostty](https://github.com/ghostty-org/ghostty) | [Kitty unicode placeholders][kgp] | ✅ Built-in |
-| [Windows Terminal](https://github.com/microsoft/terminal) (>= v1.22.10352.0) | [Sixel graphics format][sixel] | ✅ Built-in |
-| [st with Sixel patch](https://github.com/bakkeby/st-flexipatch) | [Sixel graphics format][sixel] | ✅ Built-in |
-| [Warp](https://www.warp.dev) (macOS/Linux only) | [Inline images protocol][iip] | ✅ Built-in |
-| [Tabby](https://github.com/Eugeny/tabby) | [Inline images protocol][iip] | ✅ Built-in |
-| [VSCode](https://github.com/microsoft/vscode) | [Inline images protocol][iip] | ✅ Built-in |
-| [Rio](https://github.com/raphamorim/rio) | [Inline images protocol][iip] | ❌ Rio renders images at incorrect sizes |
-| [Black Box](https://gitlab.gnome.org/raggesilver/blackbox) | [Sixel graphics format][sixel] | ✅ Built-in |
-| [Bobcat](https://github.com/ismail-yilmaz/Bobcat) | [Inline images protocol][iip] | ✅ Built-in |
-| X11 / Wayland | Window system protocol | ☑️ [Überzug++][ueberzug] required |
-| Fallback | [ASCII art (Unicode block)][ascii-art] | ☑️ [Chafa][chafa] required (>= 1.16.0) |
+| Platform | Protocol | Support |
+| ---------------------------------------------------------------------------- | -------------------------------------- | -------------------------------------- |
+| [kitty](https://github.com/kovidgoyal/kitty) (>= 0.28.0) | [Kitty unicode placeholders][kgp] | ✅ Built-in |
+| [iTerm2](https://iterm2.com) | [Inline images protocol][iip] | ✅ Built-in |
+| [WezTerm](https://github.com/wez/wezterm) | [Inline images protocol][iip] | ✅ Built-in |
+| [Konsole](https://invent.kde.org/utilities/konsole) | [Kitty old protocol][kgp-old] | ✅ Built-in |
+| [foot](https://codeberg.org/dnkl/foot) | [Sixel graphics format][sixel] | ✅ Built-in |
+| [Ghostty](https://github.com/ghostty-org/ghostty) | [Kitty unicode placeholders][kgp] | ✅ Built-in |
+| [Windows Terminal](https://github.com/microsoft/terminal) (>= v1.22.10352.0) | [Sixel graphics format][sixel] | ✅ Built-in |
+| [st with Sixel patch](https://github.com/bakkeby/st-flexipatch) | [Sixel graphics format][sixel] | ✅ Built-in |
+| [Warp](https://www.warp.dev) (macOS/Linux only) | [Inline images protocol][iip] | ✅ Built-in |
+| [Tabby](https://github.com/Eugeny/tabby) | [Inline images protocol][iip] | ✅ Built-in |
+| [VSCode](https://github.com/microsoft/vscode) | [Inline images protocol][iip] | ✅ Built-in |
+| [Rio](https://github.com/raphamorim/rio) (>= 0.3.9) | [Kitty unicode placeholders][kgp] | ✅ Built-in |
+| [Black Box](https://gitlab.gnome.org/raggesilver/blackbox) | [Sixel graphics format][sixel] | ✅ Built-in |
+| [Bobcat](https://github.com/ismail-yilmaz/Bobcat) | [Inline images protocol][iip] | ✅ Built-in |
+| X11 / Wayland | Window system protocol | ☑️ [Überzug++][ueberzug] required |
+| Fallback | [ASCII art (Unicode block)][ascii-art] | ☑️ [Chafa][chafa] required (>= 1.16.0) |
See https://yazi-rs.github.io/docs/image-preview for details.
diff --git a/cspell.json b/cspell.json
index 3fc3d927..e5d69993 100644
--- a/cspell.json
+++ b/cspell.json
@@ -1 +1 @@
-{"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"}
\ No newline at end of file
+{"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","pointee"],"version":"0.2","language":"en","flagWords":[]}
\ No newline at end of file
diff --git a/scripts/validate-form/package-lock.json b/scripts/validate-form/package-lock.json
index 5ed84a8b..03743e35 100644
--- a/scripts/validate-form/package-lock.json
+++ b/scripts/validate-form/package-lock.json
@@ -9,7 +9,7 @@
"version": "1.0.0",
"dependencies": {
"@actions/core": "^3.0.0",
- "@actions/github": "^9.0.0"
+ "@actions/github": "^9.1.0"
}
},
"node_modules/@actions/core": {
@@ -42,9 +42,9 @@
}
},
"node_modules/@actions/github": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@actions/github/-/github-9.0.0.tgz",
- "integrity": "sha512-yJ0RoswsAaKcvkmpCE4XxBRiy/whH2SdTBHWzs0gi4wkqTDhXMChjSdqBz/F4AeiDlP28rQqL33iHb+kjAMX6w==",
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/@actions/github/-/github-9.1.0.tgz",
+ "integrity": "sha512-u0hDGQeCS+7VNoLA8hYG65RLdPLMaPGfka0sZ0up7P0AiShqfX6xcuXNteGkQ7X7Tod7AMNwHd4p7DS63i8zzA==",
"license": "MIT",
"dependencies": {
"@actions/http-client": "^3.0.2",
diff --git a/scripts/validate-form/package.json b/scripts/validate-form/package.json
index 0b6d52c8..4ecb17e8 100644
--- a/scripts/validate-form/package.json
+++ b/scripts/validate-form/package.json
@@ -7,6 +7,6 @@
"private": true,
"dependencies": {
"@actions/core": "^3.0.0",
- "@actions/github": "^9.0.0"
+ "@actions/github": "^9.1.0"
}
}
diff --git a/yazi-actor/src/context.rs b/yazi-actor/src/context.rs
index 24cd8bc1..febe97a6 100644
--- a/yazi-actor/src/context.rs
+++ b/yazi-actor/src/context.rs
@@ -27,7 +27,6 @@ impl DerefMut for Ctx<'_> {
}
impl<'a> Ctx<'a> {
- #[inline]
pub fn new(action: &Action, core: &'a mut Core, term: &'a mut Option) -> Result {
let tab = if let Ok(id) = action.get::("tab") {
core
@@ -51,7 +50,6 @@ impl<'a> Ctx<'a> {
})
}
- #[inline]
pub fn renew<'b>(cx: &'a mut Ctx<'b>) -> Self {
let tab = cx.core.mgr.tabs.cursor;
Self {
@@ -65,7 +63,6 @@ impl<'a> Ctx<'a> {
}
}
- #[inline]
pub fn active(core: &'a mut Core, term: &'a mut Option) -> Self {
let tab = core.mgr.tabs.cursor;
Self {
@@ -119,6 +116,5 @@ impl<'a> Ctx<'a> {
self.tab_mut().hovered_folder_mut()
}
- #[inline]
pub fn source(&self) -> Source { if self.level != 1 { Source::Ind } else { self.source } }
}
diff --git a/yazi-actor/src/lives/file.rs b/yazi-actor/src/lives/file.rs
index 578c384c..83ae6ca1 100644
--- a/yazi-actor/src/lives/file.rs
+++ b/yazi-actor/src/lives/file.rs
@@ -2,7 +2,7 @@ use std::{ops::Deref, ptr};
use mlua::{AnyUserData, IntoLua, UserData, UserDataFields, UserDataMethods, Value};
use yazi_binding::{Range, Style, cached_field};
-use yazi_config::THEME;
+use yazi_config::{Selectable, THEME};
use yazi_shared::{path::AsPath, url::UrlLike};
use super::Lives;
diff --git a/yazi-actor/src/mgr/bulk_rename.rs b/yazi-actor/src/mgr/bulk_rename.rs
index 7443980d..938b2e1c 100644
--- a/yazi-actor/src/mgr/bulk_rename.rs
+++ b/yazi-actor/src/mgr/bulk_rename.rs
@@ -155,7 +155,7 @@ impl BulkRename {
}
fn opener() -> Option<&'static OpenerRule> {
- YAZI.opener.block(YAZI.open.all(Path::new("bulk-rename.txt"), "text/plain"))
+ YAZI.opener.block(YAZI.open.all_dummy(Path::new("bulk-rename.txt"), "text/plain"))
}
fn replace_url(url: &UrlBuf, take: usize, rep: &StrandBuf) -> Result {
diff --git a/yazi-actor/src/mgr/download.rs b/yazi-actor/src/mgr/download.rs
index ab94dbdb..8e9c174e 100644
--- a/yazi-actor/src/mgr/download.rs
+++ b/yazi-actor/src/mgr/download.rs
@@ -8,7 +8,7 @@ use yazi_fs::{File, FsScheme, provider::{Provider, local::Local}};
use yazi_macro::succ;
use yazi_parser::mgr::DownloadForm;
use yazi_proxy::MgrProxy;
-use yazi_shared::{data::Data, url::{UrlCow, UrlLike}};
+use yazi_shared::{data::Data, url::{UrlBuf, UrlLike}};
use yazi_vfs::VfsFile;
use crate::{Actor, Ctx};
@@ -29,7 +29,7 @@ impl Actor for Download {
let mut wg1 = FuturesUnordered::new();
for url in form.urls {
- let done = scheduler.file_download(url.to_owned());
+ let done = scheduler.file_download(url.clone());
wg1.push(async move { (done.future().await, url) });
}
@@ -60,7 +60,7 @@ impl Actor for Download {
}
if form.open && !urls.is_empty() {
MgrProxy::open(OpenOpt {
- cwd: Some(cwd.into()),
+ cwd: Some(cwd),
targets: urls,
interactive: false,
hovered: false,
@@ -73,7 +73,7 @@ impl Actor for Download {
}
impl Download {
- async fn prepare(urls: &[UrlCow<'_>]) {
+ async fn prepare(urls: &[UrlBuf]) {
let roots: HashSet<_> = urls.iter().filter_map(|u| u.scheme().cache()).collect();
for mut root in roots {
root.push("%lock");
diff --git a/yazi-actor/src/mgr/open.rs b/yazi-actor/src/mgr/open.rs
index d49bf177..4a39468c 100644
--- a/yazi-actor/src/mgr/open.rs
+++ b/yazi-actor/src/mgr/open.rs
@@ -1,4 +1,6 @@
use anyhow::Result;
+use futures::StreamExt;
+use hashbrown::HashSet;
use yazi_boot::ARGS;
use yazi_core::mgr::OpenDoOpt;
use yazi_fs::File;
@@ -31,17 +33,17 @@ impl Actor for Open {
if opt.targets.is_empty() {
opt.targets = if opt.hovered {
- cx.hovered().map(|h| vec![h.url.clone().into()]).unwrap_or_default()
+ cx.hovered().map(|h| vec![h.url.clone()]).unwrap_or_default()
} else {
act!(mgr:escape_visual, cx)?;
- cx.tab().selected_or_hovered().cloned().map(Into::into).collect()
+ cx.tab().selected_or_hovered().cloned().collect()
};
}
if opt.targets.is_empty() {
succ!();
}
- let todo: Vec<_> = opt
+ let todo: HashSet<_> = opt
.targets
.iter()
.enumerate()
@@ -49,21 +51,28 @@ impl Actor for Open {
.map(|(i, _)| i)
.collect();
- let cwd = opt.cwd.unwrap_or_else(|| cx.cwd().clone().into());
- if todo.is_empty() {
- return act!(mgr:open_do, cx, OpenDoOpt { cwd, targets: opt.targets, interactive: opt.interactive });
- }
-
+ let cwd = opt.cwd.unwrap_or_else(|| cx.cwd().clone());
let scheduler = cx.tasks.scheduler.clone();
tokio::spawn(async move {
- let mut files = Vec::with_capacity(todo.len());
- for i in todo {
- if let Ok(f) = File::new(&opt.targets[i]).await {
- files.push(f);
+ let mut all = Vec::with_capacity(opt.targets.len());
+ let mut part = Vec::with_capacity(todo.len());
+
+ let it = futures::stream::iter(opt.targets)
+ .enumerate()
+ .map(|(i, url)| async move { File::new(url).await.ok().map(|file| (i, file)) })
+ .buffered(3)
+ .filter_map(|item| async move { item });
+
+ futures::pin_mut!(it);
+ while let Some((i, file)) = it.next().await {
+ if todo.contains(&i) {
+ part.push(file.clone());
}
+ all.push(file);
}
- if scheduler.fetch_mimetype(files).await {
- MgrProxy::open_do(OpenDoOpt { cwd, targets: opt.targets, interactive: opt.interactive });
+
+ if !all.is_empty() && scheduler.fetch_mimetype(part).await {
+ MgrProxy::open_do(OpenDoOpt { cwd, targets: all, interactive: opt.interactive });
}
});
succ!();
diff --git a/yazi-actor/src/mgr/open_do.rs b/yazi-actor/src/mgr/open_do.rs
index 95d59e00..3af6eac8 100644
--- a/yazi-actor/src/mgr/open_do.rs
+++ b/yazi-actor/src/mgr/open_do.rs
@@ -5,7 +5,7 @@ use yazi_macro::succ;
use yazi_parser::mgr::OpenDoForm;
use yazi_proxy::{PickProxy, TasksProxy};
use yazi_scheduler::process::ProcessOpt;
-use yazi_shared::{data::Data, url::UrlCow};
+use yazi_shared::{data::Data, url::{UrlBuf, UrlCow}};
use crate::{Actor, Ctx};
@@ -20,9 +20,9 @@ impl Actor for OpenDo {
let targets: Vec<_> = opt
.targets
.into_iter()
- .map(|u| {
- let m = cx.mgr.mimetype.get(&u).unwrap_or_default();
- (u, m)
+ .map(|file| {
+ let mime = cx.mgr.mimetype.get(&file.url).unwrap_or_default();
+ (file, mime)
})
.filter(|(_, m)| !m.is_empty())
.collect();
@@ -39,8 +39,10 @@ impl Actor for OpenDo {
}
let pick = PickProxy::show(PickCfg::open(openers.iter().map(|o| o.desc()).collect()));
- let urls: Vec<_> =
- [UrlCow::default()].into_iter().chain(targets.into_iter().map(|(u, _)| u)).collect();
+ let urls: Vec<_> = [UrlCow::default()]
+ .into_iter()
+ .chain(targets.into_iter().map(|(file, _)| file.url.into()))
+ .collect();
tokio::spawn(async move {
if let Some(choice) = pick.await {
TasksProxy::open_shell_compat(ProcessOpt {
@@ -59,11 +61,11 @@ impl Actor for OpenDo {
impl OpenDo {
// TODO: remove
- fn match_and_open(cx: &Ctx, cwd: UrlCow<'static>, targets: Vec<(UrlCow<'static>, &str)>) {
+ fn match_and_open(cx: &Ctx, cwd: UrlBuf, targets: Vec<(yazi_fs::File, &str)>) {
let mut openers = HashMap::new();
- for (url, mime) in targets {
- if let Some(opener) = YAZI.opener.first(YAZI.open.all(&url, mime)) {
- openers.entry(opener).or_insert_with(|| vec![UrlCow::default()]).push(url);
+ for (file, mime) in targets {
+ if let Some(opener) = YAZI.opener.first(YAZI.open.all(&file, mime)) {
+ openers.entry(opener).or_insert_with(|| vec![UrlCow::default()]).push(file.url.into());
}
}
for (opener, args) in openers {
diff --git a/yazi-actor/src/mgr/seek.rs b/yazi-actor/src/mgr/seek.rs
index 6e0ed78d..fde0477a 100644
--- a/yazi-actor/src/mgr/seek.rs
+++ b/yazi-actor/src/mgr/seek.rs
@@ -25,12 +25,12 @@ impl Actor for Seek {
succ!(cx.tab_mut().preview.reset());
};
- let Some(previewer) = YAZI.plugin.previewer(hovered, mime) else {
+ let Some(previewer) = YAZI.plugin.previewers.matches(hovered, mime) else {
succ!(cx.tab_mut().preview.reset());
};
let job = SeekJob { file: hovered.clone(), units: form.units };
- let opt = PluginOpt::new_callback(&*previewer.run.name, move |_, plugin| {
+ let opt = PluginOpt::new_callback(previewer.name.clone(), move |_, plugin| {
plugin.call_method("seek", job)
});
act!(app:plugin, cx, opt)
diff --git a/yazi-actor/src/mgr/shell.rs b/yazi-actor/src/mgr/shell.rs
index eb4a02c6..de091fb9 100644
--- a/yazi-actor/src/mgr/shell.rs
+++ b/yazi-actor/src/mgr/shell.rs
@@ -21,7 +21,7 @@ impl Actor for Shell {
fn act(cx: &mut Ctx, mut form: Self::Form) -> Result {
act!(mgr:escape_visual, cx)?;
- let cwd = form.cwd.take().unwrap_or(cx.cwd().into()).into_owned();
+ let cwd = form.cwd.take().unwrap_or_else(|| cx.cwd().clone());
let selected: Vec<_> = cx.tab().hovered_and_selected().cloned().map(Into::into).collect();
let input = form.interactive.then(|| {
@@ -40,7 +40,7 @@ impl Actor for Shell {
}
TasksProxy::open_shell_compat(ProcessOpt {
- cwd: cwd.into(),
+ cwd,
cmd: form.run.to_string().into(),
args: selected,
block: form.block,
diff --git a/yazi-actor/src/mgr/toggle.rs b/yazi-actor/src/mgr/toggle.rs
index 59f7a455..b9c129a4 100644
--- a/yazi-actor/src/mgr/toggle.rs
+++ b/yazi-actor/src/mgr/toggle.rs
@@ -2,7 +2,7 @@ use anyhow::Result;
use yazi_macro::{render_and, succ};
use yazi_parser::mgr::ToggleForm;
use yazi_scheduler::NotifyProxy;
-use yazi_shared::{data::Data, url::UrlCow};
+use yazi_shared::data::Data;
use crate::{Actor, Ctx};
@@ -15,7 +15,7 @@ impl Actor for Toggle {
fn act(cx: &mut Ctx, form: Self::Form) -> Result {
let tab = cx.tab_mut();
- let Some(url) = form.url.or(tab.current.hovered().map(|h| UrlCow::from(&h.url))) else {
+ let Some(url) = form.url.or_else(|| tab.hovered().map(|h| h.url.clone())) else {
succ!();
};
diff --git a/yazi-actor/src/mgr/upload.rs b/yazi-actor/src/mgr/upload.rs
index d44fe224..2ba8d8b0 100644
--- a/yazi-actor/src/mgr/upload.rs
+++ b/yazi-actor/src/mgr/upload.rs
@@ -14,7 +14,7 @@ impl Actor for Upload {
fn act(cx: &mut Ctx, form: Self::Form) -> Result {
for url in form.urls {
- cx.tasks.scheduler.file_upload(url.into_owned());
+ cx.tasks.scheduler.file_upload(url);
}
succ!();
}
diff --git a/yazi-adapter/src/adapters.rs b/yazi-adapter/src/adapters.rs
index 36b50e71..77912c41 100644
--- a/yazi-adapter/src/adapters.rs
+++ b/yazi-adapter/src/adapters.rs
@@ -33,7 +33,7 @@ impl From for Adapters {
B::Ghostty => vec![A::Kgp],
B::Microsoft => vec![A::Sixel],
B::Warp => vec![A::Iip, A::KgpOld],
- B::Rio => vec![A::Iip, A::Sixel],
+ B::Rio => vec![A::Kgp],
B::BlackBox => vec![A::Sixel],
B::VSCode => vec![A::Iip, A::Sixel],
B::Tabby => vec![A::Iip, A::Sixel],
diff --git a/yazi-binding/src/access.rs b/yazi-binding/src/access.rs
index bb8a1d85..1134d982 100644
--- a/yazi-binding/src/access.rs
+++ b/yazi-binding/src/access.rs
@@ -8,15 +8,15 @@ pub struct Access(yazi_vfs::provider::Gate);
impl UserData for Access {
fn add_methods>(methods: &mut M) {
- methods.add_function_mut("append", |_, (ud, append): (AnyUserData, bool)| {
+ methods.add_function("append", |_, (ud, append): (AnyUserData, bool)| {
ud.borrow_mut::()?.0.append(append);
Ok(ud)
});
- methods.add_function_mut("create", |_, (ud, create): (AnyUserData, bool)| {
+ methods.add_function("create", |_, (ud, create): (AnyUserData, bool)| {
ud.borrow_mut::()?.0.create(create);
Ok(ud)
});
- methods.add_function_mut("create_new", |_, (ud, create_new): (AnyUserData, bool)| {
+ methods.add_function("create_new", |_, (ud, create_new): (AnyUserData, bool)| {
ud.borrow_mut::()?.0.create_new(create_new);
Ok(ud)
});
@@ -26,15 +26,15 @@ impl UserData for Access {
Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua),
}
});
- methods.add_function_mut("read", |_, (ud, read): (AnyUserData, bool)| {
+ methods.add_function("read", |_, (ud, read): (AnyUserData, bool)| {
ud.borrow_mut::()?.0.read(read);
Ok(ud)
});
- methods.add_function_mut("truncate", |_, (ud, truncate): (AnyUserData, bool)| {
+ methods.add_function("truncate", |_, (ud, truncate): (AnyUserData, bool)| {
ud.borrow_mut::()?.0.truncate(truncate);
Ok(ud)
});
- methods.add_function_mut("write", |_, (ud, write): (AnyUserData, bool)| {
+ methods.add_function("write", |_, (ud, write): (AnyUserData, bool)| {
ud.borrow_mut::()?.0.write(write);
Ok(ud)
});
diff --git a/yazi-binding/src/config/fetcher.rs b/yazi-binding/src/config/fetcher.rs
new file mode 100644
index 00000000..eb2d799e
--- /dev/null
+++ b/yazi-binding/src/config/fetcher.rs
@@ -0,0 +1,32 @@
+use std::{ops::Deref, sync::Arc};
+
+use mlua::{UserData, UserDataFields, Value};
+
+use crate::{Id, cached_field};
+
+#[derive(Clone)]
+pub struct Fetcher {
+ inner: Arc,
+
+ v_name: Option,
+}
+
+impl Deref for Fetcher {
+ type Target = yazi_config::plugin::Fetcher;
+
+ fn deref(&self) -> &Self::Target { &self.inner }
+}
+
+impl Fetcher {
+ pub fn new(inner: impl Into>) -> Self {
+ Self { inner: inner.into(), v_name: None }
+ }
+}
+
+impl UserData for Fetcher {
+ fn add_fields>(fields: &mut F) {
+ fields.add_field_method_get("id", |_, me| Ok(Id(me.id)));
+
+ cached_field!(fields, name, |lua, me| lua.create_string(&*me.name));
+ }
+}
diff --git a/yazi-binding/src/config/fetchers.rs b/yazi-binding/src/config/fetchers.rs
new file mode 100644
index 00000000..922efc34
--- /dev/null
+++ b/yazi-binding/src/config/fetchers.rs
@@ -0,0 +1,59 @@
+use mlua::{ExternalError, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
+use yazi_config::YAZI;
+
+use crate::{FileRef, Id, Iter, config::Fetcher};
+
+pub struct Fetchers;
+
+impl UserData for Fetchers {
+ fn add_methods>(methods: &mut M) {
+ methods.add_method("match", |lua, _, matcher: Option| match matcher {
+ Some(matcher) => matcher.into_lua(lua),
+ None => FetcherMatcher::new(&YAZI.plugin.fetchers).into_lua(lua),
+ });
+
+ methods.add_meta_method(MetaMethod::Len, |_, _, ()| Ok(YAZI.plugin.fetchers.load().len()));
+ }
+}
+
+// --- Matcher
+pub struct FetcherMatcher(yazi_config::plugin::FetcherMatcher<'static>);
+
+impl FetcherMatcher {
+ fn new(inner: impl Into>) -> Self {
+ Self(inner.into())
+ }
+}
+
+impl TryFrom for FetcherMatcher {
+ type Error = mlua::Error;
+
+ fn try_from(value: Table) -> Result {
+ let id: Id = value.raw_get("id").unwrap_or_default();
+ let file: Option = value.raw_get("file")?;
+ let mime: Option = value.raw_get("mime")?;
+
+ Ok(Self(yazi_config::plugin::FetcherMatcher {
+ fetchers: YAZI.plugin.fetchers.load_full(),
+ id: id.0,
+ file: file.map(|f| f.inner.clone().into()),
+ mime: mime.map(Into::into),
+ ..Default::default()
+ }))
+ }
+}
+
+impl FromLua for FetcherMatcher {
+ fn from_lua(value: Value, _: &Lua) -> mlua::Result {
+ match value {
+ Value::Table(t) => t.try_into(),
+ _ => return Err("expected a table of FetcherMatcher".into_lua_err()),
+ }
+ }
+}
+
+impl IntoLua for FetcherMatcher {
+ fn into_lua(self, lua: &Lua) -> mlua::Result {
+ Iter::new(self.0.into_iter().map(Fetcher::new), None).into_lua(lua)
+ }
+}
diff --git a/yazi-binding/src/config/mod.rs b/yazi-binding/src/config/mod.rs
new file mode 100644
index 00000000..5d106eb4
--- /dev/null
+++ b/yazi-binding/src/config/mod.rs
@@ -0,0 +1 @@
+yazi_macro::mod_flat!(fetcher fetchers preloader preloaders previewer previewers spotter spotters);
diff --git a/yazi-binding/src/config/preloader.rs b/yazi-binding/src/config/preloader.rs
new file mode 100644
index 00000000..08403d5a
--- /dev/null
+++ b/yazi-binding/src/config/preloader.rs
@@ -0,0 +1,32 @@
+use std::{ops::Deref, sync::Arc};
+
+use mlua::{UserData, UserDataFields, Value};
+
+use crate::{Id, cached_field};
+
+#[derive(Clone)]
+pub struct Preloader {
+ inner: Arc,
+
+ v_name: Option,
+}
+
+impl Deref for Preloader {
+ type Target = yazi_config::plugin::Preloader;
+
+ fn deref(&self) -> &Self::Target { &self.inner }
+}
+
+impl Preloader {
+ pub fn new(inner: impl Into>) -> Self {
+ Self { inner: inner.into(), v_name: None }
+ }
+}
+
+impl UserData for Preloader {
+ fn add_fields>(fields: &mut F) {
+ fields.add_field_method_get("id", |_, me| Ok(Id(me.id)));
+
+ cached_field!(fields, name, |lua, me| lua.create_string(&*me.name));
+ }
+}
diff --git a/yazi-binding/src/config/preloaders.rs b/yazi-binding/src/config/preloaders.rs
new file mode 100644
index 00000000..dfa87eaf
--- /dev/null
+++ b/yazi-binding/src/config/preloaders.rs
@@ -0,0 +1,59 @@
+use mlua::{ExternalError, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
+use yazi_config::YAZI;
+
+use crate::{FileRef, Id, Iter, config::Preloader};
+
+pub struct Preloaders;
+
+impl UserData for Preloaders {
+ fn add_methods>(methods: &mut M) {
+ methods.add_method("match", |lua, _, matcher: Option| match matcher {
+ Some(matcher) => matcher.into_lua(lua),
+ None => PreloaderMatcher::new(&YAZI.plugin.preloaders).into_lua(lua),
+ });
+
+ methods.add_meta_method(MetaMethod::Len, |_, _, ()| Ok(YAZI.plugin.preloaders.load().len()));
+ }
+}
+
+// --- Matcher
+pub struct PreloaderMatcher(yazi_config::plugin::PreloaderMatcher<'static>);
+
+impl PreloaderMatcher {
+ fn new(inner: impl Into>) -> Self {
+ Self(inner.into())
+ }
+}
+
+impl TryFrom for PreloaderMatcher {
+ type Error = mlua::Error;
+
+ fn try_from(value: Table) -> Result {
+ let id: Id = value.raw_get("id").unwrap_or_default();
+ let file: Option = value.raw_get("file")?;
+ let mime: Option = value.raw_get("mime")?;
+
+ Ok(Self(yazi_config::plugin::PreloaderMatcher {
+ preloaders: YAZI.plugin.preloaders.load_full(),
+ id: id.0,
+ file: file.map(|f| f.inner.clone().into()),
+ mime: mime.map(Into::into),
+ ..Default::default()
+ }))
+ }
+}
+
+impl FromLua for PreloaderMatcher {
+ fn from_lua(value: Value, _: &Lua) -> mlua::Result {
+ match value {
+ Value::Table(t) => t.try_into(),
+ _ => return Err("expected a table of PreloaderMatcher".into_lua_err()),
+ }
+ }
+}
+
+impl IntoLua for PreloaderMatcher {
+ fn into_lua(self, lua: &Lua) -> mlua::Result {
+ Iter::new(self.0.into_iter().map(Preloader::new), None).into_lua(lua)
+ }
+}
diff --git a/yazi-binding/src/config/previewer.rs b/yazi-binding/src/config/previewer.rs
new file mode 100644
index 00000000..8530c949
--- /dev/null
+++ b/yazi-binding/src/config/previewer.rs
@@ -0,0 +1,69 @@
+use std::{ops::Deref, sync::Arc};
+
+use mlua::{AnyUserData, ExternalError, FromLua, Lua, UserData, UserDataFields, Value};
+use yazi_config::plugin::previewer_id;
+
+use crate::{Id, Selector, cached_field};
+
+const EXPECTED: &str = "expected a table or Previewer";
+
+#[derive(Clone)]
+pub struct Previewer {
+ inner: Arc,
+
+ v_name: Option,
+}
+
+impl Deref for Previewer {
+ type Target = yazi_config::plugin::Previewer;
+
+ fn deref(&self) -> &Self::Target { &self.inner }
+}
+
+impl From for Arc {
+ fn from(value: Previewer) -> Self { value.inner }
+}
+
+impl Previewer {
+ pub fn new(inner: impl Into>) -> Self {
+ Self { inner: inner.into(), v_name: None }
+ }
+}
+
+impl TryFrom for Previewer {
+ type Error = mlua::Error;
+
+ fn try_from(t: mlua::Table) -> Result {
+ Ok(Self::new(yazi_config::plugin::Previewer {
+ id: previewer_id(),
+ selector: Selector::try_from(&t)?.into(),
+ run: t.raw_get::("run")?.to_str()?.parse()?,
+ }))
+ }
+}
+
+impl TryFrom for Previewer {
+ type Error = mlua::Error;
+
+ fn try_from(value: AnyUserData) -> Result {
+ Ok(Self::new(value.borrow::()?.clone()))
+ }
+}
+
+impl FromLua for Previewer {
+ fn from_lua(value: Value, _: &Lua) -> mlua::Result {
+ match value {
+ Value::Table(tbl) => Self::try_from(tbl),
+ Value::UserData(ud) => Self::try_from(ud),
+ _ => Err(EXPECTED.into_lua_err())?,
+ }
+ }
+}
+
+impl UserData for Previewer {
+ fn add_fields>(fields: &mut F) {
+ fields.add_field_method_get("id", |_, me| Ok(Id(me.id)));
+
+ cached_field!(fields, name, |lua, me| lua.create_string(&*me.name));
+ }
+}
diff --git a/yazi-binding/src/config/previewers.rs b/yazi-binding/src/config/previewers.rs
new file mode 100644
index 00000000..df5835d6
--- /dev/null
+++ b/yazi-binding/src/config/previewers.rs
@@ -0,0 +1,75 @@
+use mlua::{ExternalError, ExternalResult, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
+use yazi_config::YAZI;
+
+use crate::{FileRef, Id, Iter, config::Previewer};
+
+pub struct Previewers;
+
+impl UserData for Previewers {
+ fn add_methods>(methods: &mut M) {
+ methods.add_method("match", |lua, _, matcher: Option| match matcher {
+ Some(matcher) => matcher.into_lua(lua),
+ None => PreviewerMatcher::new(&YAZI.plugin.previewers).into_lua(lua),
+ });
+
+ methods.add_method("insert", |_, _, (index, previewer): (isize, Previewer)| {
+ let index = match index {
+ 1.. => index - 1,
+ 0 => return Err("index must be 1-based or negative".into_lua_err()),
+ _ => index,
+ };
+
+ YAZI.plugin.previewers.insert(index, previewer.clone().into()).into_lua_err()?;
+ Ok(previewer)
+ });
+
+ methods.add_method("remove", |_, _, matcher: PreviewerMatcher| {
+ YAZI.plugin.previewers.remove(matcher.0);
+ Ok(())
+ });
+
+ methods.add_meta_method(MetaMethod::Len, |_, _, ()| Ok(YAZI.plugin.previewers.load().len()));
+ }
+}
+
+// --- Matcher
+pub struct PreviewerMatcher(yazi_config::plugin::PreviewerMatcher<'static>);
+
+impl PreviewerMatcher {
+ fn new(inner: impl Into>) -> Self {
+ Self(inner.into())
+ }
+}
+
+impl TryFrom for PreviewerMatcher {
+ type Error = mlua::Error;
+
+ fn try_from(value: Table) -> Result {
+ let id: Id = value.raw_get("id").unwrap_or_default();
+ let file: Option = value.raw_get("file")?;
+ let mime: Option = value.raw_get("mime")?;
+
+ Ok(Self(yazi_config::plugin::PreviewerMatcher {
+ previewers: YAZI.plugin.previewers.load_full(),
+ id: id.0,
+ file: file.map(|f| f.inner.clone().into()),
+ mime: mime.map(Into::into),
+ ..Default::default()
+ }))
+ }
+}
+
+impl FromLua for PreviewerMatcher {
+ fn from_lua(value: Value, _: &Lua) -> mlua::Result {
+ match value {
+ Value::Table(t) => t.try_into(),
+ _ => return Err("expected a table of PreviewerMatcher".into_lua_err()),
+ }
+ }
+}
+
+impl IntoLua for PreviewerMatcher {
+ fn into_lua(self, lua: &Lua) -> mlua::Result {
+ Iter::new(self.0.into_iter().map(Previewer::new), None).into_lua(lua)
+ }
+}
diff --git a/yazi-binding/src/config/spotter.rs b/yazi-binding/src/config/spotter.rs
new file mode 100644
index 00000000..be0ea1c4
--- /dev/null
+++ b/yazi-binding/src/config/spotter.rs
@@ -0,0 +1,32 @@
+use std::{ops::Deref, sync::Arc};
+
+use mlua::{UserData, UserDataFields, Value};
+
+use crate::{Id, cached_field};
+
+#[derive(Clone)]
+pub struct Spotter {
+ inner: Arc,
+
+ v_name: Option,
+}
+
+impl Deref for Spotter {
+ type Target = yazi_config::plugin::Spotter;
+
+ fn deref(&self) -> &Self::Target { &self.inner }
+}
+
+impl Spotter {
+ pub fn new(inner: impl Into>) -> Self {
+ Self { inner: inner.into(), v_name: None }
+ }
+}
+
+impl UserData for Spotter {
+ fn add_fields>(fields: &mut F) {
+ fields.add_field_method_get("id", |_, me| Ok(Id(me.id)));
+
+ cached_field!(fields, name, |lua, me| lua.create_string(&*me.name));
+ }
+}
diff --git a/yazi-binding/src/config/spotters.rs b/yazi-binding/src/config/spotters.rs
new file mode 100644
index 00000000..5e4a2d4b
--- /dev/null
+++ b/yazi-binding/src/config/spotters.rs
@@ -0,0 +1,59 @@
+use mlua::{ExternalError, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
+use yazi_config::YAZI;
+
+use crate::{FileRef, Id, Iter, config::Spotter};
+
+pub struct Spotters;
+
+impl UserData for Spotters {
+ fn add_methods>(methods: &mut M) {
+ methods.add_method("match", |lua, _, matcher: Option| match matcher {
+ Some(matcher) => matcher.into_lua(lua),
+ None => SpotterMatcher::new(&YAZI.plugin.spotters).into_lua(lua),
+ });
+
+ methods.add_meta_method(MetaMethod::Len, |_, _, ()| Ok(YAZI.plugin.spotters.load().len()));
+ }
+}
+
+// --- Matcher
+pub struct SpotterMatcher(yazi_config::plugin::SpotterMatcher<'static>);
+
+impl SpotterMatcher {
+ fn new(inner: impl Into>) -> Self {
+ Self(inner.into())
+ }
+}
+
+impl TryFrom for SpotterMatcher {
+ type Error = mlua::Error;
+
+ fn try_from(value: Table) -> Result {
+ let id: Id = value.raw_get("id").unwrap_or_default();
+ let file: Option = value.raw_get("file")?;
+ let mime: Option = value.raw_get("mime")?;
+
+ Ok(Self(yazi_config::plugin::SpotterMatcher {
+ spotters: YAZI.plugin.spotters.load_full(),
+ id: id.0,
+ file: file.map(|f| f.inner.clone().into()),
+ mime: mime.map(Into::into),
+ ..Default::default()
+ }))
+ }
+}
+
+impl FromLua for SpotterMatcher {
+ fn from_lua(value: Value, _: &Lua) -> mlua::Result {
+ match value {
+ Value::Table(t) => t.try_into(),
+ _ => return Err("expected a table of SpotterMatcher".into_lua_err()),
+ }
+ }
+}
+
+impl IntoLua for SpotterMatcher {
+ fn into_lua(self, lua: &Lua) -> mlua::Result {
+ Iter::new(self.0.into_iter().map(Spotter::new), None).into_lua(lua)
+ }
+}
diff --git a/yazi-binding/src/elements/bar.rs b/yazi-binding/src/elements/bar.rs
index a3eb15a1..eb94303b 100644
--- a/yazi-binding/src/elements/bar.rs
+++ b/yazi-binding/src/elements/bar.rs
@@ -81,11 +81,11 @@ impl UserData for Bar {
crate::impl_area_method!(methods);
crate::impl_style_method!(methods, style);
- methods.add_function_mut("edge", |_, (ud, edge): (AnyUserData, Edge)| {
+ methods.add_function("edge", |_, (ud, edge): (AnyUserData, Edge)| {
ud.borrow_mut::()?.edge = edge;
Ok(ud)
});
- methods.add_function_mut("symbol", |_, (ud, symbol): (AnyUserData, String)| {
+ methods.add_function("symbol", |_, (ud, symbol): (AnyUserData, String)| {
ud.borrow_mut::()?.symbol = symbol;
Ok(ud)
});
diff --git a/yazi-binding/src/elements/border.rs b/yazi-binding/src/elements/border.rs
index f32d0038..a56ac58d 100644
--- a/yazi-binding/src/elements/border.rs
+++ b/yazi-binding/src/elements/border.rs
@@ -79,7 +79,7 @@ impl UserData for Border {
crate::impl_area_method!(methods);
crate::impl_style_method!(methods, style);
- methods.add_function_mut("type", |_, (ud, value): (AnyUserData, u8)| {
+ methods.add_function("type", |_, (ud, value): (AnyUserData, u8)| {
ud.borrow_mut::()?.r#type = match value {
ROUNDED => ratatui::widgets::BorderType::Rounded,
DOUBLE => ratatui::widgets::BorderType::Double,
@@ -90,20 +90,17 @@ impl UserData for Border {
};
Ok(ud)
});
- methods.add_function_mut(
- "title",
- |_, (ud, line, position): (AnyUserData, Line, Option)| {
- let position = if position == Some(Borders::BOTTOM.bits()) {
- ratatui::widgets::TitlePosition::Bottom
- } else {
- ratatui::widgets::TitlePosition::Top
- };
+ methods.add_function("title", |_, (ud, line, position): (AnyUserData, Line, Option)| {
+ let position = if position == Some(Borders::BOTTOM.bits()) {
+ ratatui::widgets::TitlePosition::Bottom
+ } else {
+ ratatui::widgets::TitlePosition::Top
+ };
- ud.borrow_mut::()?.titles.push((position, line.inner));
- Ok(ud)
- },
- );
- methods.add_function_mut("edge", |_, (ud, edge): (AnyUserData, Edge)| {
+ ud.borrow_mut::()?.titles.push((position, line.inner));
+ Ok(ud)
+ });
+ methods.add_function("edge", |_, (ud, edge): (AnyUserData, Edge)| {
ud.borrow_mut::()?.edge = edge;
Ok(ud)
});
diff --git a/yazi-binding/src/elements/gauge.rs b/yazi-binding/src/elements/gauge.rs
index c3543a5c..d9eb611c 100644
--- a/yazi-binding/src/elements/gauge.rs
+++ b/yazi-binding/src/elements/gauge.rs
@@ -57,7 +57,7 @@ impl UserData for Gauge {
crate::impl_area_method!(methods);
crate::impl_style_method!(methods, style);
- methods.add_function_mut("percent", |_, (ud, percent): (AnyUserData, u8)| {
+ methods.add_function("percent", |_, (ud, percent): (AnyUserData, u8)| {
if percent > 100 {
return Err("percent must be between 0 and 100".into_lua_err());
}
@@ -66,7 +66,7 @@ impl UserData for Gauge {
Ok(ud)
});
- methods.add_function_mut("ratio", |_, (ud, ratio): (AnyUserData, f64)| {
+ methods.add_function("ratio", |_, (ud, ratio): (AnyUserData, f64)| {
if !(0.0..1.0).contains(&ratio) {
return Err("ratio must be between 0 and 1".into_lua_err());
}
@@ -75,12 +75,12 @@ impl UserData for Gauge {
Ok(ud)
});
- methods.add_function_mut("label", |_, (ud, label): (AnyUserData, Span)| {
+ methods.add_function("label", |_, (ud, label): (AnyUserData, Span)| {
ud.borrow_mut::()?.label = Some(label.0);
Ok(ud)
});
- methods.add_function_mut("gauge_style", |_, (ud, style): (AnyUserData, Style)| {
+ methods.add_function("gauge_style", |_, (ud, style): (AnyUserData, Style)| {
ud.borrow_mut::()?.gauge_style = style.0;
Ok(ud)
});
diff --git a/yazi-binding/src/elements/layout.rs b/yazi-binding/src/elements/layout.rs
index 5449d70e..bf499894 100644
--- a/yazi-binding/src/elements/layout.rs
+++ b/yazi-binding/src/elements/layout.rs
@@ -25,15 +25,15 @@ impl Layout {
impl UserData for Layout {
fn add_methods>(methods: &mut M) {
- methods.add_function_mut("direction", |_, (ud, value): (AnyUserData, bool)| {
+ methods.add_function("direction", |_, (ud, value): (AnyUserData, bool)| {
ud.borrow_mut::()?.direction = value;
Ok(ud)
});
- methods.add_function_mut("margin", |_, (ud, value): (AnyUserData, u16)| {
+ methods.add_function("margin", |_, (ud, value): (AnyUserData, u16)| {
ud.borrow_mut::()?.margin = Some(ratatui::layout::Margin::new(value, value));
Ok(ud)
});
- methods.add_function_mut("margin_h", |_, (ud, value): (AnyUserData, u16)| {
+ methods.add_function("margin_h", |_, (ud, value): (AnyUserData, u16)| {
{
let mut me = ud.borrow_mut::()?;
if let Some(margin) = &mut me.margin {
@@ -44,7 +44,7 @@ impl UserData for Layout {
}
Ok(ud)
});
- methods.add_function_mut("margin_v", |_, (ud, value): (AnyUserData, u16)| {
+ methods.add_function("margin_v", |_, (ud, value): (AnyUserData, u16)| {
{
let mut me = ud.borrow_mut::()?;
if let Some(margin) = &mut me.margin {
@@ -55,7 +55,7 @@ impl UserData for Layout {
}
Ok(ud)
});
- methods.add_function_mut("constraints", |_, (ud, value): (AnyUserData, Vec)| {
+ methods.add_function("constraints", |_, (ud, value): (AnyUserData, Vec)| {
ud.borrow_mut::()?.constraints = value.into_iter().map(Into::into).collect();
Ok(ud)
});
diff --git a/yazi-binding/src/elements/line.rs b/yazi-binding/src/elements/line.rs
index 8d23a4a2..7a38dfcb 100644
--- a/yazi-binding/src/elements/line.rs
+++ b/yazi-binding/src/elements/line.rs
@@ -133,14 +133,14 @@ impl UserData for Line {
crate::impl_style_shorthands!(methods, style);
methods.add_method("width", |_, me, ()| Ok(me.width()));
- methods.add_function_mut("align", |_, (ud, align): (AnyUserData, Align)| {
+ methods.add_function("align", |_, (ud, align): (AnyUserData, Align)| {
ud.borrow_mut::()?.alignment = Some(align.0);
Ok(ud)
});
methods.add_method("visible", |_, me, ()| {
Ok(me.iter().flat_map(|s| s.content.chars()).any(|c| c.width().unwrap_or(0) > 0))
});
- methods.add_function_mut("truncate", |lua, (ud, t): (AnyUserData, Table)| {
+ methods.add_function("truncate", |lua, (ud, t): (AnyUserData, Table)| {
let mut me = ud.borrow_mut::()?;
let max = t.raw_get("max")?;
diff --git a/yazi-binding/src/elements/pos.rs b/yazi-binding/src/elements/pos.rs
index 5912f223..4e701c4c 100644
--- a/yazi-binding/src/elements/pos.rs
+++ b/yazi-binding/src/elements/pos.rs
@@ -91,7 +91,7 @@ impl UserData for Pos {
}
fn add_methods>(methods: &mut M) {
- methods.add_function_mut("pad", |_, (ud, pad): (AnyUserData, Pad)| {
+ methods.add_function("pad", |_, (ud, pad): (AnyUserData, Pad)| {
ud.borrow_mut::()?.pad = pad;
Ok(ud)
});
diff --git a/yazi-binding/src/elements/row.rs b/yazi-binding/src/elements/row.rs
index 9120eeb7..969f81ef 100644
--- a/yazi-binding/src/elements/row.rs
+++ b/yazi-binding/src/elements/row.rs
@@ -55,15 +55,15 @@ impl UserData for Row {
fn add_methods>(methods: &mut M) {
crate::impl_style_method!(methods, style);
- methods.add_function_mut("height", |_, (ud, value): (AnyUserData, u16)| {
+ methods.add_function("height", |_, (ud, value): (AnyUserData, u16)| {
ud.borrow_mut::()?.height = value;
Ok(ud)
});
- methods.add_function_mut("margin_t", |_, (ud, value): (AnyUserData, u16)| {
+ methods.add_function("margin_t", |_, (ud, value): (AnyUserData, u16)| {
ud.borrow_mut::()?.top_margin = value;
Ok(ud)
});
- methods.add_function_mut("margin_b", |_, (ud, value): (AnyUserData, u16)| {
+ methods.add_function("margin_b", |_, (ud, value): (AnyUserData, u16)| {
ud.borrow_mut::()?.bottom_margin = value;
Ok(ud)
});
diff --git a/yazi-binding/src/elements/span.rs b/yazi-binding/src/elements/span.rs
index 22609808..717a0d73 100644
--- a/yazi-binding/src/elements/span.rs
+++ b/yazi-binding/src/elements/span.rs
@@ -82,7 +82,7 @@ impl UserData for Span {
methods.add_method("visible", |_, Self(me), ()| {
Ok(me.content.chars().any(|c| c.width().unwrap_or(0) > 0))
});
- methods.add_function_mut("truncate", |_, (ud, t): (AnyUserData, Table)| {
+ methods.add_function("truncate", |_, (ud, t): (AnyUserData, Table)| {
ud.borrow_mut::()?.truncate(t.raw_get("max")?);
Ok(ud)
});
diff --git a/yazi-binding/src/elements/table.rs b/yazi-binding/src/elements/table.rs
index 9fa5ead1..f7defacf 100644
--- a/yazi-binding/src/elements/table.rs
+++ b/yazi-binding/src/elements/table.rs
@@ -108,45 +108,45 @@ impl UserData for Table {
fn add_methods>(methods: &mut M) {
crate::impl_area_method!(methods);
- methods.add_function_mut("header", |_, (ud, header): (AnyUserData, Row)| {
+ methods.add_function("header", |_, (ud, header): (AnyUserData, Row)| {
ud.borrow_mut::()?.header = Some(header.into());
Ok(ud)
});
- methods.add_function_mut("footer", |_, (ud, footer): (AnyUserData, Row)| {
+ methods.add_function("footer", |_, (ud, footer): (AnyUserData, Row)| {
ud.borrow_mut::()?.footer = Some(footer.into());
Ok(ud)
});
- methods.add_function_mut("widths", |_, (ud, widths): (AnyUserData, Vec)| {
+ methods.add_function("widths", |_, (ud, widths): (AnyUserData, Vec)| {
ud.borrow_mut::()?.widths = widths.into_iter().map(Into::into).collect();
Ok(ud)
});
- methods.add_function_mut("spacing", |_, (ud, spacing): (AnyUserData, u16)| {
+ methods.add_function("spacing", |_, (ud, spacing): (AnyUserData, u16)| {
ud.borrow_mut::()?.column_spacing = spacing;
Ok(ud)
});
- methods.add_function_mut("row", |_, (ud, idx): (AnyUserData, Option)| {
+ methods.add_function("row", |_, (ud, idx): (AnyUserData, Option)| {
ud.borrow_mut::()?.state.select(idx);
Ok(ud)
});
- methods.add_function_mut("col", |_, (ud, idx): (AnyUserData, Option)| {
+ methods.add_function("col", |_, (ud, idx): (AnyUserData, Option)| {
ud.borrow_mut::()?.state.select_column(idx);
Ok(ud)
});
- methods.add_function_mut("style", |_, (ud, style): (AnyUserData, Style)| {
+ methods.add_function("style", |_, (ud, style): (AnyUserData, Style)| {
ud.borrow_mut::()?.style = style.0;
Ok(ud)
});
- methods.add_function_mut("row_style", |_, (ud, style): (AnyUserData, Style)| {
+ methods.add_function("row_style", |_, (ud, style): (AnyUserData, Style)| {
ud.borrow_mut::()?.row_highlight_style = style.0;
Ok(ud)
});
- methods.add_function_mut("col_style", |_, (ud, style): (AnyUserData, Style)| {
+ methods.add_function("col_style", |_, (ud, style): (AnyUserData, Style)| {
ud.borrow_mut::()?.column_highlight_style = style.0;
Ok(ud)
});
- methods.add_function_mut("cell_style", |_, (ud, style): (AnyUserData, Style)| {
+ methods.add_function("cell_style", |_, (ud, style): (AnyUserData, Style)| {
ud.borrow_mut::()?.cell_highlight_style = style.0;
Ok(ud)
});
diff --git a/yazi-binding/src/elements/text.rs b/yazi-binding/src/elements/text.rs
index 47e824f3..64b0f8cf 100644
--- a/yazi-binding/src/elements/text.rs
+++ b/yazi-binding/src/elements/text.rs
@@ -124,15 +124,15 @@ impl UserData for Text {
crate::impl_style_method!(methods, inner.style);
crate::impl_style_shorthands!(methods, inner.style);
- methods.add_function_mut("align", |_, (ud, align): (AnyUserData, Align)| {
+ methods.add_function("align", |_, (ud, align): (AnyUserData, Align)| {
ud.borrow_mut::()?.inner.alignment = Some(align.0);
Ok(ud)
});
- methods.add_function_mut("wrap", |_, (ud, wrap): (AnyUserData, Wrap)| {
+ methods.add_function("wrap", |_, (ud, wrap): (AnyUserData, Wrap)| {
ud.borrow_mut::()?.wrap = wrap;
Ok(ud)
});
- methods.add_function_mut("scroll", |_, (ud, x, y): (AnyUserData, u16, u16)| {
+ methods.add_function("scroll", |_, (ud, x, y): (AnyUserData, u16, u16)| {
ud.borrow_mut::()?.scroll = ratatui::layout::Position { x, y };
Ok(ud)
});
diff --git a/yazi-binding/src/file.rs b/yazi-binding/src/file.rs
index d4c5761c..0ef0b640 100644
--- a/yazi-binding/src/file.rs
+++ b/yazi-binding/src/file.rs
@@ -10,7 +10,7 @@ const EXPECTED: &str = "expected a table, File, or fs::File";
#[derive(Clone)]
pub struct File {
- inner: yazi_fs::File,
+ pub(crate) inner: yazi_fs::File,
v_cha: Option,
v_url: Option,
diff --git a/yazi-binding/src/id.rs b/yazi-binding/src/id.rs
index 985316b0..1b38b478 100644
--- a/yazi-binding/src/id.rs
+++ b/yazi-binding/src/id.rs
@@ -2,7 +2,7 @@ use std::ops::Deref;
use mlua::{ExternalError, ExternalResult, FromLua, Lua, UserData, Value};
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Default)]
pub struct Id(pub yazi_shared::Id);
impl Deref for Id {
diff --git a/yazi-binding/src/lib.rs b/yazi-binding/src/lib.rs
index fc046f2d..8dda12e8 100644
--- a/yazi-binding/src/lib.rs
+++ b/yazi-binding/src/lib.rs
@@ -1,5 +1,5 @@
mod macros;
-yazi_macro::mod_pub!(elements process);
+yazi_macro::mod_pub!(config elements process);
-yazi_macro::mod_flat!(access calculator cha chan chord_cow composer error fd file handle icon id image input iter layer mouse path permit range runtime scheme stage style url utils);
+yazi_macro::mod_flat!(access calculator cha chan chord_cow composer error fd file handle icon id image input iter layer mouse path permit range runtime scheme selector stage style url utils);
diff --git a/yazi-binding/src/macros.rs b/yazi-binding/src/macros.rs
index 69f4d64e..94f7c220 100644
--- a/yazi-binding/src/macros.rs
+++ b/yazi-binding/src/macros.rs
@@ -88,7 +88,7 @@ macro_rules! cached_field_mut {
#[macro_export]
macro_rules! impl_area_method {
($methods:ident) => {
- $methods.add_function_mut(
+ $methods.add_function(
"area",
|lua, (ud, area): (mlua::AnyUserData, Option)| {
use mlua::IntoLua;
@@ -106,7 +106,7 @@ macro_rules! impl_area_method {
#[macro_export]
macro_rules! impl_style_method {
($methods:ident, $($field:tt).+) => {
- $methods.add_function_mut("style", |_, (ud, style): (mlua::AnyUserData, $crate::Style)| {
+ $methods.add_function("style", |_, (ud, style): (mlua::AnyUserData, $crate::Style)| {
ud.borrow_mut::()?.$($field).+ = style.0;
Ok(ud)
});
@@ -116,7 +116,7 @@ macro_rules! impl_style_method {
#[macro_export]
macro_rules! impl_style_shorthands {
($methods:ident, $($field:tt).+) => {
- $methods.add_function_mut("fg", |lua, (ud, value): (mlua::AnyUserData, mlua::Value)| {
+ $methods.add_function("fg", |lua, (ud, value): (mlua::AnyUserData, mlua::Value)| {
use $crate::elements::Color;
use mlua::FromLua;
use ratatui::style::Modifier;
@@ -135,7 +135,7 @@ macro_rules! impl_style_shorthands {
}
}
});
- $methods.add_function_mut("bg", |lua, (ud, value): (mlua::AnyUserData, mlua::Value)| {
+ $methods.add_function("bg", |lua, (ud, value): (mlua::AnyUserData, mlua::Value)| {
use $crate::elements::Color;
use mlua::FromLua;
use ratatui::style::Modifier;
@@ -154,7 +154,7 @@ macro_rules! impl_style_shorthands {
}
}
});
- $methods.add_function_mut("bold", |_, (ud, remove): (mlua::AnyUserData, bool)| {
+ $methods.add_function("bold", |_, (ud, remove): (mlua::AnyUserData, bool)| {
let me = &mut ud.borrow_mut::()?.$($field).+;
if remove {
*me = me.remove_modifier(ratatui::style::Modifier::BOLD);
@@ -163,7 +163,7 @@ macro_rules! impl_style_shorthands {
}
Ok(ud)
});
- $methods.add_function_mut("dim", |_, (ud, remove): (mlua::AnyUserData, bool)| {
+ $methods.add_function("dim", |_, (ud, remove): (mlua::AnyUserData, bool)| {
let me = &mut ud.borrow_mut::()?.$($field).+;
if remove {
*me = me.remove_modifier(ratatui::style::Modifier::DIM);
@@ -172,7 +172,7 @@ macro_rules! impl_style_shorthands {
}
Ok(ud)
});
- $methods.add_function_mut("italic", |_, (ud, remove): (mlua::AnyUserData, bool)| {
+ $methods.add_function("italic", |_, (ud, remove): (mlua::AnyUserData, bool)| {
let me = &mut ud.borrow_mut::()?.$($field).+;
if remove {
*me = me.remove_modifier(ratatui::style::Modifier::ITALIC);
@@ -181,7 +181,7 @@ macro_rules! impl_style_shorthands {
}
Ok(ud)
});
- $methods.add_function_mut("underline", |_, (ud, remove): (mlua::AnyUserData, bool)| {
+ $methods.add_function("underline", |_, (ud, remove): (mlua::AnyUserData, bool)| {
let me = &mut ud.borrow_mut::()?.$($field).+;
if remove {
*me = me.remove_modifier(ratatui::style::Modifier::UNDERLINED);
@@ -190,7 +190,7 @@ macro_rules! impl_style_shorthands {
}
Ok(ud)
});
- $methods.add_function_mut("blink", |_, (ud, remove): (mlua::AnyUserData, bool)| {
+ $methods.add_function("blink", |_, (ud, remove): (mlua::AnyUserData, bool)| {
let me = &mut ud.borrow_mut::()?.$($field).+;
if remove {
*me = me.remove_modifier(ratatui::style::Modifier::SLOW_BLINK);
@@ -199,7 +199,7 @@ macro_rules! impl_style_shorthands {
}
Ok(ud)
});
- $methods.add_function_mut("blink_rapid", |_, (ud, remove): (mlua::AnyUserData, bool)| {
+ $methods.add_function("blink_rapid", |_, (ud, remove): (mlua::AnyUserData, bool)| {
let me = &mut ud.borrow_mut::()?.$($field).+;
if remove {
*me = me.remove_modifier(ratatui::style::Modifier::RAPID_BLINK);
@@ -208,7 +208,7 @@ macro_rules! impl_style_shorthands {
}
Ok(ud)
});
- $methods.add_function_mut("reverse", |_, (ud, remove): (mlua::AnyUserData, bool)| {
+ $methods.add_function("reverse", |_, (ud, remove): (mlua::AnyUserData, bool)| {
let me = &mut ud.borrow_mut::()?.$($field).+;
if remove {
*me = me.remove_modifier(ratatui::style::Modifier::REVERSED);
@@ -217,7 +217,7 @@ macro_rules! impl_style_shorthands {
}
Ok(ud)
});
- $methods.add_function_mut("hidden", |_, (ud, remove): (mlua::AnyUserData, bool)| {
+ $methods.add_function("hidden", |_, (ud, remove): (mlua::AnyUserData, bool)| {
let me = &mut ud.borrow_mut::()?.$($field).+;
if remove {
*me = me.remove_modifier(ratatui::style::Modifier::HIDDEN);
@@ -226,7 +226,7 @@ macro_rules! impl_style_shorthands {
}
Ok(ud)
});
- $methods.add_function_mut("crossed", |_, (ud, remove): (mlua::AnyUserData, bool)| {
+ $methods.add_function("crossed", |_, (ud, remove): (mlua::AnyUserData, bool)| {
let me = &mut ud.borrow_mut::()?.$($field).+;
if remove {
*me = me.remove_modifier(ratatui::style::Modifier::CROSSED_OUT);
@@ -235,7 +235,7 @@ macro_rules! impl_style_shorthands {
}
Ok(ud)
});
- $methods.add_function_mut("reset", |_, ud: mlua::AnyUserData| {
+ $methods.add_function("reset", |_, ud: mlua::AnyUserData| {
ud.borrow_mut::()?.$($field).+ = ratatui::style::Style::reset();
Ok(ud)
});
diff --git a/yazi-binding/src/process/child.rs b/yazi-binding/src/process/child.rs
index 961cdcb9..b0550167 100644
--- a/yazi-binding/src/process/child.rs
+++ b/yazi-binding/src/process/child.rs
@@ -3,10 +3,9 @@ use std::{ops::DerefMut, process::ExitStatus, time::Duration};
use futures::future::try_join3;
use mlua::{AnyUserData, ExternalError, IntoLua, IntoLuaMulti, Table, UserData, UserDataMethods, Value};
use tokio::{io::{self, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter}, process::{ChildStderr, ChildStdin, ChildStdout}, select};
-use crate::Error;
use super::Status;
-use crate::process::Output;
+use crate::{Error, process::Output};
pub struct Child {
inner: tokio::process::Child,
diff --git a/yazi-binding/src/process/command.rs b/yazi-binding/src/process/command.rs
index 5dd4fdbc..bc18d5e8 100644
--- a/yazi-binding/src/process/command.rs
+++ b/yazi-binding/src/process/command.rs
@@ -138,7 +138,7 @@ impl UserData for Command {
)
}
- methods.add_function_mut("arg", |lua, (ud, arg): (AnyUserData, Value)| {
+ methods.add_function("arg", |lua, (ud, arg): (AnyUserData, Value)| {
let mut me = ud.borrow_mut::()?;
match arg {
Value::Nil => return lua.create_sequence_from(me.inner.as_std().get_args())?.into_lua(lua),
@@ -154,11 +154,11 @@ impl UserData for Command {
}
ud.into_lua(lua)
});
- methods.add_function_mut("cwd", |_, (ud, dir): (AnyUserData, mlua::String)| {
+ methods.add_function("cwd", |_, (ud, dir): (AnyUserData, mlua::String)| {
ud.borrow_mut::()?.inner.current_dir(dir.to_str()?.as_ref());
Ok(ud)
});
- methods.add_function_mut(
+ methods.add_function(
"env",
|_, (ud, key, value): (AnyUserData, mlua::String, mlua::String)| {
ud.borrow_mut::()?
@@ -167,19 +167,19 @@ impl UserData for Command {
Ok(ud)
},
);
- methods.add_function_mut("stdin", |_, (ud, stdio): (AnyUserData, Value)| {
+ methods.add_function("stdin", |_, (ud, stdio): (AnyUserData, Value)| {
ud.borrow_mut::()?.inner.stdin(make_stdio(stdio)?);
Ok(ud)
});
- methods.add_function_mut("stdout", |_, (ud, stdio): (AnyUserData, Value)| {
+ methods.add_function("stdout", |_, (ud, stdio): (AnyUserData, Value)| {
ud.borrow_mut::()?.inner.stdout(make_stdio(stdio)?);
Ok(ud)
});
- methods.add_function_mut("stderr", |_, (ud, stdio): (AnyUserData, Value)| {
+ methods.add_function("stderr", |_, (ud, stdio): (AnyUserData, Value)| {
ud.borrow_mut::()?.inner.stderr(make_stdio(stdio)?);
Ok(ud)
});
- methods.add_function_mut("memory", |_, (ud, max): (AnyUserData, usize)| {
+ methods.add_function("memory", |_, (ud, max): (AnyUserData, usize)| {
ud.borrow_mut::()?.memory = Some(max);
Ok(ud)
});
diff --git a/yazi-binding/src/process/output.rs b/yazi-binding/src/process/output.rs
index ad0a05ef..f0892486 100644
--- a/yazi-binding/src/process/output.rs
+++ b/yazi-binding/src/process/output.rs
@@ -1,9 +1,9 @@
use std::mem;
use mlua::{UserData, Value};
-use crate::{cached_field, cached_field_mut};
use super::Status;
+use crate::{cached_field, cached_field_mut};
pub struct Output {
inner: std::process::Output,
diff --git a/yazi-binding/src/selector.rs b/yazi-binding/src/selector.rs
new file mode 100644
index 00000000..9b511599
--- /dev/null
+++ b/yazi-binding/src/selector.rs
@@ -0,0 +1,43 @@
+use std::ops::Deref;
+
+use mlua::{ExternalError, FromLua, Lua, Table, UserData, Value};
+
+pub struct Selector(yazi_config::Selector);
+
+impl Deref for Selector {
+ type Target = yazi_config::Selector;
+
+ fn deref(&self) -> &Self::Target { &self.0 }
+}
+
+impl From for yazi_config::Selector {
+ fn from(value: Selector) -> Self { value.0 }
+}
+
+impl TryFrom<&Table> for Selector {
+ type Error = mlua::Error;
+
+ fn try_from(t: &Table) -> Result {
+ Ok(Self(yazi_config::Selector::new(
+ t.raw_get::