mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: make UI extensions easier (#1257)
This commit is contained in:
parent
54eb0cc663
commit
f5598ebb8a
66 changed files with 1026 additions and 789 deletions
189
Cargo.lock
generated
189
Cargo.lock
generated
|
|
@ -206,9 +206,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.5.0"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
|
|
@ -303,9 +303,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.7"
|
||||
version = "4.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f"
|
||||
checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
|
@ -313,9 +313,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.7"
|
||||
version = "4.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f"
|
||||
checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
|
@ -325,9 +325,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.5.6"
|
||||
version = "4.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbca90c87c2a04da41e95d1856e8bcd22f159bdbfa147314d2ce5218057b0e58"
|
||||
checksum = "5b4be9c4c4b1f30b78d8a750e0822b6a6102d97e62061c583a6c1dea2dfb33ae"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
|
@ -354,14 +354,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.5"
|
||||
version = "4.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6"
|
||||
checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -372,9 +372,9 @@ checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70"
|
|||
|
||||
[[package]]
|
||||
name = "clipboard-win"
|
||||
version = "5.3.1"
|
||||
version = "5.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79f4473f5144e20d9aceaf2972478f06ddf687831eafeeb434fbaf0acc4144ad"
|
||||
checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892"
|
||||
dependencies = [
|
||||
"error-code",
|
||||
]
|
||||
|
|
@ -480,7 +480,7 @@ version = "0.27.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"crossterm_winapi",
|
||||
"futures-core",
|
||||
"libc",
|
||||
|
|
@ -537,7 +537,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -548,7 +548,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
|
|||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -560,6 +560,37 @@ dependencies = [
|
|||
"powerfmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0350b5cb0331628a5916d6c5c0b72e97393b8b6b03b47a9284f4e7f5a405ffd7"
|
||||
dependencies = [
|
||||
"derive_builder_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder_core"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d48cda787f839151732d396ac69e3473923d54312c070ee21e9effcaa8ca0b1d"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder_macro"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b"
|
||||
dependencies = [
|
||||
"derive_builder_core",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
|
|
@ -792,7 +823,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -846,6 +877,18 @@ dependencies = [
|
|||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getset"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e45727250e75cc04ff2846a66397da8ef2b3db8e40e0cef4df67950a07621eb9"
|
||||
dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gif"
|
||||
version = "0.13.1"
|
||||
|
|
@ -1110,7 +1153,7 @@ version = "0.1.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"libc",
|
||||
]
|
||||
|
||||
|
|
@ -1257,7 +1300,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1282,7 +1325,7 @@ version = "6.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"filetime",
|
||||
"fsevent-sys",
|
||||
"inotify",
|
||||
|
|
@ -1366,7 +1409,7 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"block2",
|
||||
"libc",
|
||||
"objc2",
|
||||
|
|
@ -1588,7 +1631,7 @@ version = "0.27.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d16546c5b5962abf8ce6e2881e722b4e0ae3b6f1a08a26ae3573c55853ca68d3"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"cassowary",
|
||||
"compact_str",
|
||||
"crossterm",
|
||||
|
|
@ -1638,7 +1681,7 @@ version = "0.5.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1699,7 +1742,7 @@ version = "0.38.34"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
|
|
@ -1735,9 +1778,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.203"
|
||||
version = "1.0.204"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
|
||||
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
|
@ -1754,20 +1797,20 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.203"
|
||||
version = "1.0.204"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
|
||||
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.117"
|
||||
version = "1.0.120"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
|
||||
checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
|
@ -1893,7 +1936,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "2ff9eaf853dec4c8802325d8b6d3dffa86cc707fd7a1a4cdbf416e13b061787a"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1927,7 +1970,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1937,14 +1980,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.67"
|
||||
version = "2.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff8655ed1d86f3af4ee3fd3263786bc14245ad17c4c7e85ba7187fb3ae028c90"
|
||||
checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -1989,7 +2033,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2108,7 +2152,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2159,9 +2203,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.14"
|
||||
version = "0.22.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38"
|
||||
checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
|
|
@ -2201,7 +2245,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2371,7 +2415,7 @@ dependencies = [
|
|||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2382,14 +2426,41 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
|||
|
||||
[[package]]
|
||||
name = "vergen"
|
||||
version = "8.3.1"
|
||||
version = "9.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e27d6bdd219887a9eadd19e1c34f32e47fa332301184935c6d9bca26f3cca525"
|
||||
checksum = "c32e7318e93a9ac53693b6caccfb05ff22e04a44c7cf8a279051f24c09da286f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
"derive_builder",
|
||||
"rustversion",
|
||||
"time",
|
||||
"vergen-lib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vergen-gitcl"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3bbdc9746577cb4767f218d320ee0b623d415e8130332f8f562b910b61cc2c4e"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"derive_builder",
|
||||
"rustversion",
|
||||
"time",
|
||||
"vergen",
|
||||
"vergen-lib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vergen-lib"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e06bee42361e43b60f363bad49d63798d0f42fb1768091812270eca00c784720"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"derive_builder",
|
||||
"getset",
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2435,7 +2506,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
|
@ -2457,7 +2528,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
|
@ -2556,7 +2627,7 @@ checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2567,7 +2638,7 @@ checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2765,7 +2836,7 @@ dependencies = [
|
|||
"clap_complete_nushell",
|
||||
"regex",
|
||||
"serde",
|
||||
"vergen",
|
||||
"vergen-gitcl",
|
||||
"yazi-adapter",
|
||||
"yazi-config",
|
||||
"yazi-shared",
|
||||
|
|
@ -2785,7 +2856,7 @@ dependencies = [
|
|||
"serde_json",
|
||||
"tokio",
|
||||
"toml_edit",
|
||||
"vergen",
|
||||
"vergen-gitcl",
|
||||
"yazi-dds",
|
||||
"yazi-shared",
|
||||
]
|
||||
|
|
@ -2796,7 +2867,7 @@ version = "0.2.5"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"arc-swap",
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"crossterm",
|
||||
"globset",
|
||||
"indexmap",
|
||||
|
|
@ -2812,7 +2883,7 @@ name = "yazi-core"
|
|||
version = "0.2.5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"crossterm",
|
||||
"dirs",
|
||||
"futures",
|
||||
|
|
@ -2852,7 +2923,7 @@ dependencies = [
|
|||
"tokio-stream",
|
||||
"tokio-util",
|
||||
"uzers",
|
||||
"vergen",
|
||||
"vergen-gitcl",
|
||||
"yazi-boot",
|
||||
"yazi-shared",
|
||||
]
|
||||
|
|
@ -2962,7 +3033,7 @@ name = "yazi-shared"
|
|||
version = "0.2.5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"crossterm",
|
||||
"dirs",
|
||||
"futures",
|
||||
|
|
@ -2979,22 +3050,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.34"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.34"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.67",
|
||||
"syn 2.0.68",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -15,12 +15,12 @@ yazi-config = { path = "../yazi-config", version = "0.2.5" }
|
|||
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
||||
|
||||
# External dependencies
|
||||
clap = { version = "4.5.7", features = [ "derive" ] }
|
||||
serde = { version = "1.0.203", features = [ "derive" ] }
|
||||
clap = { version = "4.5.9", features = [ "derive" ] }
|
||||
serde = { version = "1.0.204", features = [ "derive" ] }
|
||||
|
||||
[build-dependencies]
|
||||
clap = { version = "4.5.7", features = [ "derive" ] }
|
||||
clap_complete = "4.5.6"
|
||||
clap_complete_nushell = "4.5.2"
|
||||
clap = { version = "4.5.9", features = [ "derive" ] }
|
||||
clap_complete = "4.5.8"
|
||||
clap_complete_fig = "4.5.1"
|
||||
vergen = { version = "8.3.1", features = [ "build", "git", "gitcl" ] }
|
||||
clap_complete_nushell = "4.5.2"
|
||||
vergen-gitcl = { version = "1.0.0", features = [ "build" ] }
|
||||
|
|
|
|||
|
|
@ -5,10 +5,13 @@ use std::{env, error::Error};
|
|||
|
||||
use clap::CommandFactory;
|
||||
use clap_complete::{generate_to, Shell};
|
||||
use vergen::EmitBuilder;
|
||||
use vergen_gitcl::{BuildBuilder, Emitter, GitclBuilder};
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
EmitBuilder::builder().build_date().git_sha(true).emit()?;
|
||||
Emitter::default()
|
||||
.add_instructions(&BuildBuilder::default().build_date(true).build()?)?
|
||||
.add_instructions(&GitclBuilder::default().commit_date(true).sha(true).build()?)?
|
||||
.emit()?;
|
||||
|
||||
if env::var_os("YAZI_GEN_COMPLETIONS").is_none() {
|
||||
return Ok(());
|
||||
|
|
|
|||
|
|
@ -14,21 +14,21 @@ yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
|||
|
||||
# External dependencies
|
||||
anyhow = "1.0.86"
|
||||
clap = { version = "4.5.7", features = [ "derive" ] }
|
||||
clap = { version = "4.5.9", features = [ "derive" ] }
|
||||
crossterm = "0.27.0"
|
||||
md-5 = "0.10.6"
|
||||
serde_json = "1.0.117"
|
||||
serde_json = "1.0.120"
|
||||
tokio = { version = "1.38.0", features = [ "full" ] }
|
||||
toml_edit = "0.22.14"
|
||||
toml_edit = "0.22.15"
|
||||
|
||||
[build-dependencies]
|
||||
anyhow = "1.0.86"
|
||||
clap = { version = "4.5.7", features = [ "derive" ] }
|
||||
clap_complete = "4.5.6"
|
||||
clap = { version = "4.5.9", features = [ "derive" ] }
|
||||
clap_complete = "4.5.8"
|
||||
clap_complete_fig = "4.5.1"
|
||||
clap_complete_nushell = "4.5.2"
|
||||
serde_json = "1.0.117"
|
||||
vergen = { version = "8.3.1", features = [ "build", "git", "gitcl" ] }
|
||||
serde_json = "1.0.120"
|
||||
vergen-gitcl = { version = "1.0.0", features = [ "build" ] }
|
||||
|
||||
[[bin]]
|
||||
name = "ya"
|
||||
|
|
|
|||
|
|
@ -5,10 +5,13 @@ use std::{env, error::Error};
|
|||
|
||||
use clap::CommandFactory;
|
||||
use clap_complete::{generate_to, Shell};
|
||||
use vergen::EmitBuilder;
|
||||
use vergen_gitcl::{BuildBuilder, Emitter, GitclBuilder};
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
EmitBuilder::builder().build_date().git_sha(true).emit()?;
|
||||
Emitter::default()
|
||||
.add_instructions(&BuildBuilder::default().build_date(true).build()?)?
|
||||
.add_instructions(&GitclBuilder::default().commit_date(true).sha(true).build()?)?
|
||||
.emit()?;
|
||||
|
||||
if env::var_os("YAZI_GEN_COMPLETIONS").is_none() {
|
||||
return Ok(());
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
|||
# External dependencies
|
||||
anyhow = "1.0.86"
|
||||
arc-swap = "1.7.1"
|
||||
bitflags = "2.5.0"
|
||||
bitflags = "2.6.0"
|
||||
crossterm = "0.27.0"
|
||||
globset = "0.4.14"
|
||||
indexmap = "2.2.6"
|
||||
ratatui = "0.27.0"
|
||||
serde = { version = "1.0.203", features = [ "derive" ] }
|
||||
serde = { version = "1.0.204", features = [ "derive" ] }
|
||||
toml = { version = "0.8.14", features = [ "preserve_order" ] }
|
||||
validator = { version = "0.18.1", features = [ "derive" ] }
|
||||
|
|
|
|||
|
|
@ -773,9 +773,9 @@ conds = [
|
|||
{ if = "sticky", text = "" },
|
||||
|
||||
# Fallback
|
||||
{ if = "dir", text = "" },
|
||||
{ if = "exec", text = "" },
|
||||
{ if = "!dir", text = "" },
|
||||
{ if = "dir", text = "" },
|
||||
{ if = "exec", text = "" },
|
||||
{ if = "!dir", text = "" },
|
||||
]
|
||||
|
||||
# : }}}
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ previewers = [
|
|||
]
|
||||
|
||||
[input]
|
||||
cursor_blink = true
|
||||
cursor_blink = false
|
||||
|
||||
# cd
|
||||
cd_title = "Change directory:"
|
||||
|
|
|
|||
|
|
@ -1,12 +1,7 @@
|
|||
use ratatui::layout::Rect;
|
||||
|
||||
#[derive(Default)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct Layout {
|
||||
pub header: Rect,
|
||||
|
||||
pub parent: Rect,
|
||||
pub current: Rect,
|
||||
pub preview: Rect,
|
||||
|
||||
pub status: Rect,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,13 +61,20 @@ pub fn init() -> anyhow::Result<()> {
|
|||
// TODO: Remove in v0.3.2
|
||||
for c in &KEYMAP.manager {
|
||||
for r in &c.run {
|
||||
if r.name == "shell" && !r.bool("confirm") && !r.bool("interactive") {
|
||||
if r.name != "shell" {
|
||||
continue;
|
||||
}
|
||||
if !r.bool("confirm") && !r.bool("interactive") {
|
||||
eprintln!(
|
||||
r#"WARNING: In Yazi v0.3, the behavior of the interactive `shell` (i.e., shell templates) must be explicitly specified with `--interactive`.
|
||||
|
||||
Please replace e.g. `shell` with `shell --interactive`, `shell "my-template"` with `shell "my-template" --interactive`, in your keymap.toml"#
|
||||
);
|
||||
return Ok(());
|
||||
} else if r.bool("confirm") && r.bool("interactive") {
|
||||
eprintln!(
|
||||
"The `shell` command cannot specify both `--confirm` and `--interactive` at the same time.",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
|||
|
||||
# External dependencies
|
||||
anyhow = "1.0.86"
|
||||
bitflags = "2.5.0"
|
||||
bitflags = "2.6.0"
|
||||
crossterm = "0.27.0"
|
||||
dirs = "5.0.1"
|
||||
futures = "0.3.30"
|
||||
|
|
@ -29,7 +29,7 @@ parking_lot = "0.12.3"
|
|||
ratatui = "0.27.0"
|
||||
regex = "1.10.5"
|
||||
scopeguard = "1.2.0"
|
||||
serde = "1.0.203"
|
||||
serde = "1.0.204"
|
||||
shell-words = "1.1.0"
|
||||
tokio = { version = "1.38.0", features = [ "full" ] }
|
||||
tokio-stream = "0.1.15"
|
||||
|
|
|
|||
|
|
@ -20,14 +20,14 @@ yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
|||
anyhow = "1.0.86"
|
||||
mlua = { version = "0.9.9", features = [ "lua54" ] }
|
||||
parking_lot = "0.12.3"
|
||||
serde = { version = "1.0.203", features = [ "derive" ] }
|
||||
serde_json = "1.0.117"
|
||||
serde = { version = "1.0.204", features = [ "derive" ] }
|
||||
serde_json = "1.0.120"
|
||||
tokio = { version = "1.38.0", features = [ "full" ] }
|
||||
tokio-stream = "0.1.15"
|
||||
tokio-util = "0.7.11"
|
||||
|
||||
[build-dependencies]
|
||||
vergen = { version = "8.3.1", features = [ "build", "git", "gitcl" ] }
|
||||
vergen-gitcl = { version = "1.0.0", features = [ "build" ] }
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
uzers = "0.12.0"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
use std::error::Error;
|
||||
|
||||
use vergen::EmitBuilder;
|
||||
use vergen_gitcl::{Emitter, GitclBuilder};
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
EmitBuilder::builder().git_sha(true).emit()?;
|
||||
Emitter::default()
|
||||
.add_instructions(&GitclBuilder::default().commit_date(true).sha(true).build()?)?
|
||||
.emit()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,5 +52,5 @@ name = "yazi"
|
|||
path = "src/main.rs"
|
||||
|
||||
[package.metadata.binstall]
|
||||
pkg-url = "{ repo }/releases/download/v{ version }/yazi-{ target }{ archive-suffix }"
|
||||
bin-dir = "yazi-{ target }/{ bin }{ binary-ext }"
|
||||
pkg-url = "{repo}/releases/download/v{version}/yazi-{target}{archive-suffix}"
|
||||
bin-dir = "yazi-{target}/{bin}{binary-ext}"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
use crossterm::event::{MouseEvent, MouseEventKind};
|
||||
use mlua::Table;
|
||||
use ratatui::layout::{Position, Rect};
|
||||
use mlua::{Table, TableExt};
|
||||
use tracing::error;
|
||||
use yazi_config::{LAYOUT, MANAGER};
|
||||
use yazi_config::MANAGER;
|
||||
use yazi_plugin::{bindings::Cast, LUA};
|
||||
|
||||
use crate::{app::App, components, lives::Lives};
|
||||
use crate::{app::App, lives::Lives};
|
||||
|
||||
pub struct Opt {
|
||||
event: MouseEvent,
|
||||
|
|
@ -19,47 +18,36 @@ impl App {
|
|||
pub(crate) fn mouse(&mut self, opt: impl Into<Opt>) {
|
||||
let event = (opt.into() as Opt).event;
|
||||
|
||||
let layout = LAYOUT.load();
|
||||
let position = Position { x: event.column, y: event.row };
|
||||
let Some(size) = self.term.as_ref().and_then(|t| t.size().ok()) else { return };
|
||||
let Ok(evt) = yazi_plugin::bindings::MouseEvent::cast(&LUA, event) else { return };
|
||||
|
||||
if matches!(event.kind, MouseEventKind::Moved | MouseEventKind::Drag(_)) {
|
||||
self.mouse_do(crate::Root::mouse, event, None);
|
||||
return;
|
||||
}
|
||||
let res = Lives::scope(&self.cx, move |_| {
|
||||
let area = yazi_plugin::elements::Rect::cast(&LUA, size)?;
|
||||
let root = LUA.globals().raw_get::<_, Table>("Root")?.call_method::<_, Table>("new", area)?;
|
||||
|
||||
if layout.current.contains(position) {
|
||||
self.mouse_do(components::Current::mouse, event, Some(layout.current));
|
||||
} else if layout.preview.contains(position) {
|
||||
self.mouse_do(components::Preview::mouse, event, Some(layout.preview));
|
||||
} else if layout.parent.contains(position) {
|
||||
self.mouse_do(components::Parent::mouse, event, Some(layout.parent));
|
||||
} else if layout.header.contains(position) {
|
||||
self.mouse_do(components::Header::mouse, event, Some(layout.header));
|
||||
} else if layout.status.contains(position) {
|
||||
self.mouse_do(components::Status::mouse, event, Some(layout.status));
|
||||
}
|
||||
}
|
||||
|
||||
fn mouse_do(
|
||||
&self,
|
||||
f: impl FnOnce(MouseEvent) -> mlua::Result<()>,
|
||||
mut event: MouseEvent,
|
||||
rect: Option<Rect>,
|
||||
) {
|
||||
if matches!(event.kind, MouseEventKind::Down(_) if MANAGER.mouse_events.draggable()) {
|
||||
let evt = yazi_plugin::bindings::MouseEvent::cast(&LUA, event);
|
||||
if let (Ok(evt), Ok(root)) = (evt, LUA.globals().raw_get::<_, Table>("Root")) {
|
||||
root.raw_set("drag_start", evt).ok();
|
||||
if matches!(event.kind, MouseEventKind::Down(_) if MANAGER.mouse_events.draggable()) {
|
||||
root.raw_set("_drag_start", evt.clone())?;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(rect) = rect {
|
||||
event.row -= rect.y;
|
||||
event.column -= rect.x;
|
||||
}
|
||||
match event.kind {
|
||||
MouseEventKind::Down(_) => root.call_method("click", (evt, false))?,
|
||||
MouseEventKind::Up(_) => root.call_method("click", (evt, true))?,
|
||||
|
||||
if let Err(e) = Lives::scope(&self.cx, move |_| f(event)) {
|
||||
error!("{:?}", e);
|
||||
MouseEventKind::ScrollDown => root.call_method("scroll", (evt, 1))?,
|
||||
MouseEventKind::ScrollUp => root.call_method("scroll", (evt, -1))?,
|
||||
|
||||
MouseEventKind::ScrollRight => root.call_method("touch", (evt, 1))?,
|
||||
MouseEventKind::ScrollLeft => root.call_method("touch", (evt, -1))?,
|
||||
|
||||
MouseEventKind::Moved => root.call_method("move", evt)?,
|
||||
MouseEventKind::Drag(_) => root.call_method("drag", evt)?,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
if let Err(e) = res {
|
||||
error!("{e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
use crossterm::event::MouseEventKind;
|
||||
use mlua::{Table, TableExt};
|
||||
use yazi_plugin::{bindings::{Cast, MouseEvent}, LUA};
|
||||
|
||||
pub(crate) struct Current;
|
||||
|
||||
impl Current {
|
||||
pub(crate) fn mouse(event: crossterm::event::MouseEvent) -> mlua::Result<()> {
|
||||
let evt = MouseEvent::cast(&LUA, event)?;
|
||||
let comp: Table = LUA.globals().raw_get("Current")?;
|
||||
|
||||
match event.kind {
|
||||
MouseEventKind::Down(_) => comp.call_method("click", (evt, false))?,
|
||||
MouseEventKind::Up(_) => comp.call_method("click", (evt, true))?,
|
||||
MouseEventKind::ScrollDown => comp.call_method("scroll", (evt, 1))?,
|
||||
MouseEventKind::ScrollUp => comp.call_method("scroll", (evt, -1))?,
|
||||
MouseEventKind::ScrollRight => comp.call_method("touch", (evt, 1))?,
|
||||
MouseEventKind::ScrollLeft => comp.call_method("touch", (evt, -1))?,
|
||||
_ => (),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
use crossterm::event::MouseEventKind;
|
||||
use mlua::{Table, TableExt};
|
||||
use ratatui::{buffer::Buffer, widgets::Widget};
|
||||
use tracing::error;
|
||||
use yazi_plugin::{bindings::{Cast, MouseEvent}, elements::{render_widgets, Rect}, LUA};
|
||||
|
||||
pub(crate) struct Header;
|
||||
|
||||
impl Widget for Header {
|
||||
fn render(self, area: ratatui::layout::Rect, buf: &mut Buffer) {
|
||||
let mut f = || {
|
||||
let area = Rect::cast(&LUA, area)?;
|
||||
let comp: Table = LUA.globals().raw_get("Header")?;
|
||||
render_widgets(comp.call_method("render", area)?, buf);
|
||||
Ok::<_, anyhow::Error>(())
|
||||
};
|
||||
if let Err(e) = f() {
|
||||
error!("{:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Header {
|
||||
pub(crate) fn mouse(event: crossterm::event::MouseEvent) -> mlua::Result<()> {
|
||||
let evt = MouseEvent::cast(&LUA, event)?;
|
||||
let comp: Table = LUA.globals().raw_get("Header")?;
|
||||
|
||||
match event.kind {
|
||||
MouseEventKind::Down(_) => comp.call_method("click", (evt, false))?,
|
||||
MouseEventKind::Up(_) => comp.call_method("click", (evt, true))?,
|
||||
MouseEventKind::ScrollDown => comp.call_method("scroll", (evt, 1))?,
|
||||
MouseEventKind::ScrollUp => comp.call_method("scroll", (evt, -1))?,
|
||||
MouseEventKind::ScrollRight => comp.call_method("touch", (evt, 1))?,
|
||||
MouseEventKind::ScrollLeft => comp.call_method("touch", (evt, -1))?,
|
||||
_ => (),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
use mlua::{Table, TableExt};
|
||||
use ratatui::{buffer::Buffer, widgets::Widget};
|
||||
use tracing::error;
|
||||
use yazi_plugin::{bindings::Cast, elements::{render_widgets, Rect}, LUA};
|
||||
|
||||
pub(crate) struct Manager;
|
||||
|
||||
impl Widget for Manager {
|
||||
fn render(self, area: ratatui::layout::Rect, buf: &mut Buffer) {
|
||||
let mut f = || {
|
||||
let area = Rect::cast(&LUA, area)?;
|
||||
let comp: Table = LUA.globals().raw_get("Manager")?;
|
||||
render_widgets(comp.call_method("render", area)?, buf);
|
||||
Ok::<_, anyhow::Error>(())
|
||||
};
|
||||
if let Err(e) = f() {
|
||||
error!("{:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +1,7 @@
|
|||
#![allow(clippy::module_inception)]
|
||||
|
||||
mod current;
|
||||
mod header;
|
||||
mod manager;
|
||||
mod parent;
|
||||
mod preview;
|
||||
mod progress;
|
||||
mod status;
|
||||
|
||||
pub(super) use current::*;
|
||||
pub(super) use header::*;
|
||||
pub(super) use manager::*;
|
||||
pub(super) use parent::*;
|
||||
pub(super) use preview::*;
|
||||
pub(super) use progress::*;
|
||||
pub(super) use status::*;
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
use crossterm::event::MouseEventKind;
|
||||
use mlua::{Table, TableExt};
|
||||
use yazi_plugin::{bindings::{Cast, MouseEvent}, LUA};
|
||||
|
||||
pub(crate) struct Parent;
|
||||
|
||||
impl Parent {
|
||||
pub(crate) fn mouse(event: crossterm::event::MouseEvent) -> mlua::Result<()> {
|
||||
let evt = MouseEvent::cast(&LUA, event)?;
|
||||
let comp: Table = LUA.globals().raw_get("Parent")?;
|
||||
|
||||
match event.kind {
|
||||
MouseEventKind::Down(_) => comp.call_method("click", (evt, false))?,
|
||||
MouseEventKind::Up(_) => comp.call_method("click", (evt, true))?,
|
||||
MouseEventKind::ScrollDown => comp.call_method("scroll", (evt, 1))?,
|
||||
MouseEventKind::ScrollUp => comp.call_method("scroll", (evt, -1))?,
|
||||
MouseEventKind::ScrollRight => comp.call_method("touch", (evt, 1))?,
|
||||
MouseEventKind::ScrollLeft => comp.call_method("touch", (evt, -1))?,
|
||||
_ => (),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,4 @@
|
|||
use crossterm::event::MouseEventKind;
|
||||
use mlua::{Table, TableExt};
|
||||
use ratatui::{buffer::Buffer, widgets::Widget};
|
||||
use yazi_plugin::{bindings::{Cast, MouseEvent}, LUA};
|
||||
|
||||
use crate::Ctx;
|
||||
|
||||
|
|
@ -12,22 +9,6 @@ pub(crate) struct Preview<'a> {
|
|||
impl<'a> Preview<'a> {
|
||||
#[inline]
|
||||
pub(crate) fn new(cx: &'a Ctx) -> Self { Self { cx } }
|
||||
|
||||
pub(crate) fn mouse(event: crossterm::event::MouseEvent) -> mlua::Result<()> {
|
||||
let evt = MouseEvent::cast(&LUA, event)?;
|
||||
let comp: Table = LUA.globals().raw_get("Preview")?;
|
||||
|
||||
match event.kind {
|
||||
MouseEventKind::Down(_) => comp.call_method("click", (evt, false))?,
|
||||
MouseEventKind::Up(_) => comp.call_method("click", (evt, true))?,
|
||||
MouseEventKind::ScrollDown => comp.call_method("scroll", (evt, 1))?,
|
||||
MouseEventKind::ScrollUp => comp.call_method("scroll", (evt, -1))?,
|
||||
MouseEventKind::ScrollRight => comp.call_method("touch", (evt, 1))?,
|
||||
MouseEventKind::ScrollLeft => comp.call_method("touch", (evt, -1))?,
|
||||
_ => (),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Preview<'_> {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ impl Progress {
|
|||
let mut f = || {
|
||||
let comp: Table = LUA.globals().raw_get("Progress")?;
|
||||
for widget in comp.call_method::<_, Vec<AnyUserData>>("partial_render", ())? {
|
||||
let Some(w) = cast_to_renderable(widget) else { continue };
|
||||
let Some(w) = cast_to_renderable(&widget) else { continue };
|
||||
|
||||
let area = w.area();
|
||||
w.render(buf);
|
||||
|
|
@ -34,7 +34,7 @@ impl Progress {
|
|||
};
|
||||
|
||||
if let Err(e) = f() {
|
||||
error!("{:?}", e);
|
||||
error!("{e}");
|
||||
}
|
||||
patches
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
use crossterm::event::MouseEventKind;
|
||||
use mlua::{Table, TableExt};
|
||||
use ratatui::widgets::Widget;
|
||||
use tracing::error;
|
||||
use yazi_plugin::{bindings::{Cast, MouseEvent}, elements::{render_widgets, Rect}, LUA};
|
||||
|
||||
pub(crate) struct Status;
|
||||
|
||||
impl Widget for Status {
|
||||
fn render(self, area: ratatui::layout::Rect, buf: &mut ratatui::buffer::Buffer) {
|
||||
let mut f = || {
|
||||
let area = Rect::cast(&LUA, area)?;
|
||||
let comp: Table = LUA.globals().raw_get("Status")?;
|
||||
render_widgets(comp.call_method("render", area)?, buf);
|
||||
Ok::<_, anyhow::Error>(())
|
||||
};
|
||||
if let Err(e) = f() {
|
||||
error!("{:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Status {
|
||||
pub(crate) fn mouse(event: crossterm::event::MouseEvent) -> mlua::Result<()> {
|
||||
let evt = MouseEvent::cast(&LUA, event)?;
|
||||
let comp: Table = LUA.globals().raw_get("Status")?;
|
||||
|
||||
match event.kind {
|
||||
MouseEventKind::Down(_) => comp.call_method("click", (evt, false))?,
|
||||
MouseEventKind::Up(_) => comp.call_method("click", (evt, true))?,
|
||||
MouseEventKind::ScrollDown => comp.call_method("scroll", (evt, 1))?,
|
||||
MouseEventKind::ScrollUp => comp.call_method("scroll", (evt, -1))?,
|
||||
MouseEventKind::ScrollRight => comp.call_method("touch", (evt, 1))?,
|
||||
MouseEventKind::ScrollLeft => comp.call_method("touch", (evt, -1))?,
|
||||
_ => (),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,9 @@
|
|||
use std::{mem, sync::Arc};
|
||||
use std::mem;
|
||||
|
||||
use mlua::{Scope, Table};
|
||||
use mlua::Scope;
|
||||
use scopeguard::defer;
|
||||
use tracing::error;
|
||||
use yazi_config::LAYOUT;
|
||||
use yazi_plugin::{elements::RectRef, LUA};
|
||||
use yazi_plugin::LUA;
|
||||
use yazi_shared::RoCell;
|
||||
|
||||
use crate::Ctx;
|
||||
|
|
@ -52,17 +51,7 @@ impl Lives {
|
|||
])?,
|
||||
)?;
|
||||
|
||||
let ret = f(scope)?;
|
||||
|
||||
LAYOUT.store(Arc::new(yazi_config::Layout {
|
||||
header: *globals.raw_get::<_, Table>("Header")?.raw_get::<_, RectRef>("area")?,
|
||||
parent: *globals.raw_get::<_, Table>("Parent")?.raw_get::<_, RectRef>("area")?,
|
||||
current: *globals.raw_get::<_, Table>("Current")?.raw_get::<_, RectRef>("area")?,
|
||||
preview: *globals.raw_get::<_, Table>("Preview")?.raw_get::<_, RectRef>("area")?,
|
||||
status: *globals.raw_get::<_, Table>("Status")?.raw_get::<_, RectRef>("area")?,
|
||||
}));
|
||||
|
||||
Ok(ret)
|
||||
f(scope)
|
||||
});
|
||||
|
||||
if let Err(ref e) = result {
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ async fn main() -> anyhow::Result<()> {
|
|||
|
||||
yazi_dds::init();
|
||||
|
||||
yazi_plugin::init();
|
||||
yazi_plugin::init()?;
|
||||
|
||||
yazi_core::init();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crossterm::event::MouseEventKind;
|
||||
use mlua::{Table, TableExt};
|
||||
use ratatui::{buffer::Buffer, layout::{Constraint, Layout, Rect}, widgets::Widget};
|
||||
use yazi_plugin::{bindings::{Cast, MouseEvent}, LUA};
|
||||
use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget};
|
||||
use tracing::error;
|
||||
use yazi_plugin::{bindings::Cast, elements::render_widgets, LUA};
|
||||
|
||||
use super::{completion, input, select, tasks, which};
|
||||
use crate::{components, help, Ctx};
|
||||
|
|
@ -16,13 +16,17 @@ impl<'a> Root<'a> {
|
|||
|
||||
impl<'a> Widget for Root<'a> {
|
||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||
let chunks =
|
||||
Layout::vertical([Constraint::Length(1), Constraint::Fill(1), Constraint::Length(1)])
|
||||
.split(area);
|
||||
let mut f = || {
|
||||
let area = yazi_plugin::elements::Rect::cast(&LUA, area)?;
|
||||
let root = LUA.globals().raw_get::<_, Table>("Root")?.call_method::<_, Table>("new", area)?;
|
||||
|
||||
render_widgets(root.call_method("render", ())?, buf);
|
||||
Ok::<_, mlua::Error>(())
|
||||
};
|
||||
if let Err(e) = f() {
|
||||
error!("Failed to render the `Root` component:\n{e}");
|
||||
}
|
||||
|
||||
components::Header.render(chunks[0], buf);
|
||||
components::Manager.render(chunks[1], buf);
|
||||
components::Status.render(chunks[2], buf);
|
||||
components::Preview::new(self.cx).render(area, buf);
|
||||
|
||||
if self.cx.tasks.visible {
|
||||
|
|
@ -50,17 +54,3 @@ impl<'a> Widget for Root<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Root<'_> {
|
||||
pub(super) fn mouse(event: crossterm::event::MouseEvent) -> mlua::Result<()> {
|
||||
let evt = MouseEvent::cast(&LUA, event)?;
|
||||
let comp: Table = LUA.globals().raw_get("Root")?;
|
||||
|
||||
match event.kind {
|
||||
MouseEventKind::Moved => comp.call_method("move", evt)?,
|
||||
MouseEventKind::Drag(_) => comp.call_method("drag", evt)?,
|
||||
_ => (),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,4 +46,4 @@ tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_lev
|
|||
uzers = "0.12.0"
|
||||
|
||||
[target."cfg(windows)".dependencies]
|
||||
clipboard-win = "5.3.1"
|
||||
clipboard-win = "5.4.0"
|
||||
|
|
|
|||
40
yazi-plugin/preset/compat.lua
Normal file
40
yazi-plugin/preset/compat.lua
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
-- TODO: remove this after 0.3.0 release
|
||||
|
||||
Manager = {}
|
||||
Folder = {}
|
||||
File = {}
|
||||
|
||||
local b = false
|
||||
function __yazi_check_and_warn_deprecated_api()
|
||||
if b then
|
||||
return
|
||||
end
|
||||
|
||||
local warn = function(name)
|
||||
ya.notify {
|
||||
title = "Deprecated API",
|
||||
content = string.format(
|
||||
[[The `%s` global variable has been removed in Yazi v0.3, please remove it from your `init.lua`.
|
||||
|
||||
See https://github.com/sxyazi/yazi/pull/1257 for details.]],
|
||||
name
|
||||
),
|
||||
timeout = 20,
|
||||
level = "warn",
|
||||
}
|
||||
end
|
||||
|
||||
b = true
|
||||
for _ in pairs(Manager) do
|
||||
warn("Manager")
|
||||
break
|
||||
end
|
||||
for _ in pairs(Folder) do
|
||||
warn("Folder")
|
||||
break
|
||||
end
|
||||
for _ in pairs(File) do
|
||||
warn("File")
|
||||
break
|
||||
end
|
||||
end
|
||||
|
|
@ -1,59 +1,58 @@
|
|||
Current = {
|
||||
area = ui.Rect.default,
|
||||
_id = "current",
|
||||
}
|
||||
|
||||
function Current:empty(area)
|
||||
local folder = Folder:by_kind(Folder.CURRENT)
|
||||
function Current:new(area, tab)
|
||||
return setmetatable({
|
||||
_area = area,
|
||||
_tab = tab,
|
||||
_folder = tab.current,
|
||||
}, { __index = self })
|
||||
end
|
||||
|
||||
function Current:empty()
|
||||
local line
|
||||
if folder.files.filter then
|
||||
if self._folder.files.filter then
|
||||
line = ui.Line("No filter results")
|
||||
else
|
||||
line = ui.Line(folder.stage == "loading" and "Loading..." or "No items")
|
||||
line = ui.Line(self._folder.stage == "loading" and "Loading..." or "No items")
|
||||
end
|
||||
|
||||
return {
|
||||
ui.Paragraph(area, { line }):align(ui.Paragraph.CENTER),
|
||||
ui.Paragraph(self._area, { line }):align(ui.Paragraph.CENTER),
|
||||
}
|
||||
end
|
||||
|
||||
function Current:render(area)
|
||||
self.area = area
|
||||
|
||||
local files = Folder:by_kind(Folder.CURRENT).window
|
||||
function Current:render()
|
||||
local files = self._folder.window
|
||||
if #files == 0 then
|
||||
return self:empty(area)
|
||||
return self:empty()
|
||||
end
|
||||
|
||||
local items, markers = {}, {}
|
||||
for i, f in ipairs(files) do
|
||||
items[#items + 1] = ui.ListItem(ui.Line(File:full(f))):style(File:style(f))
|
||||
|
||||
-- Yanked/marked/selected files
|
||||
local marker = File:marker(f)
|
||||
if marker ~= 0 then
|
||||
markers[#markers + 1] = { i, marker }
|
||||
end
|
||||
local items = {}
|
||||
for _, f in ipairs(files) do
|
||||
items[#items + 1] = ui.ListItem(Entity:render(f)):style(Entity:style(f))
|
||||
end
|
||||
|
||||
return ya.flat {
|
||||
ui.List(area, items),
|
||||
Folder:linemode(area, files),
|
||||
Folder:markers(area, markers),
|
||||
return {
|
||||
ui.List(self._area, items),
|
||||
ui.Paragraph(self._area, Linemode:render(files)):align(ui.Paragraph.RIGHT),
|
||||
}
|
||||
end
|
||||
|
||||
-- Mouse events
|
||||
function Current:click(event, up)
|
||||
if up or event.is_middle then
|
||||
return
|
||||
end
|
||||
|
||||
local f = Folder:by_kind(Folder.CURRENT)
|
||||
if event.y > #f.window or not f.hovered then
|
||||
local f = self._folder
|
||||
local y = event.y - self._area.y + 1
|
||||
if y > #f.window or not f.hovered then
|
||||
return
|
||||
end
|
||||
|
||||
ya.manager_emit("arrow", { event.y + f.offset - f.hovered.idx })
|
||||
ya.manager_emit("arrow", { y + f.offset - f.hovered.idx })
|
||||
if event.is_right then
|
||||
ya.manager_emit("open", {})
|
||||
end
|
||||
|
|
|
|||
109
yazi-plugin/preset/components/entity.lua
Normal file
109
yazi-plugin/preset/components/entity.lua
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
Entity = {
|
||||
_inc = 1000,
|
||||
}
|
||||
|
||||
function Entity:style(file)
|
||||
local style = file:style()
|
||||
if not file:is_hovered() then
|
||||
return style
|
||||
elseif file:in_preview() then
|
||||
return style and style:patch(THEME.manager.preview_hovered) or THEME.manager.preview_hovered
|
||||
else
|
||||
return style and style:patch(THEME.manager.hovered) or THEME.manager.hovered
|
||||
end
|
||||
end
|
||||
|
||||
function Entity:icon(file)
|
||||
local icon = file:icon()
|
||||
if not icon then
|
||||
return ui.Line("")
|
||||
elseif file:is_hovered() then
|
||||
return ui.Line(" " .. icon.text .. " ")
|
||||
else
|
||||
return ui.Line(" " .. icon.text .. " "):style(icon.style)
|
||||
end
|
||||
end
|
||||
|
||||
function Entity:prefix(file)
|
||||
local prefix = file:prefix() or ""
|
||||
return ui.Line(prefix ~= "" and prefix .. "/" or "")
|
||||
end
|
||||
|
||||
function Entity:highlights(file)
|
||||
local name = file.name:gsub("\r", "?", 1)
|
||||
local highlights = file:highlights()
|
||||
if not highlights or #highlights == 0 then
|
||||
return ui.Line(name)
|
||||
end
|
||||
|
||||
local spans, last = {}, 0
|
||||
for _, h in ipairs(highlights) do
|
||||
if h[1] > last then
|
||||
spans[#spans + 1] = ui.Span(name:sub(last + 1, h[1]))
|
||||
end
|
||||
spans[#spans + 1] = ui.Span(name:sub(h[1] + 1, h[2])):style(THEME.manager.find_keyword)
|
||||
last = h[2]
|
||||
end
|
||||
if last < #name then
|
||||
spans[#spans + 1] = ui.Span(name:sub(last + 1))
|
||||
end
|
||||
return ui.Line(spans)
|
||||
end
|
||||
|
||||
function Entity:found(file)
|
||||
if not file:is_hovered() then
|
||||
return ui.Line {}
|
||||
end
|
||||
|
||||
local found = file:found()
|
||||
if not found then
|
||||
return ui.Line {}
|
||||
end
|
||||
|
||||
return ui.Line {
|
||||
ui.Span(" "),
|
||||
ui.Span(string.format("[%d/%d]", found[1] + 1, found[2])):style(THEME.manager.find_position),
|
||||
}
|
||||
end
|
||||
|
||||
function Entity:symlink(file)
|
||||
if not MANAGER.show_symlink then
|
||||
return ui.Line {}
|
||||
end
|
||||
|
||||
local to = file.link_to
|
||||
return ui.Line(to and { ui.Span(" -> " .. tostring(to)):italic() } or {})
|
||||
end
|
||||
|
||||
function Entity:render(file)
|
||||
local lines = {}
|
||||
for _, child in ipairs(self._children) do
|
||||
lines[#lines + 1] = child[1](self, file)
|
||||
end
|
||||
return ui.Line(lines)
|
||||
end
|
||||
|
||||
-- Initialize children
|
||||
Entity._children = {
|
||||
{ Entity.icon, id = 1, order = 1000 },
|
||||
{ Entity.prefix, id = 2, order = 2000 },
|
||||
{ Entity.highlights, id = 3, order = 3000 },
|
||||
{ Entity.found, id = 4, order = 4000 },
|
||||
{ Entity.symlink, id = 5, order = 5000 },
|
||||
}
|
||||
|
||||
function Entity:children_add(fn, order)
|
||||
self._inc = self._inc + 1
|
||||
self._children[#self._children + 1] = { fn, id = self._inc, order = order }
|
||||
table.sort(self._children, function(a, b) return a.order < b.order end)
|
||||
return self._inc
|
||||
end
|
||||
|
||||
function Entity:children_remove(id)
|
||||
for i, child in ipairs(self._children) do
|
||||
if child.id == id then
|
||||
table.remove(self._children, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
File = {}
|
||||
|
||||
function File:icon(file)
|
||||
local icon = file:icon()
|
||||
if not icon then
|
||||
return {}
|
||||
elseif file:is_hovered() then
|
||||
return { ui.Span(" " .. icon.text .. " ") }
|
||||
else
|
||||
return { ui.Span(" " .. icon.text .. " "):style(icon.style) }
|
||||
end
|
||||
end
|
||||
|
||||
function File:prefix(file)
|
||||
local prefix = file:prefix() or ""
|
||||
return prefix == "" and {} or { ui.Span(prefix .. "/") }
|
||||
end
|
||||
|
||||
function File:highlights(file)
|
||||
local name = file.name:gsub("\r", "?", 1)
|
||||
local highlights = file:highlights()
|
||||
if not highlights or #highlights == 0 then
|
||||
return { ui.Span(name) }
|
||||
end
|
||||
|
||||
local spans, last = {}, 0
|
||||
for _, h in ipairs(highlights) do
|
||||
if h[1] > last then
|
||||
spans[#spans + 1] = ui.Span(name:sub(last + 1, h[1]))
|
||||
end
|
||||
spans[#spans + 1] = ui.Span(name:sub(h[1] + 1, h[2])):style(THEME.manager.find_keyword)
|
||||
last = h[2]
|
||||
end
|
||||
if last < #name then
|
||||
spans[#spans + 1] = ui.Span(name:sub(last + 1))
|
||||
end
|
||||
return spans
|
||||
end
|
||||
|
||||
function File:found(file)
|
||||
if not file:is_hovered() then
|
||||
return {}
|
||||
end
|
||||
|
||||
local found = file:found()
|
||||
if not found then
|
||||
return {}
|
||||
end
|
||||
|
||||
return {
|
||||
ui.Span(" "),
|
||||
ui.Span(string.format("[%d/%d]", found[1] + 1, found[2])):style(THEME.manager.find_position),
|
||||
}
|
||||
end
|
||||
|
||||
function File:symlink(file)
|
||||
if not MANAGER.show_symlink then
|
||||
return {}
|
||||
end
|
||||
|
||||
local to = file.link_to
|
||||
return to and { ui.Span(" -> " .. tostring(to)):italic() } or {}
|
||||
end
|
||||
|
||||
function File:full(file)
|
||||
return ya.flat {
|
||||
self:icon(file),
|
||||
self:prefix(file),
|
||||
self:highlights(file),
|
||||
self:found(file),
|
||||
self:symlink(file),
|
||||
}
|
||||
end
|
||||
|
||||
function File:style(file)
|
||||
local style = file:style()
|
||||
if not file:is_hovered() then
|
||||
return style
|
||||
elseif file:in_preview() then
|
||||
return style and style:patch(THEME.manager.preview_hovered) or THEME.manager.preview_hovered
|
||||
else
|
||||
return style and style:patch(THEME.manager.hovered) or THEME.manager.hovered
|
||||
end
|
||||
end
|
||||
|
||||
function File:marker(file)
|
||||
local yanked = file:is_yanked()
|
||||
if yanked ~= 0 then
|
||||
return yanked -- 1: copied, 2: cut
|
||||
end
|
||||
|
||||
local marked = file:is_marked()
|
||||
if marked == 1 then
|
||||
return 3 -- 3: marked
|
||||
elseif marked == 0 and file:is_selected() then
|
||||
return 4 -- 4: selected
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
Folder = {
|
||||
PARENT = 0,
|
||||
CURRENT = 1,
|
||||
PREVIEW = 2,
|
||||
}
|
||||
|
||||
function Folder:linemode(area, files)
|
||||
local mode = cx.active.conf.linemode
|
||||
if mode == "none" then
|
||||
return {}
|
||||
end
|
||||
|
||||
local lines = {}
|
||||
for _, f in ipairs(files) do
|
||||
local spans = { ui.Span(" ") }
|
||||
if mode == "size" then
|
||||
local size = f:size()
|
||||
spans[#spans + 1] = ui.Span(size and ya.readable_size(size) or "")
|
||||
elseif mode == "mtime" then
|
||||
local time = f.cha.modified
|
||||
spans[#spans + 1] = ui.Span(time and os.date("%y-%m-%d %H:%M", time // 1) or "")
|
||||
elseif mode == "permissions" then
|
||||
spans[#spans + 1] = ui.Span(f.cha:permissions() or "")
|
||||
elseif mode == "owner" then
|
||||
spans[#spans + 1] = ya.user_name and ui.Span(ya.user_name(f.cha.uid) .. ":" .. ya.group_name(f.cha.gid))
|
||||
or ui.Span("")
|
||||
end
|
||||
|
||||
spans[#spans + 1] = ui.Span(" ")
|
||||
lines[#lines + 1] = ui.Line(spans)
|
||||
end
|
||||
return ui.Paragraph(area, lines):align(ui.Paragraph.RIGHT)
|
||||
end
|
||||
|
||||
function Folder:markers(area, markers)
|
||||
if #markers == 0 or area.w * area.h == 0 then
|
||||
return {}
|
||||
end
|
||||
|
||||
local elements = {}
|
||||
local append = function(last)
|
||||
local y = math.min(area.y + last[1], area.y + area.h) - 1
|
||||
local bar = ui.Bar(
|
||||
ui.Rect {
|
||||
x = math.max(0, area.x - 1),
|
||||
y = y,
|
||||
w = 1,
|
||||
h = math.min(1 + last[2] - last[1], area.y + area.h - y),
|
||||
},
|
||||
ui.Bar.LEFT
|
||||
)
|
||||
|
||||
if last[3] == 1 then
|
||||
bar = bar:style(THEME.manager.marker_copied)
|
||||
elseif last[3] == 2 then
|
||||
bar = bar:style(THEME.manager.marker_cut)
|
||||
elseif last[3] == 3 then
|
||||
bar = bar:style(THEME.manager.marker_marked)
|
||||
elseif last[3] == 4 then
|
||||
bar = bar:style(THEME.manager.marker_selected)
|
||||
end
|
||||
elements[#elements + 1] = bar
|
||||
end
|
||||
|
||||
local last = { markers[1][1], markers[1][1], markers[1][2] } -- start, end, type
|
||||
for _, m in ipairs(markers) do
|
||||
if m[1] - last[2] > 1 or last[3] ~= m[2] then
|
||||
append(last)
|
||||
last = { m[1], m[1], m[2] }
|
||||
else
|
||||
last[2] = m[1]
|
||||
end
|
||||
end
|
||||
|
||||
append(last)
|
||||
return elements
|
||||
end
|
||||
|
||||
function Folder:by_kind(kind)
|
||||
if kind == self.PARENT then
|
||||
return cx.active.parent
|
||||
elseif kind == self.CURRENT then
|
||||
return cx.active.current
|
||||
elseif kind == self.PREVIEW then
|
||||
return cx.active.preview.folder
|
||||
end
|
||||
end
|
||||
|
||||
function Folder:window(kind)
|
||||
local folder = self:by_kind(kind)
|
||||
return folder and folder.window
|
||||
end
|
||||
|
|
@ -1,15 +1,22 @@
|
|||
Header = {
|
||||
area = ui.Rect.default,
|
||||
_id = "header",
|
||||
}
|
||||
|
||||
function Header:new(area, tab)
|
||||
return setmetatable({
|
||||
_area = area,
|
||||
_tab = tab,
|
||||
}, { __index = self })
|
||||
end
|
||||
|
||||
function Header:cwd(max)
|
||||
local s = ya.readable_path(tostring(cx.active.current.cwd)) .. self:flags()
|
||||
local s = ya.readable_path(tostring(self._tab.current.cwd)) .. self:flags()
|
||||
return ui.Span(ya.truncate(s, { max = max, rtl = true })):style(THEME.manager.cwd)
|
||||
end
|
||||
|
||||
function Header:flags()
|
||||
local cwd = cx.active.current.cwd
|
||||
local filter = cx.active.current.files.filter
|
||||
local cwd = self._tab.current.cwd
|
||||
local filter = self._tab.current.files.filter
|
||||
|
||||
local s = cwd.is_search and string.format(" (search: %s", cwd:frag()) or ""
|
||||
if not filter then
|
||||
|
|
@ -26,7 +33,7 @@ function Header:count()
|
|||
|
||||
local count, style
|
||||
if yanked == 0 then
|
||||
count = #cx.active.selected
|
||||
count = #self._tab.selected
|
||||
style = THEME.manager.count_selected
|
||||
elseif cx.yanked.is_cut then
|
||||
count = yanked
|
||||
|
|
@ -67,17 +74,16 @@ function Header:tabs()
|
|||
return ui.Line(spans)
|
||||
end
|
||||
|
||||
function Header:render(area)
|
||||
self.area = area
|
||||
|
||||
function Header:render()
|
||||
local right = ui.Line { self:count(), self:tabs() }
|
||||
local left = ui.Line { self:cwd(math.max(0, area.w - right:width())) }
|
||||
local left = ui.Line { self:cwd(math.max(0, self._area.w - right:width())) }
|
||||
return {
|
||||
ui.Paragraph(area, { left }),
|
||||
ui.Paragraph(area, { right }):align(ui.Paragraph.RIGHT),
|
||||
ui.Paragraph(self._area, { left }),
|
||||
ui.Paragraph(self._area, { right }):align(ui.Paragraph.RIGHT),
|
||||
}
|
||||
end
|
||||
|
||||
-- Mouse events
|
||||
function Header:click(event, up) end
|
||||
|
||||
function Header:scroll(event, step) end
|
||||
|
|
|
|||
77
yazi-plugin/preset/components/linemode.lua
Normal file
77
yazi-plugin/preset/components/linemode.lua
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
Linemode = {
|
||||
_inc = 1000,
|
||||
}
|
||||
|
||||
function Linemode:solo(file)
|
||||
local mode = cx.active.conf.linemode
|
||||
if mode == "none" or mode == "solo" then
|
||||
return ui.Line("")
|
||||
end
|
||||
|
||||
if not self[mode] then
|
||||
return ui.Line(" " .. mode .. " ")
|
||||
end
|
||||
|
||||
return ui.Line {
|
||||
ui.Span(" "),
|
||||
self[mode](self, file),
|
||||
ui.Span(" "),
|
||||
}
|
||||
end
|
||||
|
||||
function Linemode:size(file)
|
||||
local size = file:size()
|
||||
return ui.Line(size and ya.readable_size(size) or "")
|
||||
end
|
||||
|
||||
function Linemode:mtime(file)
|
||||
local time = file.cha.modified
|
||||
return ui.Line(time and os.date("%y-%m-%d %H:%M", time // 1) or "")
|
||||
end
|
||||
|
||||
function Linemode:permissions(file) return ui.Line(file.cha:permissions() or "") end
|
||||
|
||||
function Linemode:owner(file)
|
||||
if not ya.user_name then
|
||||
return ui.Line("")
|
||||
else
|
||||
return ui.Line(ya.user_name(file.cha.uid) .. ":" .. ya.group_name(file.cha.gid))
|
||||
end
|
||||
end
|
||||
|
||||
function Linemode:render(files)
|
||||
local lines = {}
|
||||
for _, f in ipairs(files) do
|
||||
lines[#lines + 1] = self:children_render(f)
|
||||
end
|
||||
return lines
|
||||
end
|
||||
|
||||
-- Initialize children
|
||||
Linemode._children = {
|
||||
{ Linemode.solo, id = 1, order = 1000 },
|
||||
}
|
||||
|
||||
function Linemode:children_add(fn, order)
|
||||
self._inc = self._inc + 1
|
||||
self._children[#self._children + 1] = { fn, id = self._inc, order = order }
|
||||
table.sort(self._children, function(a, b) return a.order < b.order end)
|
||||
return self._inc
|
||||
end
|
||||
|
||||
function Linemode:children_remove(id)
|
||||
for i, child in ipairs(self._children) do
|
||||
if child.id == id then
|
||||
table.remove(self._children, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Linemode:children_render(file)
|
||||
local lines = {}
|
||||
for _, child in ipairs(self._children) do
|
||||
lines[#lines + 1] = child[1](self, file)
|
||||
end
|
||||
return ui.Line(lines)
|
||||
end
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
Manager = {
|
||||
area = ui.Rect.default,
|
||||
}
|
||||
|
||||
function Manager:layout(area)
|
||||
self.area = area
|
||||
|
||||
return ui.Layout()
|
||||
:direction(ui.Layout.HORIZONTAL)
|
||||
:constraints({
|
||||
ui.Constraint.Ratio(MANAGER.ratio.parent, MANAGER.ratio.all),
|
||||
ui.Constraint.Ratio(MANAGER.ratio.current, MANAGER.ratio.all),
|
||||
ui.Constraint.Ratio(MANAGER.ratio.preview, MANAGER.ratio.all),
|
||||
})
|
||||
:split(area)
|
||||
end
|
||||
|
||||
function Manager:render(area)
|
||||
local chunks = self:layout(area)
|
||||
|
||||
return ya.flat {
|
||||
-- Borders
|
||||
ui.Bar(chunks[1], ui.Bar.RIGHT):symbol(THEME.manager.border_symbol):style(THEME.manager.border_style),
|
||||
ui.Bar(chunks[3], ui.Bar.LEFT):symbol(THEME.manager.border_symbol):style(THEME.manager.border_style),
|
||||
|
||||
-- Parent
|
||||
Parent:render(chunks[1]:padding(ui.Padding.x(1))),
|
||||
-- Current
|
||||
Current:render(chunks[2]),
|
||||
-- Preview
|
||||
Preview:render(chunks[3]:padding(ui.Padding.x(1))),
|
||||
}
|
||||
end
|
||||
71
yazi-plugin/preset/components/marker.lua
Normal file
71
yazi-plugin/preset/components/marker.lua
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
Marker = {
|
||||
_id = "marker",
|
||||
}
|
||||
|
||||
function Marker:new(area, folder)
|
||||
return setmetatable({
|
||||
_area = area,
|
||||
_folder = folder,
|
||||
}, { __index = self })
|
||||
end
|
||||
|
||||
function Marker:render()
|
||||
if self._area.w * self._area.h == 0 then
|
||||
return {}
|
||||
elseif not self._folder or #self._folder.window == 0 then
|
||||
return {}
|
||||
end
|
||||
|
||||
local elements = {}
|
||||
local append = function(last)
|
||||
if not last[3] then
|
||||
return
|
||||
end
|
||||
|
||||
local y = math.min(self._area.y + last[1], self._area.y + self._area.h) - 1
|
||||
local rect = ui.Rect {
|
||||
x = math.max(0, self._area.x - 1),
|
||||
y = y,
|
||||
w = 1,
|
||||
h = math.min(1 + last[2] - last[1], self._area.y + self._area.h - y),
|
||||
}
|
||||
elements[#elements + 1] = ui.Bar(rect, ui.Bar.LEFT):style(last[3])
|
||||
end
|
||||
|
||||
local last = { 0, 0, nil } -- start, end, style
|
||||
for i, f in ipairs(self._folder.window) do
|
||||
local style = self:style(f)
|
||||
if i - last[2] > 1 or last[3] ~= style then
|
||||
append(last)
|
||||
last = { i, i, style }
|
||||
else
|
||||
last[2] = i
|
||||
end
|
||||
end
|
||||
|
||||
append(last)
|
||||
return elements
|
||||
end
|
||||
|
||||
function Marker:style(file)
|
||||
local marked = file:is_marked()
|
||||
if marked == 1 then
|
||||
return THEME.manager.marker_marked
|
||||
elseif marked == 0 and file:is_selected() then
|
||||
return THEME.manager.marker_selected
|
||||
end
|
||||
|
||||
local yanked = file:is_yanked()
|
||||
if yanked == 1 then
|
||||
return THEME.manager.marker_copied
|
||||
elseif yanked == 2 then
|
||||
return THEME.manager.marker_cut
|
||||
end
|
||||
end
|
||||
|
||||
-- Mouse events
|
||||
function Marker:click(event, up) end
|
||||
|
||||
function Marker:scroll(event, step) end
|
||||
|
||||
function Marker:touch(event, step) end
|
||||
|
|
@ -1,40 +1,40 @@
|
|||
Parent = {
|
||||
area = ui.Rect.default,
|
||||
_id = "parent",
|
||||
}
|
||||
|
||||
function Parent:render(area)
|
||||
self.area = area
|
||||
function Parent:new(area, tab)
|
||||
return setmetatable({
|
||||
_area = area,
|
||||
_tab = tab,
|
||||
_folder = tab.parent,
|
||||
}, { __index = self })
|
||||
end
|
||||
|
||||
local folder = Folder:by_kind(Folder.PARENT)
|
||||
if not folder then
|
||||
function Parent:render()
|
||||
if not self._folder then
|
||||
return {}
|
||||
end
|
||||
|
||||
local items, markers = {}, {}
|
||||
for i, f in ipairs(folder.window) do
|
||||
items[#items + 1] = ui.ListItem(ui.Line(File:full(f))):style(File:style(f))
|
||||
|
||||
-- Yanked/marked/selected files
|
||||
local marker = File:marker(f)
|
||||
if marker ~= 0 then
|
||||
markers[#markers + 1] = { i, marker }
|
||||
end
|
||||
local items = {}
|
||||
for _, f in ipairs(self._folder.window) do
|
||||
items[#items + 1] = ui.ListItem(Entity:render(f)):style(Entity:style(f))
|
||||
end
|
||||
|
||||
return ya.flat {
|
||||
ui.List(area, items),
|
||||
Folder:markers(area, markers),
|
||||
return {
|
||||
ui.List(self._area, items),
|
||||
}
|
||||
end
|
||||
|
||||
-- Mouse events
|
||||
function Parent:click(event, up)
|
||||
if up or not event.is_left then
|
||||
return
|
||||
end
|
||||
|
||||
local window = Folder:window(Folder.PARENT) or {}
|
||||
if window[event.y] then
|
||||
ya.manager_emit("reveal", { window[event.y].url })
|
||||
local y = event.y - self._area.y + 1
|
||||
local window = self._folder and self._folder.window or {}
|
||||
if window[y] then
|
||||
ya.manager_emit("reveal", { window[y].url })
|
||||
else
|
||||
ya.manager_emit("leave", {})
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,20 +1,27 @@
|
|||
Preview = {
|
||||
area = ui.Rect.default,
|
||||
_id = "preview",
|
||||
}
|
||||
|
||||
function Preview:render(area)
|
||||
self.area = area
|
||||
return {}
|
||||
function Preview:new(area, tab)
|
||||
return setmetatable({
|
||||
_area = area,
|
||||
_tab = tab,
|
||||
_folder = tab.preview.folder,
|
||||
}, { __index = self })
|
||||
end
|
||||
|
||||
function Preview:render() return {} end
|
||||
|
||||
-- Mouse events
|
||||
function Preview:click(event, up)
|
||||
if up or not event.is_left then
|
||||
return
|
||||
end
|
||||
|
||||
local window = Folder:window(Folder.PREVIEW) or {}
|
||||
if window[event.y] then
|
||||
ya.manager_emit("reveal", { window[event.y].url })
|
||||
local y = event.y - self._area.y + 1
|
||||
local window = self._folder and self._folder.window or {}
|
||||
if window[y] then
|
||||
ya.manager_emit("reveal", { window[y].url })
|
||||
else
|
||||
ya.manager_emit("enter", {})
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
Progress = {
|
||||
area = ui.Rect.default,
|
||||
_area = ui.Rect.default, -- TODO: remove this
|
||||
}
|
||||
|
||||
function Progress:render(area, offset)
|
||||
self.area = ui.Rect {
|
||||
self._area = ui.Rect {
|
||||
x = math.max(0, area.w - offset - 21),
|
||||
y = area.y,
|
||||
w = ya.clamp(0, area.w - offset - 1, 20),
|
||||
|
|
@ -15,16 +15,13 @@ end
|
|||
-- Progress bars usually need frequent updates to report the latest task progress.
|
||||
-- We use `partial_render()` to partially render it when there is progress change,
|
||||
-- which has almost no cost compared to a full render by `render()`.
|
||||
--
|
||||
-- However, at this time, we can only access `cx.tasks`. If you need certain data from the complete `cx`,
|
||||
-- just cache it to `self` during `render()`, and read it in `partial_render()` - this process is referred to as "composition".
|
||||
function Progress:partial_render()
|
||||
local progress = cx.tasks.progress
|
||||
if progress.total == 0 then
|
||||
return { ui.Paragraph(self.area, {}) }
|
||||
return { ui.Paragraph(self._area, {}) }
|
||||
end
|
||||
|
||||
local gauge = ui.Gauge(self.area)
|
||||
local gauge = ui.Gauge(self._area)
|
||||
if progress.fail == 0 then
|
||||
gauge = gauge:gauge_style(THEME.status.progress_normal)
|
||||
else
|
||||
|
|
|
|||
36
yazi-plugin/preset/components/rail.lua
Normal file
36
yazi-plugin/preset/components/rail.lua
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
Rail = {
|
||||
_id = "rail",
|
||||
_area = ui.Rect.default,
|
||||
}
|
||||
|
||||
function Rail:new(chunks, tab)
|
||||
local me = setmetatable({ _chunks = chunks, _tab = tab }, { __index = self })
|
||||
me:build()
|
||||
return me
|
||||
end
|
||||
|
||||
function Rail:build()
|
||||
self._base = {
|
||||
ui.Bar(self._chunks[1], ui.Bar.RIGHT):symbol(THEME.manager.border_symbol):style(THEME.manager.border_style),
|
||||
ui.Bar(self._chunks[3], ui.Bar.LEFT):symbol(THEME.manager.border_symbol):style(THEME.manager.border_style),
|
||||
}
|
||||
self._children = {
|
||||
Marker:new(self._chunks[1], self._tab.parent),
|
||||
Marker:new(self._chunks[2], self._tab.current),
|
||||
}
|
||||
end
|
||||
|
||||
function Rail:render()
|
||||
local children = self._base or {}
|
||||
for _, child in ipairs(self._children) do
|
||||
children = ya.list_merge(children, ya.render_with(child))
|
||||
end
|
||||
return children
|
||||
end
|
||||
|
||||
-- Mouse events
|
||||
function Rail:click(event, up) end
|
||||
|
||||
function Rail:scroll(event, step) end
|
||||
|
||||
function Rail:touch(event, step) end
|
||||
|
|
@ -1,7 +1,59 @@
|
|||
Root = {
|
||||
drag_start = ui.Rect.default,
|
||||
_id = "root",
|
||||
_drag_start = ui.Rect.default,
|
||||
}
|
||||
|
||||
function Root:new(area)
|
||||
local me = setmetatable({ _area = area }, { __index = self })
|
||||
me:layout()
|
||||
me:build()
|
||||
return me
|
||||
end
|
||||
|
||||
function Root:layout()
|
||||
self._chunks = ui.Layout()
|
||||
:direction(ui.Layout.VERTICAL)
|
||||
:constraints({
|
||||
ui.Constraint.Length(1),
|
||||
ui.Constraint.Fill(1),
|
||||
ui.Constraint.Length(1),
|
||||
})
|
||||
:split(self._area)
|
||||
end
|
||||
|
||||
function Root:build()
|
||||
self._children = {
|
||||
Header:new(self._chunks[1], cx.active),
|
||||
Tab:new(self._chunks[2], cx.active),
|
||||
Status:new(self._chunks[3], cx.active),
|
||||
}
|
||||
end
|
||||
|
||||
function Root:render()
|
||||
local children = self._base or {}
|
||||
for _, child in ipairs(self._children) do
|
||||
children = ya.list_merge(children, ya.render_with(child))
|
||||
end
|
||||
__yazi_check_and_warn_deprecated_api() -- TODO: remove this after 0.3.0 release
|
||||
return children
|
||||
end
|
||||
|
||||
-- Mouse events
|
||||
function Root:click(event, up)
|
||||
local c = ya.child_at(ui.Position { x = event.x, y = event.y }, self._children)
|
||||
return c and c:click(event, up)
|
||||
end
|
||||
|
||||
function Root:scroll(event, step)
|
||||
local c = ya.child_at(ui.Position { x = event.x, y = event.y }, self._children)
|
||||
return c and c:scroll(event, step)
|
||||
end
|
||||
|
||||
function Root:touch(event, step)
|
||||
local c = ya.child_at(ui.Position { x = event.x, y = event.y }, self._children)
|
||||
return c and c:touch(event, step)
|
||||
end
|
||||
|
||||
function Root:move(event) end
|
||||
|
||||
function Root:drag(event) end
|
||||
|
|
|
|||
|
|
@ -1,11 +1,22 @@
|
|||
Status = {
|
||||
area = ui.Rect.default,
|
||||
LEFT = 0,
|
||||
RIGHT = 1,
|
||||
|
||||
_id = "status",
|
||||
_inc = 1000,
|
||||
}
|
||||
|
||||
function Status.style()
|
||||
if cx.active.mode.is_select then
|
||||
function Status:new(area, tab)
|
||||
return setmetatable({
|
||||
_area = area,
|
||||
_tab = tab,
|
||||
}, { __index = self })
|
||||
end
|
||||
|
||||
function Status:style()
|
||||
if self._tab.mode.is_select then
|
||||
return THEME.status.mode_select
|
||||
elseif cx.active.mode.is_unset then
|
||||
elseif self._tab.mode.is_unset then
|
||||
return THEME.status.mode_unset
|
||||
else
|
||||
return THEME.status.mode_normal
|
||||
|
|
@ -13,12 +24,12 @@ function Status.style()
|
|||
end
|
||||
|
||||
function Status:mode()
|
||||
local mode = tostring(cx.active.mode):upper()
|
||||
local mode = tostring(self._tab.mode):upper()
|
||||
if mode == "UNSET" then
|
||||
mode = "UN-SET"
|
||||
end
|
||||
|
||||
local style = self.style()
|
||||
local style = self:style()
|
||||
return ui.Line {
|
||||
ui.Span(THEME.status.separator_open):fg(style.bg),
|
||||
ui.Span(" " .. mode .. " "):style(style),
|
||||
|
|
@ -26,12 +37,12 @@ function Status:mode()
|
|||
end
|
||||
|
||||
function Status:size()
|
||||
local h = cx.active.current.hovered
|
||||
local h = self._tab.current.hovered
|
||||
if not h then
|
||||
return ui.Line {}
|
||||
end
|
||||
|
||||
local style = self.style()
|
||||
local style = self:style()
|
||||
return ui.Line {
|
||||
ui.Span(" " .. ya.readable_size(h:size() or h.cha.length) .. " "):fg(style.bg):bg(THEME.status.separator_style.bg),
|
||||
ui.Span(THEME.status.separator_close):fg(THEME.status.separator_style.fg),
|
||||
|
|
@ -39,16 +50,16 @@ function Status:size()
|
|||
end
|
||||
|
||||
function Status:name()
|
||||
local h = cx.active.current.hovered
|
||||
local h = self._tab.current.hovered
|
||||
if not h then
|
||||
return ui.Span("")
|
||||
return ui.Line {}
|
||||
end
|
||||
|
||||
return ui.Span(" " .. h.name)
|
||||
return ui.Line(" " .. h.name)
|
||||
end
|
||||
|
||||
function Status:permissions()
|
||||
local h = cx.active.current.hovered
|
||||
local h = self._tab.current.hovered
|
||||
if not h then
|
||||
return ui.Line {}
|
||||
end
|
||||
|
|
@ -78,8 +89,8 @@ end
|
|||
|
||||
function Status:percentage()
|
||||
local percent = 0
|
||||
local cursor = cx.active.current.cursor
|
||||
local length = #cx.active.current.files
|
||||
local cursor = self._tab.current.cursor
|
||||
local length = #self._tab.current.files
|
||||
if cursor ~= 0 and length ~= 0 then
|
||||
percent = math.floor((cursor + 1) * 100 / length)
|
||||
end
|
||||
|
|
@ -92,7 +103,7 @@ function Status:percentage()
|
|||
percent = string.format(" %3d%% ", percent)
|
||||
end
|
||||
|
||||
local style = self.style()
|
||||
local style = self:style()
|
||||
return ui.Line {
|
||||
ui.Span(" " .. THEME.status.separator_open):fg(THEME.status.separator_style.fg),
|
||||
ui.Span(percent):fg(style.bg):bg(THEME.status.separator_style.bg),
|
||||
|
|
@ -100,30 +111,69 @@ function Status:percentage()
|
|||
end
|
||||
|
||||
function Status:position()
|
||||
local cursor = cx.active.current.cursor
|
||||
local length = #cx.active.current.files
|
||||
local cursor = self._tab.current.cursor
|
||||
local length = #self._tab.current.files
|
||||
|
||||
local style = self.style()
|
||||
local style = self:style()
|
||||
return ui.Line {
|
||||
ui.Span(string.format(" %2d/%-2d ", cursor + 1, length)):style(style),
|
||||
ui.Span(THEME.status.separator_close):fg(style.bg),
|
||||
}
|
||||
end
|
||||
|
||||
function Status:render(area)
|
||||
self.area = area
|
||||
|
||||
local left = ui.Line { self:mode(), self:size(), self:name() }
|
||||
local right = ui.Line { self:permissions(), self:percentage(), self:position() }
|
||||
function Status:render()
|
||||
local left = self:children_render(self.LEFT)
|
||||
local right = self:children_render(self.RIGHT)
|
||||
return {
|
||||
ui.Paragraph(area, { left }),
|
||||
ui.Paragraph(area, { right }):align(ui.Paragraph.RIGHT),
|
||||
table.unpack(Progress:render(area, right:width())),
|
||||
ui.Paragraph(self._area, { left }),
|
||||
ui.Paragraph(self._area, { right }):align(ui.Paragraph.RIGHT),
|
||||
table.unpack(Progress:render(self._area, right:width())),
|
||||
}
|
||||
end
|
||||
|
||||
-- Mouse events
|
||||
function Status:click(event, up) end
|
||||
|
||||
function Status:scroll(event, step) end
|
||||
|
||||
function Status:touch(event, step) end
|
||||
|
||||
-- Initialize children
|
||||
Status._left = {
|
||||
{ Status.mode, id = 1, order = 1000 },
|
||||
{ Status.size, id = 2, order = 2000 },
|
||||
{ Status.name, id = 3, order = 3000 },
|
||||
}
|
||||
Status._right = {
|
||||
{ Status.permissions, id = 4, order = 1000 },
|
||||
{ Status.percentage, id = 5, order = 2000 },
|
||||
{ Status.position, id = 6, order = 3000 },
|
||||
}
|
||||
|
||||
function Status:children_add(fn, order, side)
|
||||
self._inc = self._inc + 1
|
||||
local children = side == self.RIGHT and self._right or self._left
|
||||
|
||||
children[#children + 1] = { fn, id = self._inc, order = order }
|
||||
table.sort(children, function(a, b) return a.order < b.order end)
|
||||
|
||||
return self._inc
|
||||
end
|
||||
|
||||
function Status:children_remove(id, side)
|
||||
local children = side == self.RIGHT and self._right or self._left
|
||||
for i, child in ipairs(children) do
|
||||
if child.id == id then
|
||||
table.remove(children, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Status:children_render(side)
|
||||
local lines = {}
|
||||
for _, child in ipairs(side == self.RIGHT and self._right or self._left) do
|
||||
lines[#lines + 1] = child[1](self)
|
||||
end
|
||||
return ui.Line(lines)
|
||||
end
|
||||
|
|
|
|||
54
yazi-plugin/preset/components/tab.lua
Normal file
54
yazi-plugin/preset/components/tab.lua
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
Tab = {
|
||||
_id = "tab",
|
||||
}
|
||||
|
||||
function Tab:new(area, tab)
|
||||
local me = setmetatable({ _area = area, _tab = tab }, { __index = self })
|
||||
me:layout()
|
||||
me:build()
|
||||
return me
|
||||
end
|
||||
|
||||
function Tab:layout()
|
||||
self._chunks = ui.Layout()
|
||||
:direction(ui.Layout.HORIZONTAL)
|
||||
:constraints({
|
||||
ui.Constraint.Ratio(MANAGER.ratio.parent, MANAGER.ratio.all),
|
||||
ui.Constraint.Ratio(MANAGER.ratio.current, MANAGER.ratio.all),
|
||||
ui.Constraint.Ratio(MANAGER.ratio.preview, MANAGER.ratio.all),
|
||||
})
|
||||
:split(self._area)
|
||||
end
|
||||
|
||||
function Tab:build()
|
||||
self._children = {
|
||||
Rail:new(self._chunks, self._tab),
|
||||
Parent:new(self._chunks[1]:padding(ui.Padding.x(1)), self._tab),
|
||||
Current:new(self._chunks[2], self._tab),
|
||||
Preview:new(self._chunks[3]:padding(ui.Padding.x(1)), self._tab),
|
||||
}
|
||||
end
|
||||
|
||||
function Tab:render()
|
||||
local children = self._base or {}
|
||||
for _, child in ipairs(self._children) do
|
||||
children = ya.list_merge(children, ya.render_with(child))
|
||||
end
|
||||
return children
|
||||
end
|
||||
|
||||
-- Mouse events
|
||||
function Tab:click(event, up)
|
||||
local c = ya.child_at(ui.Position { x = event.x, y = event.y }, self._children)
|
||||
return c and c:click(event, up)
|
||||
end
|
||||
|
||||
function Tab:scroll(event, step)
|
||||
local c = ya.child_at(ui.Position { x = event.x, y = event.y }, self._children)
|
||||
return c and c:scroll(event, step)
|
||||
end
|
||||
|
||||
function Tab:touch(event, step)
|
||||
local c = ya.child_at(ui.Position { x = event.x, y = event.y }, self._children)
|
||||
return c and c:touch(event, step)
|
||||
end
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
local M = {}
|
||||
|
||||
function M:peek()
|
||||
local folder = Folder:by_kind(Folder.PREVIEW)
|
||||
local folder = cx.active.preview.folder
|
||||
if not folder or folder.cwd ~= self.file.url then
|
||||
return
|
||||
end
|
||||
|
|
@ -18,28 +18,19 @@ function M:peek()
|
|||
})
|
||||
end
|
||||
|
||||
local items, markers = {}, {}
|
||||
for i, f in ipairs(folder.window) do
|
||||
items[#items + 1] = ui.ListItem(ui.Line(File:full(f))):style(File:style(f))
|
||||
|
||||
-- Yanked/marked/selected files
|
||||
local marker = File:marker(f)
|
||||
if marker ~= 0 then
|
||||
markers[#markers + 1] = { i, marker }
|
||||
end
|
||||
local items = {}
|
||||
for _, f in ipairs(folder.window) do
|
||||
items[#items + 1] = ui.ListItem(Entity:render(f)):style(Entity:style(f))
|
||||
end
|
||||
|
||||
ya.preview_widgets(
|
||||
self,
|
||||
ya.flat {
|
||||
ui.List(self.area, items),
|
||||
Folder:markers(self.area, markers),
|
||||
}
|
||||
)
|
||||
ya.preview_widgets(self, {
|
||||
ui.List(self.area, items),
|
||||
table.unpack(Marker:new(self.area, folder):render()),
|
||||
})
|
||||
end
|
||||
|
||||
function M:seek(units)
|
||||
local folder = Folder:by_kind(Folder.PREVIEW)
|
||||
local folder = cx.active.preview.folder
|
||||
if folder and folder.cwd == self.file.url then
|
||||
local step = math.floor(units * self.area.h / 10)
|
||||
local bound = math.max(0, #folder.files - self.area.h)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ function M:peek() end
|
|||
|
||||
function M:seek() end
|
||||
|
||||
function M:fetch() return 1 end
|
||||
|
||||
function M:preload() return 1 end
|
||||
|
||||
return M
|
||||
|
|
|
|||
|
|
@ -14,18 +14,11 @@ end
|
|||
|
||||
function ya.round(x) return x >= 0 and math.floor(x + 0.5) or math.ceil(x - 0.5) end
|
||||
|
||||
function ya.flat(t)
|
||||
local r = {}
|
||||
for _, v in ipairs(t) do
|
||||
if type(v) == "table" then
|
||||
for _, v2 in ipairs(ya.flat(v)) do
|
||||
r[#r + 1] = v2
|
||||
end
|
||||
else
|
||||
r[#r + 1] = v
|
||||
end
|
||||
function ya.list_merge(a, b)
|
||||
for _, v in ipairs(b) do
|
||||
a[#a + 1] = v
|
||||
end
|
||||
return r
|
||||
return a
|
||||
end
|
||||
|
||||
function ya.basename(str) return string.gsub(str, "(.*[/\\])(.*)", "%2") end
|
||||
|
|
@ -50,3 +43,11 @@ function ya.readable_path(path)
|
|||
return path
|
||||
end
|
||||
end
|
||||
|
||||
function ya.child_at(position, children)
|
||||
for i = #children, 1, -1 do
|
||||
if children[i]._area:contains(position) then
|
||||
return children[i]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ pub struct MouseEvent;
|
|||
impl MouseEvent {
|
||||
pub fn register(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.register_userdata_type::<crossterm::event::MouseEvent>(|reg| {
|
||||
reg.add_field_method_get("x", |_, me| Ok(me.column as u32 + 1));
|
||||
reg.add_field_method_get("y", |_, me| Ok(me.row as u32 + 1));
|
||||
reg.add_field_method_get("x", |_, me| Ok(me.column));
|
||||
reg.add_field_method_get("y", |_, me| Ok(me.row));
|
||||
reg.add_field_method_get("is_left", |_, me| {
|
||||
use crossterm::event::MouseEventKind as K;
|
||||
Ok(matches!(me.kind, K::Down(b) | K::Up(b) | K::Drag(b) if b == MouseButton::Left))
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use mlua::AnyUserData;
|
|||
|
||||
use crate::elements::Renderable;
|
||||
|
||||
pub fn cast_to_renderable(ud: AnyUserData) -> Option<Box<dyn Renderable + Send>> {
|
||||
pub fn cast_to_renderable(ud: &AnyUserData) -> Option<Box<dyn Renderable + Send>> {
|
||||
if let Ok(c) = ud.take::<crate::elements::Paragraph>() {
|
||||
Some(Box::new(c))
|
||||
} else if let Ok(c) = ud.take::<crate::elements::List>() {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,18 @@ impl Constraint {
|
|||
pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> {
|
||||
let constraint = lua.create_table()?;
|
||||
|
||||
constraint.raw_set(
|
||||
"Min",
|
||||
lua.create_function(|_, n: u16| Ok(Constraint(ratatui::layout::Constraint::Min(n))))?,
|
||||
)?;
|
||||
constraint.raw_set(
|
||||
"Max",
|
||||
lua.create_function(|_, n: u16| Ok(Constraint(ratatui::layout::Constraint::Max(n))))?,
|
||||
)?;
|
||||
constraint.raw_set(
|
||||
"Length",
|
||||
lua.create_function(|_, n: u16| Ok(Constraint(ratatui::layout::Constraint::Length(n))))?,
|
||||
)?;
|
||||
constraint.raw_set(
|
||||
"Percentage",
|
||||
lua
|
||||
|
|
@ -19,16 +31,8 @@ impl Constraint {
|
|||
})?,
|
||||
)?;
|
||||
constraint.raw_set(
|
||||
"Length",
|
||||
lua.create_function(|_, n: u16| Ok(Constraint(ratatui::layout::Constraint::Length(n))))?,
|
||||
)?;
|
||||
constraint.raw_set(
|
||||
"Max",
|
||||
lua.create_function(|_, n: u16| Ok(Constraint(ratatui::layout::Constraint::Max(n))))?,
|
||||
)?;
|
||||
constraint.raw_set(
|
||||
"Min",
|
||||
lua.create_function(|_, n: u16| Ok(Constraint(ratatui::layout::Constraint::Min(n))))?,
|
||||
"Fill",
|
||||
lua.create_function(|_, n: u16| Ok(Constraint(ratatui::layout::Constraint::Fill(n))))?,
|
||||
)?;
|
||||
|
||||
ui.raw_set("Constraint", constraint)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use mlua::{AnyUserData, Lua};
|
||||
use mlua::{AnyUserData, Lua, Table};
|
||||
use tracing::error;
|
||||
|
||||
use crate::cast_to_renderable;
|
||||
|
||||
|
|
@ -21,6 +22,7 @@ pub fn pour(lua: &Lua) -> mlua::Result<()> {
|
|||
super::ListItem::install(lua, &ui)?;
|
||||
super::Padding::install(lua, &ui)?;
|
||||
super::Paragraph::install(lua, &ui)?;
|
||||
super::Position::install(lua, &ui)?;
|
||||
super::Rect::install(lua, &ui)?;
|
||||
super::Span::install(lua, &ui)?;
|
||||
super::Style::install(lua, &ui)?;
|
||||
|
|
@ -36,10 +38,16 @@ pub trait Renderable {
|
|||
fn clone_render(&self, buf: &mut ratatui::buffer::Buffer);
|
||||
}
|
||||
|
||||
pub fn render_widgets(widgets: Vec<AnyUserData>, buf: &mut ratatui::buffer::Buffer) {
|
||||
for widget in widgets {
|
||||
if let Some(w) = cast_to_renderable(widget) {
|
||||
w.render(buf);
|
||||
pub fn render_widgets(widgets: Table, buf: &mut ratatui::buffer::Buffer) {
|
||||
for widget in widgets.sequence_values::<AnyUserData>() {
|
||||
let Ok(widget) = widget else {
|
||||
error!("Failed to convert to renderable UserData: {}", widget.unwrap_err());
|
||||
continue;
|
||||
};
|
||||
|
||||
match cast_to_renderable(&widget) {
|
||||
Some(w) => w.render(buf),
|
||||
None => error!("Only the UserData of renderable element is accepted: {widget:#?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,11 @@ impl TryFrom<Table<'_>> for Line {
|
|||
if let Ok(span) = ud.take::<Span>() {
|
||||
spans.push(span.0);
|
||||
} else if let Ok(line) = ud.take::<Line>() {
|
||||
spans.extend(line.0.spans.into_iter().collect::<Vec<_>>());
|
||||
let style = line.0.style;
|
||||
spans.extend(line.0.spans.into_iter().map(|mut span| {
|
||||
span.style = style.patch(span.style);
|
||||
span
|
||||
}));
|
||||
} else {
|
||||
return Err("expected a table of Spans or Lines".into_lua_err());
|
||||
}
|
||||
|
|
@ -83,9 +87,9 @@ impl UserData for Line {
|
|||
{
|
||||
let mut me = ud.borrow_mut::<Self>()?;
|
||||
me.0.style = match value {
|
||||
Value::Nil => me.0.style.patch(ratatui::style::Style::reset()),
|
||||
Value::Table(tb) => me.0.style.patch(Style::try_from(tb)?.0),
|
||||
Value::UserData(ud) => me.0.style.patch(ud.borrow::<Style>()?.0),
|
||||
Value::Nil => ratatui::style::Style::default(),
|
||||
Value::Table(tb) => Style::try_from(tb)?.0,
|
||||
Value::UserData(ud) => ud.borrow::<Style>()?.0,
|
||||
_ => return Err("expected a Style or Table or nil".into_lua_err()),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ mod line;
|
|||
mod list;
|
||||
mod padding;
|
||||
mod paragraph;
|
||||
mod position;
|
||||
mod rect;
|
||||
mod span;
|
||||
mod style;
|
||||
|
|
@ -26,6 +27,7 @@ pub use line::*;
|
|||
pub use list::*;
|
||||
pub use padding::*;
|
||||
pub use paragraph::*;
|
||||
pub use position::*;
|
||||
pub use rect::*;
|
||||
pub use span::*;
|
||||
pub use style::*;
|
||||
|
|
|
|||
38
yazi-plugin/src/elements/position.rs
Normal file
38
yazi-plugin/src/elements/position.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
use mlua::{AnyUserData, Lua, Table, UserDataFields, UserDataRef};
|
||||
|
||||
use crate::bindings::Cast;
|
||||
|
||||
pub type PositionRef<'lua> = UserDataRef<'lua, ratatui::layout::Position>;
|
||||
|
||||
pub struct Position;
|
||||
|
||||
impl Position {
|
||||
pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> {
|
||||
let new = lua.create_function(|lua, (_, args): (Table, Table)| {
|
||||
Position::cast(lua, ratatui::layout::Position {
|
||||
x: args.raw_get("x")?,
|
||||
y: args.raw_get("y")?,
|
||||
})
|
||||
})?;
|
||||
|
||||
let position =
|
||||
lua.create_table_from([("default", Position::cast(lua, Default::default())?)])?;
|
||||
|
||||
position.set_metatable(Some(lua.create_table_from([("__call", new)])?));
|
||||
|
||||
ui.raw_set("Position", position)
|
||||
}
|
||||
|
||||
pub fn register(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.register_userdata_type::<ratatui::layout::Position>(|reg| {
|
||||
reg.add_field_method_get("x", |_, me| Ok(me.x));
|
||||
reg.add_field_method_get("y", |_, me| Ok(me.y));
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Cast<ratatui::layout::Position> for Position {
|
||||
fn cast(lua: &Lua, data: ratatui::layout::Position) -> mlua::Result<AnyUserData> {
|
||||
lua.create_any_userdata(data)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
use mlua::{AnyUserData, Lua, Table, UserDataFields, UserDataMethods, UserDataRef};
|
||||
|
||||
use super::PaddingRef;
|
||||
use super::{PaddingRef, Position, PositionRef};
|
||||
use crate::bindings::Cast;
|
||||
|
||||
pub type RectRef<'lua> = UserDataRef<'lua, ratatui::layout::Rect>;
|
||||
|
|
@ -46,6 +46,8 @@ impl Rect {
|
|||
r.height = r.height.saturating_sub(padding.top + padding.bottom);
|
||||
Rect::cast(lua, r)
|
||||
});
|
||||
reg.add_method("position", |lua, me, ()| Position::cast(lua, me.as_position()));
|
||||
reg.add_method("contains", |_, me, position: PositionRef| Ok(me.contains(*position)));
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ pub async fn entry(name: String, args: Vec<Data>) -> mlua::Result<()> {
|
|||
tokio::task::spawn_blocking(move || {
|
||||
let lua = slim_lua(&name)?;
|
||||
let plugin: Table = if let Some(b) = LOADER.read().get(&name) {
|
||||
lua.load(b.as_ref()).call(())?
|
||||
lua.load(b.as_ref()).set_name(name).call(())?
|
||||
} else {
|
||||
return Err("unloaded plugin".into_lua_err());
|
||||
};
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ pub async fn fetch(name: &str, files: Vec<yazi_shared::fs::File>) -> mlua::Resul
|
|||
tokio::task::spawn_blocking(move || {
|
||||
let lua = slim_lua(&name)?;
|
||||
let plugin: Table = if let Some(b) = LOADER.read().get(&name) {
|
||||
lua.load(b.as_ref()).call(())?
|
||||
lua.load(b.as_ref()).set_name(name).call(())?
|
||||
} else {
|
||||
return Err("unloaded plugin".into_lua_err());
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ pub fn slim_lua(name: &str) -> mlua::Result<Lua> {
|
|||
crate::process::install(&lua)?;
|
||||
crate::utils::install_isolate(&lua)?;
|
||||
crate::Config::new(&lua).install_preview()?;
|
||||
lua.load(include_str!("../../preset/ya.lua")).exec()?;
|
||||
lua.load(include_str!("../../preset/ya.lua")).set_name("ya.lua").exec()?;
|
||||
|
||||
// Elements
|
||||
let ui = lua.create_table()?;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ pub fn peek(cmd: &Cmd, file: yazi_shared::fs::File, skip: usize) -> Cancellation
|
|||
);
|
||||
|
||||
let plugin: Table = if let Some(b) = LOADER.read().get(&name) {
|
||||
lua.load(b.as_ref()).call(())?
|
||||
lua.load(b.as_ref()).set_name(name).call(())?
|
||||
} else {
|
||||
return Err("unloaded plugin".into_lua_err());
|
||||
};
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ pub async fn preload(name: &str, file: yazi_shared::fs::File) -> mlua::Result<u8
|
|||
tokio::task::spawn_blocking(move || {
|
||||
let lua = slim_lua(&name)?;
|
||||
let plugin: Table = if let Some(b) = LOADER.read().get(&name) {
|
||||
lua.load(b.as_ref()).call(())?
|
||||
lua.load(b.as_ref()).set_name(name).call(())?
|
||||
} else {
|
||||
return Err("unloaded plugin".into_lua_err());
|
||||
};
|
||||
|
|
|
|||
|
|
@ -26,9 +26,10 @@ pub use lua::*;
|
|||
pub use opt::*;
|
||||
pub use runtime::*;
|
||||
|
||||
pub fn init() {
|
||||
pub fn init() -> anyhow::Result<()> {
|
||||
CLIPBOARD.with(Default::default);
|
||||
|
||||
crate::loader::init();
|
||||
crate::init_lua();
|
||||
crate::init_lua()?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::{borrow::Cow, collections::HashMap, ops::Deref};
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use anyhow::Result;
|
||||
use mlua::{ExternalError, Table};
|
||||
use parking_lot::RwLock;
|
||||
use tokio::fs;
|
||||
|
|
@ -22,36 +22,31 @@ impl Loader {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let b = match name {
|
||||
"dds" => Some(&include_bytes!("../../preset/plugins/dds.lua")[..]),
|
||||
"noop" => Some(&include_bytes!("../../preset/plugins/noop.lua")[..]),
|
||||
"session" => Some(&include_bytes!("../../preset/plugins/session.lua")[..]),
|
||||
_ => None,
|
||||
let preset = match name {
|
||||
"dds" => &include_bytes!("../../preset/plugins/dds.lua")[..],
|
||||
"noop" => include_bytes!("../../preset/plugins/noop.lua"),
|
||||
"session" => include_bytes!("../../preset/plugins/session.lua"),
|
||||
"archive" => include_bytes!("../../preset/plugins/archive.lua"),
|
||||
"code" => include_bytes!("../../preset/plugins/code.lua"),
|
||||
"file" => include_bytes!("../../preset/plugins/file.lua"),
|
||||
"folder" => include_bytes!("../../preset/plugins/folder.lua"),
|
||||
"font" => include_bytes!("../../preset/plugins/font.lua"),
|
||||
"fzf" => include_bytes!("../../preset/plugins/fzf.lua"),
|
||||
"image" => include_bytes!("../../preset/plugins/image.lua"),
|
||||
"json" => include_bytes!("../../preset/plugins/json.lua"),
|
||||
"magick" => include_bytes!("../../preset/plugins/magick.lua"),
|
||||
"mime" => include_bytes!("../../preset/plugins/mime.lua"),
|
||||
"pdf" => include_bytes!("../../preset/plugins/pdf.lua"),
|
||||
"video" => include_bytes!("../../preset/plugins/video.lua"),
|
||||
"zoxide" => include_bytes!("../../preset/plugins/zoxide.lua"),
|
||||
_ => b"",
|
||||
};
|
||||
if let Some(b) = b {
|
||||
self.cache.write().insert(name.to_owned(), Cow::Borrowed(b));
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let path = BOOT.plugin_dir.join(format!("{name}.yazi/init.lua"));
|
||||
let b = fs::read(path).await.map(|v| v.into()).or_else(|_| {
|
||||
Ok(Cow::from(match name {
|
||||
"archive" => &include_bytes!("../../preset/plugins/archive.lua")[..],
|
||||
"code" => include_bytes!("../../preset/plugins/code.lua"),
|
||||
"file" => include_bytes!("../../preset/plugins/file.lua"),
|
||||
"folder" => include_bytes!("../../preset/plugins/folder.lua"),
|
||||
"font" => include_bytes!("../../preset/plugins/font.lua"),
|
||||
"fzf" => include_bytes!("../../preset/plugins/fzf.lua"),
|
||||
"image" => include_bytes!("../../preset/plugins/image.lua"),
|
||||
"json" => include_bytes!("../../preset/plugins/json.lua"),
|
||||
"magick" => include_bytes!("../../preset/plugins/magick.lua"),
|
||||
"mime" => include_bytes!("../../preset/plugins/mime.lua"),
|
||||
"pdf" => include_bytes!("../../preset/plugins/pdf.lua"),
|
||||
"video" => include_bytes!("../../preset/plugins/video.lua"),
|
||||
"zoxide" => include_bytes!("../../preset/plugins/zoxide.lua"),
|
||||
_ => bail!("plugin not found: {name}"),
|
||||
}))
|
||||
})?;
|
||||
let b = if preset.is_empty() {
|
||||
Cow::Owned(fs::read(BOOT.plugin_dir.join(format!("{name}.yazi/init.lua"))).await?)
|
||||
} else {
|
||||
Cow::Borrowed(preset)
|
||||
};
|
||||
|
||||
self.cache.write().insert(name.to_owned(), b);
|
||||
Ok(())
|
||||
|
|
@ -65,10 +60,11 @@ impl Loader {
|
|||
}
|
||||
|
||||
let t: Table = match self.read().get(name) {
|
||||
Some(b) => LUA.load(b.as_ref()).call(())?,
|
||||
Some(b) => LUA.load(b.as_ref()).set_name(name).call(())?,
|
||||
None => Err(format!("plugin `{name}` not found").into_lua_err())?,
|
||||
};
|
||||
|
||||
// TODO: rename to `_id`
|
||||
t.raw_set("_name", LUA.create_string(name)?)?;
|
||||
loaded.raw_set(name, t.clone())?;
|
||||
Ok(t)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use anyhow::Result;
|
||||
use anyhow::{Context, Result};
|
||||
use mlua::Lua;
|
||||
use yazi_boot::BOOT;
|
||||
use yazi_shared::RoCell;
|
||||
|
|
@ -7,11 +7,12 @@ use crate::runtime::Runtime;
|
|||
|
||||
pub static LUA: RoCell<Lua> = RoCell::new();
|
||||
|
||||
pub(super) fn init_lua() {
|
||||
pub(super) fn init_lua() -> Result<()> {
|
||||
LUA.init(Lua::new());
|
||||
|
||||
stage_1(&LUA).expect("Lua setup failed");
|
||||
stage_2(&LUA).expect("Lua runtime failed");
|
||||
stage_1(&LUA).context("Lua setup failed")?;
|
||||
stage_2(&LUA).context("Lua runtime failed")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn stage_1(lua: &'static Lua) -> Result<()> {
|
||||
|
|
@ -20,7 +21,7 @@ fn stage_1(lua: &'static Lua) -> Result<()> {
|
|||
|
||||
// Base
|
||||
lua.set_named_registry_value("rt", Runtime::default())?;
|
||||
lua.load(include_str!("../preset/ya.lua")).exec()?;
|
||||
lua.load(include_str!("../preset/ya.lua")).set_name("ya.lua").exec()?;
|
||||
crate::bindings::Icon::register(lua)?;
|
||||
crate::bindings::MouseEvent::register(lua)?;
|
||||
crate::elements::pour(lua)?;
|
||||
|
|
@ -31,25 +32,28 @@ fn stage_1(lua: &'static Lua) -> Result<()> {
|
|||
crate::url::pour(lua)?;
|
||||
|
||||
// Components
|
||||
lua.load(include_str!("../preset/components/current.lua")).exec()?;
|
||||
lua.load(include_str!("../preset/components/file.lua")).exec()?;
|
||||
lua.load(include_str!("../preset/components/folder.lua")).exec()?;
|
||||
lua.load(include_str!("../preset/components/header.lua")).exec()?;
|
||||
lua.load(include_str!("../preset/components/manager.lua")).exec()?;
|
||||
lua.load(include_str!("../preset/components/parent.lua")).exec()?;
|
||||
lua.load(include_str!("../preset/components/preview.lua")).exec()?;
|
||||
lua.load(include_str!("../preset/components/progress.lua")).exec()?;
|
||||
lua.load(include_str!("../preset/components/root.lua")).exec()?;
|
||||
lua.load(include_str!("../preset/components/status.lua")).exec()?;
|
||||
lua.load(include_str!("../preset/components/current.lua")).set_name("current.lua").exec()?;
|
||||
lua.load(include_str!("../preset/components/entity.lua")).set_name("entity.lua").exec()?;
|
||||
lua.load(include_str!("../preset/components/header.lua")).set_name("header.lua").exec()?;
|
||||
lua.load(include_str!("../preset/components/linemode.lua")).set_name("linemode.lua").exec()?;
|
||||
lua.load(include_str!("../preset/components/marker.lua")).set_name("marker.lua").exec()?;
|
||||
lua.load(include_str!("../preset/components/parent.lua")).set_name("parent.lua").exec()?;
|
||||
lua.load(include_str!("../preset/components/preview.lua")).set_name("preview.lua").exec()?;
|
||||
lua.load(include_str!("../preset/components/progress.lua")).set_name("progress.lua").exec()?;
|
||||
lua.load(include_str!("../preset/components/rail.lua")).set_name("rail.lua").exec()?;
|
||||
lua.load(include_str!("../preset/components/root.lua")).set_name("root.lua").exec()?;
|
||||
lua.load(include_str!("../preset/components/status.lua")).set_name("status.lua").exec()?;
|
||||
lua.load(include_str!("../preset/components/tab.lua")).set_name("tab.lua").exec()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn stage_2(lua: &'static Lua) -> mlua::Result<()> {
|
||||
lua.load(include_str!("../preset/setup.lua")).exec()?;
|
||||
lua.load(include_str!("../preset/setup.lua")).set_name("setup.lua").exec()?;
|
||||
lua.load(include_str!("../preset/compat.lua")).set_name("compat.lua").exec()?;
|
||||
|
||||
if let Ok(b) = std::fs::read(BOOT.config_dir.join("init.lua")) {
|
||||
lua.load(b).exec()?;
|
||||
lua.load(b).set_name("init.lua").exec()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use mlua::{ExternalError, Lua, Table, Value};
|
||||
use mlua::{ExternalError, Lua, Table, TableExt, Value};
|
||||
use tracing::error;
|
||||
use yazi_config::LAYOUT;
|
||||
use yazi_dds::Sendable;
|
||||
use yazi_shared::{emit, event::{Cmd, Data}, render, Layer};
|
||||
|
||||
use super::Utils;
|
||||
use crate::elements::RectRef;
|
||||
|
||||
impl Utils {
|
||||
fn parse_args(t: Table) -> mlua::Result<HashMap<String, Data>> {
|
||||
|
|
@ -33,6 +36,38 @@ impl Utils {
|
|||
})?,
|
||||
)?;
|
||||
|
||||
ya.raw_set(
|
||||
"render_with",
|
||||
lua.create_function(|lua, c: Table| {
|
||||
let id: mlua::String = c.get("_id")?;
|
||||
let id = id.to_str()?;
|
||||
|
||||
match id {
|
||||
"current" => {
|
||||
LAYOUT.store(Arc::new(yazi_config::Layout {
|
||||
current: *c.raw_get::<_, RectRef>("_area")?,
|
||||
..*LAYOUT.load_full()
|
||||
}));
|
||||
}
|
||||
"preview" => {
|
||||
LAYOUT.store(Arc::new(yazi_config::Layout {
|
||||
preview: *c.raw_get::<_, RectRef>("_area")?,
|
||||
..*LAYOUT.load_full()
|
||||
}));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match c.call_method::<_, Table>("render", ()) {
|
||||
Err(e) => {
|
||||
error!("Failed to `render()` the `{id}` component:\n{e}");
|
||||
lua.create_table()
|
||||
}
|
||||
ok => ok,
|
||||
}
|
||||
})?,
|
||||
)?;
|
||||
|
||||
ya.raw_set(
|
||||
"app_emit",
|
||||
lua.create_function(|_, (name, args): (String, Table)| {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ impl Utils {
|
|||
ya.raw_set(
|
||||
"dbg",
|
||||
lua.create_function(|_, values: Variadic<Value>| {
|
||||
let s = values.into_iter().map(|v| format!("{:#?}", v)).collect::<Vec<_>>().join(" ");
|
||||
let s = values.into_iter().map(|v| format!("{v:#?}")).collect::<Vec<_>>().join(" ");
|
||||
Ok(debug!("{s}"))
|
||||
})?,
|
||||
)?;
|
||||
|
|
@ -16,7 +16,7 @@ impl Utils {
|
|||
ya.raw_set(
|
||||
"err",
|
||||
lua.create_function(|_, values: Variadic<Value>| {
|
||||
let s = values.into_iter().map(|v| format!("{:#?}", v)).collect::<Vec<_>>().join(" ");
|
||||
let s = values.into_iter().map(|v| format!("{v:#?}")).collect::<Vec<_>>().join(" ");
|
||||
Ok(error!("{s}"))
|
||||
})?,
|
||||
)?;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ impl Utils {
|
|||
"preview_widgets",
|
||||
lua.create_async_function(|_, (t, widgets): (Table, Vec<AnyUserData>)| async move {
|
||||
let mut lock = PreviewLock::try_from(t)?;
|
||||
lock.data = widgets.into_iter().filter_map(cast_to_renderable).collect();
|
||||
lock.data = widgets.into_iter().filter_map(|ud| cast_to_renderable(&ud)).collect();
|
||||
|
||||
emit!(Call(Cmd::new("preview").with_any("lock", lock), Layer::Manager));
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ rust-version = "1.78.0"
|
|||
|
||||
[dependencies]
|
||||
anyhow = "1.0.86"
|
||||
bitflags = "2.5.0"
|
||||
bitflags = "2.6.0"
|
||||
crossterm = "0.27.0"
|
||||
dirs = "5.0.1"
|
||||
futures = "0.3.30"
|
||||
|
|
@ -19,7 +19,7 @@ parking_lot = "0.12.3"
|
|||
percent-encoding = "2.3.1"
|
||||
ratatui = "0.27.0"
|
||||
regex = "1.10.5"
|
||||
serde = { version = "1.0.203", features = [ "derive" ] }
|
||||
serde = { version = "1.0.204", features = [ "derive" ] }
|
||||
shell-words = "1.1.0"
|
||||
tokio = { version = "1.38.0", features = [ "full" ] }
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue