feat: Introduce remote scheme

Signed-off-by: Xuanwo <github@xuanwo.io>
This commit is contained in:
Xuanwo 2024-06-13 21:05:57 +08:00 committed by sxyazi
parent 794694e2d6
commit 049cdefeed
No known key found for this signature in database
22 changed files with 2553 additions and 1175 deletions

659
Cargo.lock generated
View file

@ -139,12 +139,35 @@ dependencies = [
"event-listener", "event-listener",
] ]
[[package]]
name = "async-trait"
version = "0.1.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.3.0" version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "backon"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d67782c3f868daa71d3533538e98a8e13713231969def7536e8039606fc46bf0"
dependencies = [
"fastrand",
"futures-core",
"pin-project",
"tokio",
]
[[package]] [[package]]
name = "backtrace" name = "backtrace"
version = "0.3.71" version = "0.3.71"
@ -287,7 +310,9 @@ checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [ dependencies = [
"android-tzdata", "android-tzdata",
"iana-time-zone", "iana-time-zone",
"js-sys",
"num-traits", "num-traits",
"wasm-bindgen",
"windows-targets 0.52.5", "windows-targets 0.52.5",
] ]
@ -415,12 +440,56 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "const-oid"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "const-random"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359"
dependencies = [
"const-random-macro",
]
[[package]]
name = "const-random-macro"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
dependencies = [
"getrandom",
"once_cell",
"tiny-keccak",
]
[[package]] [[package]]
name = "core-foundation-sys" name = "core-foundation-sys"
version = "0.8.6" version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]]
name = "cpufeatures"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
dependencies = [
"libc",
]
[[package]]
name = "crc32c"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a47af21622d091a8f0fb295b88bc886ac74efcc613efc19f5d0b21de5c89e47"
dependencies = [
"rustc_version",
]
[[package]] [[package]]
name = "crc32fast" name = "crc32fast"
version = "1.4.0" version = "1.4.0"
@ -557,7 +626,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [ dependencies = [
"block-buffer", "block-buffer",
"const-oid",
"crypto-common", "crypto-common",
"subtle",
] ]
[[package]] [[package]]
@ -581,6 +652,15 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "dlv-list"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f"
dependencies = [
"const-random",
]
[[package]] [[package]]
name = "either" name = "either"
version = "1.11.0" version = "1.11.0"
@ -651,6 +731,12 @@ dependencies = [
"zune-inflate", "zune-inflate",
] ]
[[package]]
name = "fastrand"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
[[package]] [[package]]
name = "fdeflate" name = "fdeflate"
version = "0.3.4" version = "0.3.4"
@ -682,6 +768,12 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "flagset"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdeb3aa5e95cf9aabc17f060cfa0ced7b83f042390760ca53bf09df9968acaa1"
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.28" version = "1.0.28"
@ -831,8 +923,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"js-sys",
"libc", "libc",
"wasi", "wasi",
"wasm-bindgen",
] ]
[[package]] [[package]]
@ -902,6 +996,21 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hmac"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
"digest",
]
[[package]] [[package]]
name = "home" name = "home"
version = "0.5.9" version = "0.5.9"
@ -911,6 +1020,102 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "http"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "http-body"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
dependencies = [
"bytes",
"http",
]
[[package]]
name = "http-body-util"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
dependencies = [
"bytes",
"futures-util",
"http",
"http-body",
"pin-project-lite",
]
[[package]]
name = "httparse"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0e7a4dd27b9476dc40cb050d3632d3bba3a70ddbff012285f7f8559a1e7e545"
[[package]]
name = "hyper"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http",
"http-body",
"httparse",
"itoa",
"pin-project-lite",
"smallvec",
"tokio",
"want",
]
[[package]]
name = "hyper-rustls"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c"
dependencies = [
"futures-util",
"http",
"hyper",
"hyper-util",
"rustls",
"rustls-pki-types",
"tokio",
"tokio-rustls",
"tower-service",
]
[[package]]
name = "hyper-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http",
"http-body",
"hyper",
"pin-project-lite",
"socket2",
"tokio",
"tower",
"tower-service",
"tracing",
]
[[package]] [[package]]
name = "iana-time-zone" name = "iana-time-zone"
version = "0.1.60" version = "0.1.60"
@ -1004,6 +1209,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "ipnet"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.12.1" version = "0.12.1"
@ -1175,6 +1386,12 @@ version = "2.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
[[package]]
name = "mime"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]] [[package]]
name = "minimal-lexical" name = "minimal-lexical"
version = "0.2.1" version = "0.2.1"
@ -1373,6 +1590,36 @@ dependencies = [
"pkg-config", "pkg-config",
] ]
[[package]]
name = "opendal"
version = "0.47.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c3ba698f2258bebdf7a3a38862bb6ef1f96d351627002686dacc228f805bdd6"
dependencies = [
"anyhow",
"async-trait",
"backon",
"base64 0.22.1",
"bytes",
"chrono",
"crc32c",
"flagset",
"futures",
"getrandom",
"http",
"log",
"md-5",
"once_cell",
"percent-encoding",
"quick-xml",
"reqsign",
"reqwest",
"serde",
"serde_json",
"tokio",
"uuid",
]
[[package]] [[package]]
name = "option-ext" name = "option-ext"
version = "0.2.0" version = "0.2.0"
@ -1388,6 +1635,16 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "ordered-multimap"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79"
dependencies = [
"dlv-list",
"hashbrown",
]
[[package]] [[package]]
name = "overload" name = "overload"
version = "0.1.1" version = "0.1.1"
@ -1435,6 +1692,26 @@ version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pin-project"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
]
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.14" version = "0.2.14"
@ -1486,6 +1763,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]] [[package]]
name = "proc-macro-error" name = "proc-macro-error"
version = "1.0.4" version = "1.0.4"
@ -1535,6 +1818,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33"
dependencies = [ dependencies = [
"memchr", "memchr",
"serde",
] ]
[[package]] [[package]]
@ -1546,6 +1830,36 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]] [[package]]
name = "ratatui" name = "ratatui"
version = "0.26.3" version = "0.26.3"
@ -1644,6 +1958,103 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
[[package]]
name = "reqsign"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70fe66d4cd0b5ed9b1abbfe639bf6baeaaf509f7da2d51b31111ba945be59286"
dependencies = [
"anyhow",
"async-trait",
"base64 0.22.1",
"chrono",
"form_urlencoded",
"getrandom",
"hex",
"hmac",
"home",
"http",
"log",
"percent-encoding",
"quick-xml",
"rand",
"reqwest",
"rust-ini",
"serde",
"serde_json",
"sha1",
"sha2",
]
[[package]]
name = "reqwest"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10"
dependencies = [
"base64 0.22.1",
"bytes",
"futures-core",
"futures-util",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-rustls",
"hyper-util",
"ipnet",
"js-sys",
"log",
"mime",
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls",
"rustls-pemfile",
"rustls-pki-types",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"tokio",
"tokio-rustls",
"tokio-util",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
"webpki-roots",
"winreg",
]
[[package]]
name = "ring"
version = "0.17.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
dependencies = [
"cc",
"cfg-if",
"getrandom",
"libc",
"spin",
"untrusted",
"windows-sys 0.52.0",
]
[[package]]
name = "rust-ini"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d625ed57d8f49af6cfa514c42e1a71fadcff60eb0b1c517ff82fe41aa025b41"
dependencies = [
"cfg-if",
"ordered-multimap",
"trim-in-place",
]
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.23" version = "0.1.23"
@ -1656,6 +2067,15 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.34" version = "0.38.34"
@ -1669,6 +2089,47 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "rustls"
version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432"
dependencies = [
"log",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-pemfile"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d"
dependencies = [
"base64 0.22.1",
"rustls-pki-types",
]
[[package]]
name = "rustls-pki-types"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
[[package]]
name = "rustls-webpki"
version = "0.102.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]] [[package]]
name = "rustversion" name = "rustversion"
version = "1.0.15" version = "1.0.15"
@ -1696,6 +2157,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "semver"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.203" version = "1.0.203"
@ -1746,6 +2213,40 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
"form_urlencoded",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sha1"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "sha2"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]] [[package]]
name = "sharded-slab" name = "sharded-slab"
version = "0.1.7" version = "0.1.7"
@ -1899,6 +2400,12 @@ dependencies = [
"syn 2.0.66", "syn 2.0.66",
] ]
[[package]]
name = "subtle"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.109" version = "1.0.109"
@ -1920,6 +2427,12 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "sync_wrapper"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]] [[package]]
name = "syntect" name = "syntect"
version = "5.2.0" version = "5.2.0"
@ -2035,6 +2548,15 @@ dependencies = [
"time-core", "time-core",
] ]
[[package]]
name = "tiny-keccak"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
dependencies = [
"crunchy",
]
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.6.0" version = "1.6.0"
@ -2080,6 +2602,17 @@ dependencies = [
"syn 2.0.66", "syn 2.0.66",
] ]
[[package]]
name = "tokio-rustls"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
dependencies = [
"rustls",
"rustls-pki-types",
"tokio",
]
[[package]] [[package]]
name = "tokio-stream" name = "tokio-stream"
version = "0.1.15" version = "0.1.15"
@ -2139,6 +2672,33 @@ dependencies = [
"winnow", "winnow",
] ]
[[package]]
name = "tower"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
dependencies = [
"futures-core",
"futures-util",
"pin-project",
"pin-project-lite",
"tokio",
"tower-layer",
"tower-service",
]
[[package]]
name = "tower-layer"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
[[package]]
name = "tower-service"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]] [[package]]
name = "tracing" name = "tracing"
version = "0.1.40" version = "0.1.40"
@ -2224,6 +2784,18 @@ dependencies = [
"windows", "windows",
] ]
[[package]]
name = "trim-in-place"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc"
[[package]]
name = "try-lock"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.17.0" version = "1.17.0"
@ -2273,6 +2845,12 @@ version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]] [[package]]
name = "url" name = "url"
version = "2.5.0" version = "2.5.0"
@ -2290,6 +2868,16 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "uuid"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
dependencies = [
"getrandom",
"serde",
]
[[package]] [[package]]
name = "uzers" name = "uzers"
version = "0.12.0" version = "0.12.0"
@ -2364,6 +2952,15 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "want"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
dependencies = [
"try-lock",
]
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.0+wasi-snapshot-preview1" version = "0.11.0+wasi-snapshot-preview1"
@ -2395,6 +2992,18 @@ dependencies = [
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0"
dependencies = [
"cfg-if",
"js-sys",
"wasm-bindgen",
"web-sys",
]
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.92" version = "0.2.92"
@ -2424,6 +3033,38 @@ version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
[[package]]
name = "wasm-streams"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129"
dependencies = [
"futures-util",
"js-sys",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]]
name = "web-sys"
version = "0.3.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "webpki-roots"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c452ad30530b54a4d8e71952716a212b08efd0f3562baa66c29a618b07da7c3"
dependencies = [
"rustls-pki-types",
]
[[package]] [[package]]
name = "weezl" name = "weezl"
version = "0.1.8" version = "0.1.8"
@ -2683,6 +3324,16 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "winreg"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
dependencies = [
"cfg-if",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "winsafe" name = "winsafe"
version = "0.0.19" version = "0.0.19"
@ -2756,6 +3407,7 @@ dependencies = [
"crossterm", "crossterm",
"globset", "globset",
"indexmap", "indexmap",
"opendal",
"ratatui", "ratatui",
"serde", "serde",
"shell-words", "shell-words",
@ -2927,6 +3579,7 @@ dependencies = [
"filetime", "filetime",
"futures", "futures",
"libc", "libc",
"opendal",
"parking_lot", "parking_lot",
"percent-encoding", "percent-encoding",
"ratatui", "ratatui",
@ -2957,6 +3610,12 @@ dependencies = [
"syn 2.0.66", "syn 2.0.66",
] ]
[[package]]
name = "zeroize"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
[[package]] [[package]]
name = "zune-inflate" name = "zune-inflate"
version = "0.2.54" version = "0.2.54"

View file

@ -28,4 +28,7 @@ scopeguard = "1.2.0"
tokio = { version = "1.38.0", features = ["full"] } tokio = { version = "1.38.0", features = ["full"] }
# Logging # Logging
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] } tracing = { version = "0.1.40", features = [
"max_level_debug",
"release_max_level_warn",
] }

View file

@ -23,3 +23,4 @@ serde = { version = "1.0.203", features = [ "derive" ] }
shell-words = "1.1.0" shell-words = "1.1.0"
toml = { version = "0.8.14", features = [ "preserve_order" ] } toml = { version = "0.8.14", features = [ "preserve_order" ] }
validator = { version = "0.18.1", features = [ "derive" ] } validator = { version = "0.18.1", features = [ "derive" ] }
opendal = "0.47.0"

View file

@ -5,304 +5,756 @@
[manager] [manager]
keymap = [ keymap = [
{ on = [ "<Esc>" ], run = "escape", desc = "Exit visual mode, clear selected, or cancel search" }, { on = [
{ on = [ "<C-[>" ], run = "escape", desc = "Exit visual mode, clear selected, or cancel search" }, "<Esc>",
{ on = [ "q" ], run = "quit", desc = "Exit the process" }, ], run = "escape", desc = "Exit visual mode, clear selected, or cancel search" },
{ on = [ "Q" ], run = "quit --no-cwd-file", desc = "Exit the process without writing cwd-file" }, { on = [
{ on = [ "<C-c>" ], run = "close", desc = "Close the current tab, or quit if it is last tab" }, "<C-[>",
{ on = [ "<C-z>" ], run = "suspend", desc = "Suspend the process" }, ], run = "escape", desc = "Exit visual mode, clear selected, or cancel search" },
{ on = [
"q",
], run = "quit", desc = "Exit the process" },
{ on = [
"Q",
], run = "quit --no-cwd-file", desc = "Exit the process without writing cwd-file" },
{ on = [
"<C-c>",
], run = "close", desc = "Close the current tab, or quit if it is last tab" },
{ on = [
"<C-z>",
], run = "suspend", desc = "Suspend the process" },
# Navigation # Navigation
{ on = [ "k" ], run = "arrow -1", desc = "Move cursor up" }, { on = [
{ on = [ "j" ], run = "arrow 1", desc = "Move cursor down" }, "k",
], run = "arrow -1", desc = "Move cursor up" },
{ on = [
"j",
], run = "arrow 1", desc = "Move cursor down" },
{ on = [ "K" ], run = "arrow -5", desc = "Move cursor up 5 lines" }, { on = [
{ on = [ "J" ], run = "arrow 5", desc = "Move cursor down 5 lines" }, "K",
], run = "arrow -5", desc = "Move cursor up 5 lines" },
{ on = [
"J",
], run = "arrow 5", desc = "Move cursor down 5 lines" },
{ on = [ "<S-Up>" ], run = "arrow -5", desc = "Move cursor up 5 lines" }, { on = [
{ on = [ "<S-Down>" ], run = "arrow 5", desc = "Move cursor down 5 lines" }, "<S-Up>",
], run = "arrow -5", desc = "Move cursor up 5 lines" },
{ on = [
"<S-Down>",
], run = "arrow 5", desc = "Move cursor down 5 lines" },
{ on = [ "<C-u>" ], run = "arrow -50%", desc = "Move cursor up half page" }, { on = [
{ on = [ "<C-d>" ], run = "arrow 50%", desc = "Move cursor down half page" }, "<C-u>",
{ on = [ "<C-b>" ], run = "arrow -100%", desc = "Move cursor up one page" }, ], run = "arrow -50%", desc = "Move cursor up half page" },
{ on = [ "<C-f>" ], run = "arrow 100%", desc = "Move cursor down one page" }, { on = [
"<C-d>",
], run = "arrow 50%", desc = "Move cursor down half page" },
{ on = [
"<C-b>",
], run = "arrow -100%", desc = "Move cursor up one page" },
{ on = [
"<C-f>",
], run = "arrow 100%", desc = "Move cursor down one page" },
{ on = [ "<C-PageUp>" ], run = "arrow -50%", desc = "Move cursor up half page" }, { on = [
{ on = [ "<C-PageDown>" ], run = "arrow 50%", desc = "Move cursor down half page" }, "<C-PageUp>",
{ on = [ "<PageUp>" ], run = "arrow -100%", desc = "Move cursor up one page" }, ], run = "arrow -50%", desc = "Move cursor up half page" },
{ on = [ "<PageDown>" ], run = "arrow 100%", desc = "Move cursor down one page" }, { on = [
"<C-PageDown>",
], run = "arrow 50%", desc = "Move cursor down half page" },
{ on = [
"<PageUp>",
], run = "arrow -100%", desc = "Move cursor up one page" },
{ on = [
"<PageDown>",
], run = "arrow 100%", desc = "Move cursor down one page" },
{ on = [ "h" ], run = "leave", desc = "Go back to the parent directory" }, { on = [
{ on = [ "l" ], run = "enter", desc = "Enter the child directory" }, "h",
], run = "leave", desc = "Go back to the parent directory" },
{ on = [
"l",
], run = "enter", desc = "Enter the child directory" },
{ on = [ "H" ], run = "back", desc = "Go back to the previous directory" }, { on = [
{ on = [ "L" ], run = "forward", desc = "Go forward to the next directory" }, "H",
], run = "back", desc = "Go back to the previous directory" },
{ on = [
"L",
], run = "forward", desc = "Go forward to the next directory" },
{ on = [ "<A-k>" ], run = "seek -5", desc = "Seek up 5 units in the preview" }, { on = [
{ on = [ "<A-j>" ], run = "seek 5", desc = "Seek down 5 units in the preview" }, "<A-k>",
{ on = [ "<A-PageUp>" ], run = "seek -5", desc = "Seek up 5 units in the preview" }, ], run = "seek -5", desc = "Seek up 5 units in the preview" },
{ on = [ "<A-PageDown>" ], run = "seek 5", desc = "Seek down 5 units in the preview" }, { on = [
"<A-j>",
], run = "seek 5", desc = "Seek down 5 units in the preview" },
{ on = [
"<A-PageUp>",
], run = "seek -5", desc = "Seek up 5 units in the preview" },
{ on = [
"<A-PageDown>",
], run = "seek 5", desc = "Seek down 5 units in the preview" },
{ on = [ "<Up>" ], run = "arrow -1", desc = "Move cursor up" }, { on = [
{ on = [ "<Down>" ], run = "arrow 1", desc = "Move cursor down" }, "<Up>",
{ on = [ "<Left>" ], run = "leave", desc = "Go back to the parent directory" }, ], run = "arrow -1", desc = "Move cursor up" },
{ on = [ "<Right>" ], run = "enter", desc = "Enter the child directory" }, { on = [
"<Down>",
], run = "arrow 1", desc = "Move cursor down" },
{ on = [
"<Left>",
], run = "leave", desc = "Go back to the parent directory" },
{ on = [
"<Right>",
], run = "enter", desc = "Enter the child directory" },
{ on = [ "g", "g" ], run = "arrow -99999999", desc = "Move cursor to the top" }, { on = [
{ on = [ "G" ], run = "arrow 99999999", desc = "Move cursor to the bottom" }, "g",
"g",
], run = "arrow -99999999", desc = "Move cursor to the top" },
{ on = [
"G",
], run = "arrow 99999999", desc = "Move cursor to the bottom" },
# Selection # Selection
{ on = [ "<Space>" ], run = [ "select --state=none", "arrow 1" ], desc = "Toggle the current selection state" }, { on = [
{ on = [ "v" ], run = "visual_mode", desc = "Enter visual mode (selection mode)" }, "<Space>",
{ on = [ "V" ], run = "visual_mode --unset", desc = "Enter visual mode (unset mode)" }, ], run = [
{ on = [ "<C-a>" ], run = "select_all --state=true", desc = "Select all files" }, "select --state=none",
{ on = [ "<C-r>" ], run = "select_all --state=none", desc = "Inverse selection of all files" }, "arrow 1",
], desc = "Toggle the current selection state" },
{ on = [
"v",
], run = "visual_mode", desc = "Enter visual mode (selection mode)" },
{ on = [
"V",
], run = "visual_mode --unset", desc = "Enter visual mode (unset mode)" },
{ on = [
"<C-a>",
], run = "select_all --state=true", desc = "Select all files" },
{ on = [
"<C-r>",
], run = "select_all --state=none", desc = "Inverse selection of all files" },
# Operation # Operation
{ on = [ "o" ], run = "open", desc = "Open the selected files" }, { on = [
{ on = [ "O" ], run = "open --interactive", desc = "Open the selected files interactively" }, "o",
{ on = [ "<Enter>" ], run = "open", desc = "Open the selected files" }, ], run = "open", desc = "Open the selected files" },
{ on = [ "<S-Enter>" ], run = "open --interactive", desc = "Open the selected files interactively" }, { on = [
{ on = [ "y" ], run = "yank", desc = "Copy the selected files" }, "O",
{ on = [ "Y" ], run = "unyank", desc = "Cancel the yank status of files" }, ], run = "open --interactive", desc = "Open the selected files interactively" },
{ on = [ "x" ], run = "yank --cut", desc = "Cut the selected files" }, { on = [
{ on = [ "X" ], run = "unyank", desc = "Cancel the yank status of files" }, "<Enter>",
{ on = [ "p" ], run = "paste", desc = "Paste the files" }, ], run = "open", desc = "Open the selected files" },
{ on = [ "P" ], run = "paste --force", desc = "Paste the files (overwrite if the destination exists)" }, { on = [
{ on = [ "-" ], run = "link", desc = "Symlink the absolute path of files" }, "<S-Enter>",
{ on = [ "_" ], run = "link --relative", desc = "Symlink the relative path of files" }, ], run = "open --interactive", desc = "Open the selected files interactively" },
{ on = [ "d" ], run = "remove", desc = "Move the files to the trash" }, { on = [
{ on = [ "D" ], run = "remove --permanently", desc = "Permanently delete the files" }, "y",
{ on = [ "a" ], run = "create", desc = "Create a file or directory (ends with / for directories)" }, ], run = "yank", desc = "Copy the selected files" },
{ on = [ "r" ], run = "rename --cursor=before_ext", desc = "Rename a file or directory" }, { on = [
{ on = [ ";" ], run = "shell", desc = "Run a shell command" }, "Y",
{ on = [ ":" ], run = "shell --block", desc = "Run a shell command (block the UI until the command finishes)" }, ], run = "unyank", desc = "Cancel the yank status of files" },
{ on = [ "." ], run = "hidden toggle", desc = "Toggle the visibility of hidden files" }, { on = [
{ on = [ "s" ], run = "search fd", desc = "Search files by name using fd" }, "x",
{ on = [ "S" ], run = "search rg", desc = "Search files by content using ripgrep" }, ], run = "yank --cut", desc = "Cut the selected files" },
{ on = [ "<C-s>" ], run = "search none", desc = "Cancel the ongoing search" }, { on = [
{ on = [ "z" ], run = "plugin zoxide", desc = "Jump to a directory using zoxide" }, "X",
{ on = [ "Z" ], run = "plugin fzf", desc = "Jump to a directory, or reveal a file using fzf" }, ], run = "unyank", desc = "Cancel the yank status of files" },
{ on = [
"p",
], run = "paste", desc = "Paste the files" },
{ on = [
"P",
], run = "paste --force", desc = "Paste the files (overwrite if the destination exists)" },
{ on = [
"-",
], run = "link", desc = "Symlink the absolute path of files" },
{ on = [
"_",
], run = "link --relative", desc = "Symlink the relative path of files" },
{ on = [
"d",
], run = "remove", desc = "Move the files to the trash" },
{ on = [
"D",
], run = "remove --permanently", desc = "Permanently delete the files" },
{ on = [
"a",
], run = "create", desc = "Create a file or directory (ends with / for directories)" },
{ on = [
"r",
], run = "rename --cursor=before_ext", desc = "Rename a file or directory" },
{ on = [
";",
], run = "shell", desc = "Run a shell command" },
{ on = [
":",
], run = "shell --block", desc = "Run a shell command (block the UI until the command finishes)" },
{ on = [
".",
], run = "hidden toggle", desc = "Toggle the visibility of hidden files" },
{ on = [
"s",
], run = "search fd", desc = "Search files by name using fd" },
{ on = [
"S",
], run = "search rg", desc = "Search files by content using ripgrep" },
{ on = [
"<C-s>",
], run = "search none", desc = "Cancel the ongoing search" },
{ on = [
"z",
], run = "plugin zoxide", desc = "Jump to a directory using zoxide" },
{ on = [
"Z",
], run = "plugin fzf", desc = "Jump to a directory, or reveal a file using fzf" },
# Linemode # Linemode
{ on = [ "m", "s" ], run = "linemode size", desc = "Set linemode to size" }, { on = [
{ on = [ "m", "p" ], run = "linemode permissions", desc = "Set linemode to permissions" }, "m",
{ on = [ "m", "m" ], run = "linemode mtime", desc = "Set linemode to mtime" }, "s",
{ on = [ "m", "n" ], run = "linemode none", desc = "Set linemode to none" }, ], run = "linemode size", desc = "Set linemode to size" },
{ on = [
"m",
"p",
], run = "linemode permissions", desc = "Set linemode to permissions" },
{ on = [
"m",
"m",
], run = "linemode mtime", desc = "Set linemode to mtime" },
{ on = [
"m",
"n",
], run = "linemode none", desc = "Set linemode to none" },
# Copy # Copy
{ on = [ "c", "c" ], run = "copy path", desc = "Copy the absolute path" }, { on = [
{ on = [ "c", "d" ], run = "copy dirname", desc = "Copy the path of the parent directory" }, "c",
{ on = [ "c", "f" ], run = "copy filename", desc = "Copy the name of the file" }, "c",
{ on = [ "c", "n" ], run = "copy name_without_ext", desc = "Copy the name of the file without the extension" }, ], run = "copy path", desc = "Copy the absolute path" },
{ on = [
"c",
"d",
], run = "copy dirname", desc = "Copy the path of the parent directory" },
{ on = [
"c",
"f",
], run = "copy filename", desc = "Copy the name of the file" },
{ on = [
"c",
"n",
], run = "copy name_without_ext", desc = "Copy the name of the file without the extension" },
# Filter # Filter
{ on = [ "f" ], run = "filter --smart", desc = "Filter the files" }, { on = [
"f",
], run = "filter --smart", desc = "Filter the files" },
# Find # Find
{ on = [ "/" ], run = "find --smart", desc = "Find next file" }, { on = [
{ on = [ "?" ], run = "find --previous --smart", desc = "Find previous file" }, "/",
{ on = [ "n" ], run = "find_arrow", desc = "Go to next found file" }, ], run = "find --smart", desc = "Find next file" },
{ on = [ "N" ], run = "find_arrow --previous", desc = "Go to previous found file" }, { on = [
"?",
], run = "find --previous --smart", desc = "Find previous file" },
{ on = [
"n",
], run = "find_arrow", desc = "Go to next found file" },
{ on = [
"N",
], run = "find_arrow --previous", desc = "Go to previous found file" },
# Sorting # Sorting
{ on = [ ",", "m" ], run = "sort modified --reverse=no", desc = "Sort by modified time" }, { on = [
{ on = [ ",", "M" ], run = "sort modified --reverse", desc = "Sort by modified time (reverse)" }, ",",
{ on = [ ",", "c" ], run = "sort created --reverse=no", desc = "Sort by created time" }, "m",
{ on = [ ",", "C" ], run = "sort created --reverse", desc = "Sort by created time (reverse)" }, ], run = "sort modified --reverse=no", desc = "Sort by modified time" },
{ on = [ ",", "e" ], run = "sort extension --reverse=no", desc = "Sort by extension" }, { on = [
{ on = [ ",", "E" ], run = "sort extension --reverse", desc = "Sort by extension (reverse)" }, ",",
{ on = [ ",", "a" ], run = "sort alphabetical --reverse=no", desc = "Sort alphabetically" }, "M",
{ on = [ ",", "A" ], run = "sort alphabetical --reverse", desc = "Sort alphabetically (reverse)" }, ], run = "sort modified --reverse", desc = "Sort by modified time (reverse)" },
{ on = [ ",", "n" ], run = "sort natural --reverse=no", desc = "Sort naturally" }, { on = [
{ on = [ ",", "N" ], run = "sort natural --reverse", desc = "Sort naturally (reverse)" }, ",",
{ on = [ ",", "s" ], run = "sort size --reverse=no", desc = "Sort by size" }, "c",
{ on = [ ",", "S" ], run = "sort size --reverse", desc = "Sort by size (reverse)" }, ], run = "sort created --reverse=no", desc = "Sort by created time" },
{ on = [
",",
"C",
], run = "sort created --reverse", desc = "Sort by created time (reverse)" },
{ on = [
",",
"e",
], run = "sort extension --reverse=no", desc = "Sort by extension" },
{ on = [
",",
"E",
], run = "sort extension --reverse", desc = "Sort by extension (reverse)" },
{ on = [
",",
"a",
], run = "sort alphabetical --reverse=no", desc = "Sort alphabetically" },
{ on = [
",",
"A",
], run = "sort alphabetical --reverse", desc = "Sort alphabetically (reverse)" },
{ on = [
",",
"n",
], run = "sort natural --reverse=no", desc = "Sort naturally" },
{ on = [
",",
"N",
], run = "sort natural --reverse", desc = "Sort naturally (reverse)" },
{ on = [
",",
"s",
], run = "sort size --reverse=no", desc = "Sort by size" },
{ on = [
",",
"S",
], run = "sort size --reverse", desc = "Sort by size (reverse)" },
# Tabs # Tabs
{ on = [ "t" ], run = "tab_create --current", desc = "Create a new tab using the current path" }, { on = [
"t",
], run = "tab_create --current", desc = "Create a new tab using the current path" },
{ on = [ "1" ], run = "tab_switch 0", desc = "Switch to the first tab" }, { on = [
{ on = [ "2" ], run = "tab_switch 1", desc = "Switch to the second tab" }, "1",
{ on = [ "3" ], run = "tab_switch 2", desc = "Switch to the third tab" }, ], run = "tab_switch 0", desc = "Switch to the first tab" },
{ on = [ "4" ], run = "tab_switch 3", desc = "Switch to the fourth tab" }, { on = [
{ on = [ "5" ], run = "tab_switch 4", desc = "Switch to the fifth tab" }, "2",
{ on = [ "6" ], run = "tab_switch 5", desc = "Switch to the sixth tab" }, ], run = "tab_switch 1", desc = "Switch to the second tab" },
{ on = [ "7" ], run = "tab_switch 6", desc = "Switch to the seventh tab" }, { on = [
{ on = [ "8" ], run = "tab_switch 7", desc = "Switch to the eighth tab" }, "3",
{ on = [ "9" ], run = "tab_switch 8", desc = "Switch to the ninth tab" }, ], run = "tab_switch 2", desc = "Switch to the third tab" },
{ on = [
"4",
], run = "tab_switch 3", desc = "Switch to the fourth tab" },
{ on = [
"5",
], run = "tab_switch 4", desc = "Switch to the fifth tab" },
{ on = [
"6",
], run = "tab_switch 5", desc = "Switch to the sixth tab" },
{ on = [
"7",
], run = "tab_switch 6", desc = "Switch to the seventh tab" },
{ on = [
"8",
], run = "tab_switch 7", desc = "Switch to the eighth tab" },
{ on = [
"9",
], run = "tab_switch 8", desc = "Switch to the ninth tab" },
{ on = [ "[" ], run = "tab_switch -1 --relative", desc = "Switch to the previous tab" }, { on = [
{ on = [ "]" ], run = "tab_switch 1 --relative", desc = "Switch to the next tab" }, "[",
], run = "tab_switch -1 --relative", desc = "Switch to the previous tab" },
{ on = [
"]",
], run = "tab_switch 1 --relative", desc = "Switch to the next tab" },
{ on = [ "{" ], run = "tab_swap -1", desc = "Swap the current tab with the previous tab" }, { on = [
{ on = [ "}" ], run = "tab_swap 1", desc = "Swap the current tab with the next tab" }, "{",
], run = "tab_swap -1", desc = "Swap the current tab with the previous tab" },
{ on = [
"}",
], run = "tab_swap 1", desc = "Swap the current tab with the next tab" },
# Tasks # Tasks
{ on = [ "w" ], run = "tasks_show", desc = "Show the tasks manager" }, { on = [
"w",
], run = "tasks_show", desc = "Show the tasks manager" },
# Goto # Goto
{ on = [ "g", "h" ], run = "cd ~", desc = "Go to the home directory" }, { on = [
{ on = [ "g", "c" ], run = "cd ~/.config", desc = "Go to the config directory" }, "g",
{ on = [ "g", "d" ], run = "cd ~/Downloads", desc = "Go to the downloads directory" }, "h",
{ on = [ "g", "<Space>" ], run = "cd --interactive", desc = "Go to a directory interactively" }, ], run = "cd ~", desc = "Go to the home directory" },
{ on = [
"g",
"c",
], run = "cd ~/.config", desc = "Go to the config directory" },
{ on = [
"g",
"d",
], run = "cd ~/Downloads", desc = "Go to the downloads directory" },
{ on = [
"g",
"<Space>",
], run = "cd --interactive", desc = "Go to a directory interactively" },
# Help # Help
{ on = [ "~" ], run = "help", desc = "Open help" }, { on = [
"~",
], run = "help", desc = "Open help" },
] ]
[tasks] [tasks]
keymap = [ keymap = [
{ on = [ "<Esc>" ], run = "close", desc = "Hide the task manager" }, { on = [
{ on = [ "<C-[>" ], run = "close", desc = "Hide the task manager" }, "<Esc>",
{ on = [ "<C-c>" ], run = "close", desc = "Hide the task manager" }, ], run = "close", desc = "Hide the task manager" },
{ on = [ "w" ], run = "close", desc = "Hide the task manager" }, { on = [
"<C-[>",
], run = "close", desc = "Hide the task manager" },
{ on = [
"<C-c>",
], run = "close", desc = "Hide the task manager" },
{ on = [
"w",
], run = "close", desc = "Hide the task manager" },
{ on = [ "k" ], run = "arrow -1", desc = "Move cursor up" }, { on = [
{ on = [ "j" ], run = "arrow 1", desc = "Move cursor down" }, "k",
], run = "arrow -1", desc = "Move cursor up" },
{ on = [
"j",
], run = "arrow 1", desc = "Move cursor down" },
{ on = [ "<Up>" ], run = "arrow -1", desc = "Move cursor up" }, { on = [
{ on = [ "<Down>" ], run = "arrow 1", desc = "Move cursor down" }, "<Up>",
], run = "arrow -1", desc = "Move cursor up" },
{ on = [
"<Down>",
], run = "arrow 1", desc = "Move cursor down" },
{ on = [ "<Enter>" ], run = "inspect", desc = "Inspect the task" }, { on = [
{ on = [ "x" ], run = "cancel", desc = "Cancel the task" }, "<Enter>",
], run = "inspect", desc = "Inspect the task" },
{ on = [
"x",
], run = "cancel", desc = "Cancel the task" },
{ on = [ "~" ], run = "help", desc = "Open help" } { on = [
"~",
], run = "help", desc = "Open help" },
] ]
[select] [select]
keymap = [ keymap = [
{ on = [ "<Esc>" ], run = "close", desc = "Cancel selection" }, { on = [
{ on = [ "<C-[>" ], run = "close", desc = "Cancel selection" }, "<Esc>",
{ on = [ "<C-c>" ], run = "close", desc = "Cancel selection" }, ], run = "close", desc = "Cancel selection" },
{ on = [ "<Enter>" ], run = "close --submit", desc = "Submit the selection" }, { on = [
"<C-[>",
], run = "close", desc = "Cancel selection" },
{ on = [
"<C-c>",
], run = "close", desc = "Cancel selection" },
{ on = [
"<Enter>",
], run = "close --submit", desc = "Submit the selection" },
{ on = [ "k" ], run = "arrow -1", desc = "Move cursor up" }, { on = [
{ on = [ "j" ], run = "arrow 1", desc = "Move cursor down" }, "k",
], run = "arrow -1", desc = "Move cursor up" },
{ on = [
"j",
], run = "arrow 1", desc = "Move cursor down" },
{ on = [ "K" ], run = "arrow -5", desc = "Move cursor up 5 lines" }, { on = [
{ on = [ "J" ], run = "arrow 5", desc = "Move cursor down 5 lines" }, "K",
], run = "arrow -5", desc = "Move cursor up 5 lines" },
{ on = [
"J",
], run = "arrow 5", desc = "Move cursor down 5 lines" },
{ on = [ "<Up>" ], run = "arrow -1", desc = "Move cursor up" }, { on = [
{ on = [ "<Down>" ], run = "arrow 1", desc = "Move cursor down" }, "<Up>",
], run = "arrow -1", desc = "Move cursor up" },
{ on = [
"<Down>",
], run = "arrow 1", desc = "Move cursor down" },
{ on = [ "<S-Up>" ], run = "arrow -5", desc = "Move cursor up 5 lines" }, { on = [
{ on = [ "<S-Down>" ], run = "arrow 5", desc = "Move cursor down 5 lines" }, "<S-Up>",
], run = "arrow -5", desc = "Move cursor up 5 lines" },
{ on = [
"<S-Down>",
], run = "arrow 5", desc = "Move cursor down 5 lines" },
{ on = [ "~" ], run = "help", desc = "Open help" } { on = [
"~",
], run = "help", desc = "Open help" },
] ]
[input] [input]
keymap = [ keymap = [
{ on = [ "<C-c>" ], run = "close", desc = "Cancel input" }, { on = [
{ on = [ "<Enter>" ], run = "close --submit", desc = "Submit the input" }, "<C-c>",
{ on = [ "<Esc>" ], run = "escape", desc = "Go back the normal mode, or cancel input" }, ], run = "close", desc = "Cancel input" },
{ on = [ "<C-[>" ], run = "escape", desc = "Go back the normal mode, or cancel input" }, { on = [
"<Enter>",
], run = "close --submit", desc = "Submit the input" },
{ on = [
"<Esc>",
], run = "escape", desc = "Go back the normal mode, or cancel input" },
{ on = [
"<C-[>",
], run = "escape", desc = "Go back the normal mode, or cancel input" },
# Mode # Mode
{ on = [ "i" ], run = "insert", desc = "Enter insert mode" }, { on = [
{ on = [ "a" ], run = "insert --append", desc = "Enter append mode" }, "i",
{ on = [ "I" ], run = [ "move -999", "insert" ], desc = "Move to the BOL, and enter insert mode" }, ], run = "insert", desc = "Enter insert mode" },
{ on = [ "A" ], run = [ "move 999", "insert --append" ], desc = "Move to the EOL, and enter append mode" }, { on = [
{ on = [ "v" ], run = "visual", desc = "Enter visual mode" }, "a",
{ on = [ "V" ], run = [ "move -999", "visual", "move 999" ], desc = "Enter visual mode and select all" }, ], run = "insert --append", desc = "Enter append mode" },
{ on = [
"I",
], run = [
"move -999",
"insert",
], desc = "Move to the BOL, and enter insert mode" },
{ on = [
"A",
], run = [
"move 999",
"insert --append",
], desc = "Move to the EOL, and enter append mode" },
{ on = [
"v",
], run = "visual", desc = "Enter visual mode" },
{ on = [
"V",
], run = [
"move -999",
"visual",
"move 999",
], desc = "Enter visual mode and select all" },
# Character-wise movement # Character-wise movement
{ on = [ "h" ], run = "move -1", desc = "Move back a character" }, { on = [
{ on = [ "l" ], run = "move 1", desc = "Move forward a character" }, "h",
{ on = [ "<Left>" ], run = "move -1", desc = "Move back a character" }, ], run = "move -1", desc = "Move back a character" },
{ on = [ "<Right>" ], run = "move 1", desc = "Move forward a character" }, { on = [
{ on = [ "<C-b>" ], run = "move -1", desc = "Move back a character" }, "l",
{ on = [ "<C-f>" ], run = "move 1", desc = "Move forward a character" }, ], run = "move 1", desc = "Move forward a character" },
{ on = [
"<Left>",
], run = "move -1", desc = "Move back a character" },
{ on = [
"<Right>",
], run = "move 1", desc = "Move forward a character" },
{ on = [
"<C-b>",
], run = "move -1", desc = "Move back a character" },
{ on = [
"<C-f>",
], run = "move 1", desc = "Move forward a character" },
# Word-wise movement # Word-wise movement
{ on = [ "b" ], run = "backward", desc = "Move back to the start of the current or previous word" }, { on = [
{ on = [ "w" ], run = "forward", desc = "Move forward to the start of the next word" }, "b",
{ on = [ "e" ], run = "forward --end-of-word", desc = "Move forward to the end of the current or next word" }, ], run = "backward", desc = "Move back to the start of the current or previous word" },
{ on = [ "<A-b>" ], run = "backward", desc = "Move back to the start of the current or previous word" }, { on = [
{ on = [ "<A-f>" ], run = "forward --end-of-word", desc = "Move forward to the end of the current or next word" }, "w",
], run = "forward", desc = "Move forward to the start of the next word" },
{ on = [
"e",
], run = "forward --end-of-word", desc = "Move forward to the end of the current or next word" },
{ on = [
"<A-b>",
], run = "backward", desc = "Move back to the start of the current or previous word" },
{ on = [
"<A-f>",
], run = "forward --end-of-word", desc = "Move forward to the end of the current or next word" },
# Line-wise movement # Line-wise movement
{ on = [ "0" ], run = "move -999", desc = "Move to the BOL" }, { on = [
{ on = [ "$" ], run = "move 999", desc = "Move to the EOL" }, "0",
{ on = [ "<C-a>" ], run = "move -999", desc = "Move to the BOL" }, ], run = "move -999", desc = "Move to the BOL" },
{ on = [ "<C-e>" ], run = "move 999", desc = "Move to the EOL" }, { on = [
{ on = [ "<Home>" ], run = "move -999", desc = "Move to the BOL" }, "$",
{ on = [ "<End>" ], run = "move 999", desc = "Move to the EOL" }, ], run = "move 999", desc = "Move to the EOL" },
{ on = [
"<C-a>",
], run = "move -999", desc = "Move to the BOL" },
{ on = [
"<C-e>",
], run = "move 999", desc = "Move to the EOL" },
{ on = [
"<Home>",
], run = "move -999", desc = "Move to the BOL" },
{ on = [
"<End>",
], run = "move 999", desc = "Move to the EOL" },
# Delete # Delete
{ on = [ "<Backspace>" ], run = "backspace", desc = "Delete the character before the cursor" }, { on = [
{ on = [ "<Delete>" ], run = "backspace --under", desc = "Delete the character under the cursor" }, "<Backspace>",
{ on = [ "<C-h>" ], run = "backspace", desc = "Delete the character before the cursor" }, ], run = "backspace", desc = "Delete the character before the cursor" },
{ on = [ "<C-d>" ], run = "backspace --under", desc = "Delete the character under the cursor" }, { on = [
"<Delete>",
], run = "backspace --under", desc = "Delete the character under the cursor" },
{ on = [
"<C-h>",
], run = "backspace", desc = "Delete the character before the cursor" },
{ on = [
"<C-d>",
], run = "backspace --under", desc = "Delete the character under the cursor" },
# Kill # Kill
{ on = [ "<C-u>" ], run = "kill bol", desc = "Kill backwards to the BOL" }, { on = [
{ on = [ "<C-k>" ], run = "kill eol", desc = "Kill forwards to the EOL" }, "<C-u>",
{ on = [ "<C-w>" ], run = "kill backward", desc = "Kill backwards to the start of the current word" }, ], run = "kill bol", desc = "Kill backwards to the BOL" },
{ on = [ "<A-d>" ], run = "kill forward", desc = "Kill forwards to the end of the current word" }, { on = [
"<C-k>",
], run = "kill eol", desc = "Kill forwards to the EOL" },
{ on = [
"<C-w>",
], run = "kill backward", desc = "Kill backwards to the start of the current word" },
{ on = [
"<A-d>",
], run = "kill forward", desc = "Kill forwards to the end of the current word" },
# Cut/Yank/Paste # Cut/Yank/Paste
{ on = [ "d" ], run = "delete --cut", desc = "Cut the selected characters" }, { on = [
{ on = [ "D" ], run = [ "delete --cut", "move 999" ], desc = "Cut until the EOL" }, "d",
{ on = [ "c" ], run = "delete --cut --insert", desc = "Cut the selected characters, and enter insert mode" }, ], run = "delete --cut", desc = "Cut the selected characters" },
{ on = [ "C" ], run = [ "delete --cut --insert", "move 999" ], desc = "Cut until the EOL, and enter insert mode" }, { on = [
{ on = [ "x" ], run = [ "delete --cut", "move 1 --in-operating" ], desc = "Cut the current character" }, "D",
{ on = [ "y" ], run = "yank", desc = "Copy the selected characters" }, ], run = [
{ on = [ "p" ], run = "paste", desc = "Paste the copied characters after the cursor" }, "delete --cut",
{ on = [ "P" ], run = "paste --before", desc = "Paste the copied characters before the cursor" }, "move 999",
], desc = "Cut until the EOL" },
{ on = [
"c",
], run = "delete --cut --insert", desc = "Cut the selected characters, and enter insert mode" },
{ on = [
"C",
], run = [
"delete --cut --insert",
"move 999",
], desc = "Cut until the EOL, and enter insert mode" },
{ on = [
"x",
], run = [
"delete --cut",
"move 1 --in-operating",
], desc = "Cut the current character" },
{ on = [
"y",
], run = "yank", desc = "Copy the selected characters" },
{ on = [
"p",
], run = "paste", desc = "Paste the copied characters after the cursor" },
{ on = [
"P",
], run = "paste --before", desc = "Paste the copied characters before the cursor" },
# Undo/Redo # Undo/Redo
{ on = [ "u" ], run = "undo", desc = "Undo the last operation" }, { on = [
{ on = [ "<C-r>" ], run = "redo", desc = "Redo the last operation" }, "u",
], run = "undo", desc = "Undo the last operation" },
{ on = [
"<C-r>",
], run = "redo", desc = "Redo the last operation" },
# Help # Help
{ on = [ "~" ], run = "help", desc = "Open help" } { on = [
"~",
], run = "help", desc = "Open help" },
] ]
[completion] [completion]
keymap = [ keymap = [
{ on = [ "<C-c>" ], run = "close", desc = "Cancel completion" }, { on = [
{ on = [ "<Tab>" ], run = "close --submit", desc = "Submit the completion" }, "<C-c>",
{ on = [ "<Enter>" ], run = [ "close --submit", "close_input --submit" ], desc = "Submit the completion and input" }, ], run = "close", desc = "Cancel completion" },
{ on = [
"<Tab>",
], run = "close --submit", desc = "Submit the completion" },
{ on = [
"<Enter>",
], run = [
"close --submit",
"close_input --submit",
], desc = "Submit the completion and input" },
{ on = [ "<A-k>" ], run = "arrow -1", desc = "Move cursor up" }, { on = [
{ on = [ "<A-j>" ], run = "arrow 1", desc = "Move cursor down" }, "<A-k>",
], run = "arrow -1", desc = "Move cursor up" },
{ on = [
"<A-j>",
], run = "arrow 1", desc = "Move cursor down" },
{ on = [ "<Up>" ], run = "arrow -1", desc = "Move cursor up" }, { on = [
{ on = [ "<Down>" ], run = "arrow 1", desc = "Move cursor down" }, "<Up>",
], run = "arrow -1", desc = "Move cursor up" },
{ on = [
"<Down>",
], run = "arrow 1", desc = "Move cursor down" },
{ on = [ "<C-p>" ], run = "arrow -1", desc = "Move cursor up" }, { on = [
{ on = [ "<C-n>" ], run = "arrow 1", desc = "Move cursor down" }, "<C-p>",
], run = "arrow -1", desc = "Move cursor up" },
{ on = [
"<C-n>",
], run = "arrow 1", desc = "Move cursor down" },
{ on = [ "~" ], run = "help", desc = "Open help" } { on = [
"~",
], run = "help", desc = "Open help" },
] ]
[help] [help]
keymap = [ keymap = [
{ on = [ "<Esc>" ], run = "escape", desc = "Clear the filter, or hide the help" }, { on = [
{ on = [ "<C-[>" ], run = "escape", desc = "Clear the filter, or hide the help" }, "<Esc>",
{ on = [ "q" ], run = "close", desc = "Exit the process" }, ], run = "escape", desc = "Clear the filter, or hide the help" },
{ on = [ "<C-c>" ], run = "close", desc = "Hide the help" }, { on = [
"<C-[>",
], run = "escape", desc = "Clear the filter, or hide the help" },
{ on = [
"q",
], run = "close", desc = "Exit the process" },
{ on = [
"<C-c>",
], run = "close", desc = "Hide the help" },
# Navigation # Navigation
{ on = [ "k" ], run = "arrow -1", desc = "Move cursor up" }, { on = [
{ on = [ "j" ], run = "arrow 1", desc = "Move cursor down" }, "k",
], run = "arrow -1", desc = "Move cursor up" },
{ on = [
"j",
], run = "arrow 1", desc = "Move cursor down" },
{ on = [ "K" ], run = "arrow -5", desc = "Move cursor up 5 lines" }, { on = [
{ on = [ "J" ], run = "arrow 5", desc = "Move cursor down 5 lines" }, "K",
], run = "arrow -5", desc = "Move cursor up 5 lines" },
{ on = [
"J",
], run = "arrow 5", desc = "Move cursor down 5 lines" },
{ on = [ "<Up>" ], run = "arrow -1", desc = "Move cursor up" }, { on = [
{ on = [ "<Down>" ], run = "arrow 1", desc = "Move cursor down" }, "<Up>",
], run = "arrow -1", desc = "Move cursor up" },
{ on = [
"<Down>",
], run = "arrow 1", desc = "Move cursor down" },
{ on = [ "<S-Up>" ], run = "arrow -5", desc = "Move cursor up 5 lines" }, { on = [
{ on = [ "<S-Down>" ], run = "arrow 5", desc = "Move cursor down 5 lines" }, "<S-Up>",
], run = "arrow -5", desc = "Move cursor up 5 lines" },
{ on = [
"<S-Down>",
], run = "arrow 5", desc = "Move cursor down 5 lines" },
# Filtering # Filtering
{ on = [ "/" ], run = "filter", desc = "Apply a filter for the help items" }, { on = [
"/",
], run = "filter", desc = "Apply a filter for the help items" },
] ]

View file

@ -191,7 +191,7 @@ rules = [
# Fallback # Fallback
# { name = "*", fg = "white" }, # { name = "*", fg = "white" },
{ name = "*/", fg = "blue" } { name = "*/", fg = "blue" },
] ]
[icon] [icon]

View file

@ -55,20 +55,51 @@ play = [
[open] [open]
rules = [ rules = [
{ name = "*/", use = [ "edit", "open", "reveal" ] }, { name = "*/", use = [
"edit",
"open",
"reveal",
] },
{ mime = "text/*", use = [ "edit", "reveal" ] }, { mime = "text/*", use = [
{ mime = "image/*", use = [ "open", "reveal" ] }, "edit",
{ mime = "{audio,video}/*", use = [ "play", "reveal" ] }, "reveal",
{ mime = "inode/x-empty", use = [ "edit", "reveal" ] }, ] },
{ mime = "image/*", use = [
"open",
"reveal",
] },
{ mime = "{audio,video}/*", use = [
"play",
"reveal",
] },
{ mime = "inode/x-empty", use = [
"edit",
"reveal",
] },
{ mime = "application/{,g}zip", use = [ "extract", "reveal" ] }, { mime = "application/{,g}zip", use = [
{ mime = "application/x-{tar,bzip*,7z-compressed,xz,rar}", use = [ "extract", "reveal" ] }, "extract",
"reveal",
] },
{ mime = "application/x-{tar,bzip*,7z-compressed,xz,rar}", use = [
"extract",
"reveal",
] },
{ mime = "application/json", use = [ "edit", "reveal" ] }, { mime = "application/json", use = [
{ mime = "*/javascript", use = [ "edit", "reveal" ] }, "edit",
"reveal",
] },
{ mime = "*/javascript", use = [
"edit",
"reveal",
] },
{ name = "*", use = [ "open", "reveal" ] }, { name = "*", use = [
"open",
"reveal",
] },
] ]
[tasks] [tasks]

View file

@ -13,15 +13,18 @@ pub mod popup;
mod preset; mod preset;
pub mod preview; pub mod preview;
mod priority; mod priority;
pub mod schemes;
mod tasks; mod tasks;
pub mod theme; pub mod theme;
mod validation; mod validation;
pub mod which; pub mod which;
use crate::schemes::Schemes;
pub use layout::*; pub use layout::*;
pub(crate) use pattern::*; pub(crate) use pattern::*;
pub(crate) use preset::*; pub(crate) use preset::*;
pub use priority::*; pub use priority::*;
use yazi_shared::fs::SCHEMES;
static MERGED_YAZI: RoCell<String> = RoCell::new(); static MERGED_YAZI: RoCell<String> = RoCell::new();
static MERGED_KEYMAP: RoCell<String> = RoCell::new(); static MERGED_KEYMAP: RoCell<String> = RoCell::new();
@ -61,5 +64,9 @@ pub fn init() -> anyhow::Result<()> {
SELECT.with(Default::default); SELECT.with(Default::default);
WHICH.with(Default::default); WHICH.with(Default::default);
// Load schemes.
let schemes = Schemes::default().make()?;
SCHEMES.init(schemes);
Ok(()) Ok(())
} }

View file

@ -0,0 +1,3 @@
mod schemes;
pub use schemes::*;

View file

@ -0,0 +1,54 @@
use anyhow::Result;
use serde::{Deserialize, Deserializer};
use std::collections::HashMap;
use crate::MERGED_YAZI;
/// Schemes in configuration file.
#[derive(Debug)]
pub struct Schemes {
pub rules: Vec<Scheme>,
}
impl Default for Schemes {
fn default() -> Self {
toml::from_str(&MERGED_YAZI).unwrap()
}
}
impl Schemes {
/// Consume loaded config to build yazi_shared::fs::Schemes.
pub fn make(self) -> Result<yazi_shared::fs::Schemes> {
yazi_shared::fs::Schemes::from_iter(self.rules.into_iter().map(|s| (s.name, s.typ, s.config)))
}
}
impl<'de> Deserialize<'de> for Schemes {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize, Default)]
#[serde(default)]
struct Outer {
schemes: Shadow,
}
#[derive(Deserialize, Default)]
struct Shadow {
rules: Vec<Scheme>,
}
let outer = Outer::deserialize(deserializer)?;
Ok(Self { rules: outer.schemes.rules })
}
}
/// Scheme in configuration file.
#[derive(Debug, Deserialize)]
pub struct Scheme {
pub name: String,
#[serde(rename = "type")]
pub typ: String,
pub config: HashMap<String, String>,
}

View file

@ -31,12 +31,19 @@ futures = "0.3.30"
mlua = { version = "0.9.8", features = ["lua54"] } mlua = { version = "0.9.8", features = ["lua54"] }
ratatui = "0.26.3" ratatui = "0.26.3"
scopeguard = "1.2.0" scopeguard = "1.2.0"
syntect = { version = "5.2.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] } syntect = { version = "5.2.0", default-features = false, features = [
"parsing",
"plist-load",
"regex-onig",
] }
tokio = { version = "1.38.0", features = ["full"] } tokio = { version = "1.38.0", features = ["full"] }
tokio-util = "0.7.11" tokio-util = "0.7.11"
# Logging # Logging
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] } tracing = { version = "0.1.40", features = [
"max_level_debug",
"release_max_level_warn",
] }
tracing-appender = "0.2.3" tracing-appender = "0.2.3"
tracing-subscriber = "0.3.18" tracing-subscriber = "0.3.18"

View file

@ -27,14 +27,23 @@ base64 = "0.22.1"
crossterm = "0.27.0" crossterm = "0.27.0"
futures = "0.3.30" futures = "0.3.30"
md-5 = "0.10.6" md-5 = "0.10.6"
mlua = { version = "0.9.8", features = [ "lua54", "serialize", "macros", "async" ] } mlua = { version = "0.9.8", features = [
"lua54",
"serialize",
"macros",
"async",
] }
parking_lot = "0.12.3" parking_lot = "0.12.3"
ratatui = "0.26.3" ratatui = "0.26.3"
serde = "1.0.203" serde = "1.0.203"
serde_json = "1.0.117" serde_json = "1.0.117"
shell-escape = "0.1.5" shell-escape = "0.1.5"
shell-words = "1.1.0" shell-words = "1.1.0"
syntect = { version = "5.2.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] } syntect = { version = "5.2.0", default-features = false, features = [
"parsing",
"plist-load",
"regex-onig",
] }
tokio = { version = "1.38.0", features = ["full"] } tokio = { version = "1.38.0", features = ["full"] }
tokio-stream = "0.1.15" tokio-stream = "0.1.15"
tokio-util = "0.7.11" tokio-util = "0.7.11"
@ -42,7 +51,10 @@ unicode-width = "0.1.13"
yazi-prebuild = "0.1.2" yazi-prebuild = "0.1.2"
# Logging # Logging
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] } tracing = { version = "0.1.40", features = [
"max_level_debug",
"release_max_level_warn",
] }
[target."cfg(unix)".dependencies] [target."cfg(unix)".dependencies]
uzers = "0.12.0" uzers = "0.12.0"

View file

@ -24,7 +24,10 @@ scopeguard = "1.2.0"
tokio = { version = "1.38.0", features = ["full"] } tokio = { version = "1.38.0", features = ["full"] }
# Logging # Logging
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] } tracing = { version = "0.1.40", features = [
"max_level_debug",
"release_max_level_warn",
] }
[target."cfg(unix)".dependencies] [target."cfg(unix)".dependencies]
libc = "0.2.155" libc = "0.2.155"

View file

@ -23,6 +23,7 @@ regex = "1.10.5"
serde = { version = "1.0.203", features = [ "derive" ] } serde = { version = "1.0.203", features = [ "derive" ] }
shell-words = "1.1.0" shell-words = "1.1.0"
tokio = { version = "1.38.0", features = [ "full" ] } tokio = { version = "1.38.0", features = [ "full" ] }
opendal = { version = "0.47.0", features = ["services-s3"] }
# Logging # Logging
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] } tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] }

View file

@ -1,9 +1,15 @@
use std::ops::Add;
use std::time::{Duration, SystemTime};
use std::{cell::Cell, ffi::OsStr, fs::Metadata, ops::Deref}; use std::{cell::Cell, ffi::OsStr, fs::Metadata, ops::Deref};
use anyhow::Result; use anyhow::{anyhow, Result};
use tokio::fs; use tokio::fs;
use crate::{fs::{Cha, ChaKind, Url}, theme::IconCache}; use crate::fs::SCHEMES;
use crate::{
fs::{Cha, ChaKind, Url},
theme::IconCache,
};
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct File { pub struct File {
@ -17,12 +23,18 @@ impl Deref for File {
type Target = Cha; type Target = Cha;
#[inline] #[inline]
fn deref(&self) -> &Self::Target { &self.cha } fn deref(&self) -> &Self::Target {
&self.cha
}
} }
impl File { impl File {
#[inline] #[inline]
pub async fn from(url: Url) -> Result<Self> { pub async fn from(url: Url) -> Result<Self> {
if url.is_remote().is_some() {
return Self::from_remote(url).await;
}
let meta = fs::symlink_metadata(&url).await?; let meta = fs::symlink_metadata(&url).await?;
Ok(Self::from_meta(url, meta).await) Ok(Self::from_meta(url, meta).await)
} }
@ -57,21 +69,63 @@ impl File {
Self { url, cha: Cha::from(meta).with_kind(ck), link_to, icon: Default::default() } Self { url, cha: Cha::from(meta).with_kind(ck), link_to, icon: Default::default() }
} }
/// Build a new file from remote.
pub async fn from_remote(url: Url) -> Result<Self> {
let scheme = url.is_remote().ok_or(anyhow!("not a remote file"))?;
let op = SCHEMES.get(scheme)?;
let meta = op.stat(&url.as_path().to_string_lossy()).await?;
let mut kind = ChaKind::default();
if meta.is_dir() {
kind |= ChaKind::DIR;
}
let cha = Cha {
kind,
len: meta.content_length(),
accessed: None,
created: None,
modified: meta
.last_modified()
.map(|v| SystemTime::UNIX_EPOCH.add(Duration::from_micros(v.timestamp_micros() as u64))),
// Always return 774 for remote files.
#[cfg(unix)]
permissions: 0774,
// Always return current user for remote files.
#[cfg(unix)]
uid: unsafe { libc::getuid().into() },
// Always return current group for remote files.
#[cfg(unix)]
gid: unsafe { libc::getgid().into() },
};
Ok(Self { url, cha, link_to: None, icon: Default::default() })
}
#[inline] #[inline]
pub fn from_dummy(url: &Url) -> Self { Self { url: url.to_owned(), ..Default::default() } } pub fn from_dummy(url: &Url) -> Self {
Self { url: url.to_owned(), ..Default::default() }
}
} }
impl File { impl File {
// --- Url // --- Url
#[inline] #[inline]
pub fn url(&self) -> Url { self.url.clone() } pub fn url(&self) -> Url {
self.url.clone()
#[inline] }
pub fn name(&self) -> Option<&OsStr> { self.url.file_name() }
#[inline]
#[inline] pub fn name(&self) -> Option<&OsStr> {
pub fn stem(&self) -> Option<&OsStr> { self.url.file_stem() } self.url.file_name()
}
#[inline]
pub fn parent(&self) -> Option<Url> { self.url.parent_url() } #[inline]
pub fn stem(&self) -> Option<&OsStr> {
self.url.file_stem()
}
#[inline]
pub fn parent(&self) -> Option<Url> {
self.url.parent_url()
}
} }

View file

@ -3,6 +3,7 @@ mod file;
mod fns; mod fns;
mod op; mod op;
mod path; mod path;
mod schemes;
mod url; mod url;
pub use cha::*; pub use cha::*;
@ -10,4 +11,5 @@ pub use file::*;
pub use fns::*; pub use fns::*;
pub use op::*; pub use op::*;
pub use path::*; pub use path::*;
pub use schemes::*;
pub use url::*; pub use url::*;

View file

@ -0,0 +1,32 @@
use crate::RoCell;
use anyhow::{anyhow, Result};
use opendal::Operator;
use std::collections::HashMap;
use std::str::FromStr;
/// SCHEMES is the read only cell of schemes that already loaded.
pub static SCHEMES: RoCell<Schemes> = RoCell::new();
/// Schemes carries all the schemes defined in the configuration file.
#[derive(Debug)]
pub struct Schemes(HashMap<String, Operator>);
impl Schemes {
/// Build schemes from iterator.
pub fn from_iter(
iter: impl IntoIterator<Item = (String, String, HashMap<String, String>)>,
) -> Result<Self> {
let mut schemes = HashMap::new();
for (name, typ, config) in iter {
let scheme = opendal::Scheme::from_str(&typ)?;
let operator = Operator::via_map(scheme, config)?;
schemes.insert(name, operator);
}
Ok(Self(schemes))
}
/// Get operator by scheme name.
pub fn get(&self, scheme: &str) -> Result<Operator> {
self.0.get(scheme).cloned().ok_or(anyhow!("storage scheme {scheme} is not configured"))
}
}

View file

@ -1,4 +1,9 @@
use std::{ffi::{OsStr, OsString}, fmt::{Debug, Display, Formatter}, ops::{Deref, DerefMut}, path::{Path, PathBuf}}; use std::{
ffi::{OsStr, OsString},
fmt::{Debug, Display, Formatter},
ops::{Deref, DerefMut},
path::{Path, PathBuf},
};
use percent_encoding::{percent_decode_str, percent_encode, AsciiSet, CONTROLS}; use percent_encoding::{percent_decode_str, percent_encode, AsciiSet, CONTROLS};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -12,46 +17,63 @@ pub struct Url {
frag: String, frag: String,
} }
#[derive(Clone, Copy, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Clone, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum UrlScheme { pub enum UrlScheme {
#[default] #[default]
Regular, Regular,
Search, Search,
Archive, Archive,
Remote(String),
} }
impl Deref for Url { impl Deref for Url {
type Target = PathBuf; type Target = PathBuf;
fn deref(&self) -> &Self::Target { &self.path } fn deref(&self) -> &Self::Target {
&self.path
}
} }
impl DerefMut for Url { impl DerefMut for Url {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.path } fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.path
}
} }
impl Debug for Url { impl Debug for Url {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.path.display()) } fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.path.display())
}
} }
impl From<PathBuf> for Url { impl From<PathBuf> for Url {
fn from(path: PathBuf) -> Self { Self { path, ..Default::default() } } fn from(path: PathBuf) -> Self {
Self { path, ..Default::default() }
}
} }
impl From<&PathBuf> for Url { impl From<&PathBuf> for Url {
fn from(path: &PathBuf) -> Self { Self::from(path.clone()) } fn from(path: &PathBuf) -> Self {
Self::from(path.clone())
}
} }
impl From<&Path> for Url { impl From<&Path> for Url {
fn from(path: &Path) -> Self { Self::from(path.to_path_buf()) } fn from(path: &Path) -> Self {
Self::from(path.to_path_buf())
}
} }
impl From<String> for Url { impl From<String> for Url {
fn from(path: String) -> Self { Self::from(path.as_str()) } fn from(path: String) -> Self {
Self::from(path.as_str())
}
} }
impl From<&String> for Url { impl From<&String> for Url {
fn from(path: &String) -> Self { Self::from(path.as_str()) } fn from(path: &String) -> Self {
Self::from(path.as_str())
}
} }
impl From<&str> for Url { impl From<&str> for Url {
@ -85,31 +107,35 @@ impl From<&str> for Url {
} }
impl AsRef<Url> for Url { impl AsRef<Url> for Url {
fn as_ref(&self) -> &Url { self } fn as_ref(&self) -> &Url {
self
}
} }
impl AsRef<Path> for Url { impl AsRef<Path> for Url {
fn as_ref(&self) -> &Path { &self.path } fn as_ref(&self) -> &Path {
&self.path
}
} }
impl AsRef<OsStr> for Url { impl AsRef<OsStr> for Url {
fn as_ref(&self) -> &OsStr { self.path.as_os_str() } fn as_ref(&self) -> &OsStr {
self.path.as_os_str()
}
} }
impl Display for Url { impl Display for Url {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
if self.scheme == UrlScheme::Regular { match &self.scheme {
return f.write_str(&self.path.to_string_lossy()); UrlScheme::Regular => return f.write_str(&self.path.to_string_lossy()),
UrlScheme::Search => write!(f, "search://")?,
UrlScheme::Archive => write!(f, "archive://")?,
UrlScheme::Remote(scheme) => write!(f, "{scheme}://")?,
} }
let scheme = match self.scheme {
UrlScheme::Regular => unreachable!(),
UrlScheme::Search => "search://",
UrlScheme::Archive => "archive://",
};
let path = percent_encode(self.path.as_os_str().as_encoded_bytes(), ENCODE_SET); let path = percent_encode(self.path.as_os_str().as_encoded_bytes(), ENCODE_SET);
write!(f, "{path}")?;
write!(f, "{scheme}{path}")?;
if !self.frag.is_empty() { if !self.frag.is_empty() {
write!(f, "#{}", self.frag)?; write!(f, "#{}", self.frag)?;
} }
@ -126,6 +152,7 @@ impl Url {
UrlScheme::Regular => url, UrlScheme::Regular => url,
UrlScheme::Search => url, UrlScheme::Search => url,
UrlScheme::Archive => url.into_archive(), UrlScheme::Archive => url.into_archive(),
UrlScheme::Remote(_) => url,
} }
} }
@ -137,6 +164,7 @@ impl Url {
UrlScheme::Regular => url, UrlScheme::Regular => url,
UrlScheme::Search => url, UrlScheme::Search => url,
UrlScheme::Archive => url, UrlScheme::Archive => url,
UrlScheme::Remote(_) => url,
} }
}) })
} }
@ -147,7 +175,9 @@ impl Url {
} }
#[inline] #[inline]
pub fn into_os_string(self) -> OsString { self.path.into_os_string() } pub fn into_os_string(self) -> OsString {
self.path.into_os_string()
}
#[cfg(unix)] #[cfg(unix)]
#[inline] #[inline]
@ -159,10 +189,14 @@ impl Url {
impl Url { impl Url {
// --- Scheme // --- Scheme
#[inline] #[inline]
pub fn is_regular(&self) -> bool { self.scheme == UrlScheme::Regular } pub fn is_regular(&self) -> bool {
self.scheme == UrlScheme::Regular
}
#[inline] #[inline]
pub fn to_regular(&self) -> Self { self.clone().into_regular() } pub fn to_regular(&self) -> Self {
self.clone().into_regular()
}
#[inline] #[inline]
pub fn into_regular(mut self) -> Self { pub fn into_regular(mut self) -> Self {
@ -171,10 +205,14 @@ impl Url {
} }
#[inline] #[inline]
pub fn is_search(&self) -> bool { self.scheme == UrlScheme::Search } pub fn is_search(&self) -> bool {
self.scheme == UrlScheme::Search
}
#[inline] #[inline]
pub fn to_search(&self, frag: String) -> Self { self.clone().into_search(frag) } pub fn to_search(&self, frag: String) -> Self {
self.clone().into_search(frag)
}
#[inline] #[inline]
pub fn into_search(mut self, frag: String) -> Self { pub fn into_search(mut self, frag: String) -> Self {
@ -184,10 +222,14 @@ impl Url {
} }
#[inline] #[inline]
pub fn is_archive(&self) -> bool { self.scheme == UrlScheme::Archive } pub fn is_archive(&self) -> bool {
self.scheme == UrlScheme::Archive
}
#[inline] #[inline]
pub fn to_archive(&self) -> Self { self.clone().into_archive() } pub fn to_archive(&self) -> Self {
self.clone().into_archive()
}
#[inline] #[inline]
pub fn into_archive(mut self) -> Self { pub fn into_archive(mut self) -> Self {
@ -195,13 +237,28 @@ impl Url {
self self
} }
/// Check and fetch remote scheme.
///
/// Returns None if current url is not remote, otherwise returns `Some(scheme)`
#[inline]
pub fn is_remote(&self) -> Option<&str> {
match &self.scheme {
UrlScheme::Remote(scheme) => Some(scheme),
_ => None,
}
}
// --- Path // --- Path
#[inline] #[inline]
pub fn set_path(&mut self, path: PathBuf) { self.path = path; } pub fn set_path(&mut self, path: PathBuf) {
self.path = path;
}
// --- Frag // --- Frag
#[inline] #[inline]
pub fn frag(&self) -> &str { &self.frag } pub fn frag(&self) -> &str {
&self.frag
}
} }
impl From<&str> for UrlScheme { impl From<&str> for UrlScheme {