mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 14:51:03 +00:00
feat: mount manager (#2199)
This commit is contained in:
parent
6c94227d40
commit
3e1c8950f2
40 changed files with 1068 additions and 340 deletions
352
Cargo.lock
generated
352
Cargo.lock
generated
|
|
@ -63,7 +63,7 @@ dependencies = [
|
|||
"ratatui",
|
||||
"simdutf8",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -107,11 +107,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.6"
|
||||
version = "3.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
|
||||
checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
|
|
@ -200,7 +201,7 @@ dependencies = [
|
|||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -242,9 +243,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.6.0"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
|
||||
|
||||
[[package]]
|
||||
name = "bitstream-io"
|
||||
|
|
@ -333,9 +334,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.7"
|
||||
version = "1.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7"
|
||||
checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
|
|
@ -367,14 +368,14 @@ dependencies = [
|
|||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"num-traits",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.23"
|
||||
version = "4.5.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
|
||||
checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
|
@ -382,9 +383,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.23"
|
||||
version = "4.5.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
|
||||
checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
|
@ -394,9 +395,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.5.40"
|
||||
version = "4.5.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac2e663e3e3bed2d32d065a8404024dad306e699a04263ec59919529f803aee9"
|
||||
checksum = "33a7e468e750fa4b6be660e8b5651ad47372e8fb114030b594c2d75d48c5ffd0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
|
@ -423,9 +424,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.18"
|
||||
version = "4.5.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
|
||||
checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
|
|
@ -550,7 +551,7 @@ version = "0.28.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.8.0",
|
||||
"crossterm_winapi",
|
||||
"filedescriptor",
|
||||
"futures-core",
|
||||
|
|
@ -675,23 +676,23 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "5.0.1"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
||||
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.4.1"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
||||
checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -791,7 +792,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "e182f7dbc2ef73d9ef67351c5fbbea084729c48362d3ce9dd44c28e32e277fe5"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"thiserror",
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -801,7 +802,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "7199d965852c3bac31f779ef99cbb4537f80e952e2d6aa0ffeb30cce00f4f46e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"thiserror",
|
||||
"thiserror 1.0.69",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
|
|
@ -1223,9 +1224,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "image-webp"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e031e8e3d94711a9ccb5d6ea357439ef3dcbed361798bd4071dc4d9793fbe22f"
|
||||
checksum = "b77d01e822461baa8409e156015a1d91735549f0f2c17691bd2d996bef238f7f"
|
||||
dependencies = [
|
||||
"byteorder-lite",
|
||||
"quick-error",
|
||||
|
|
@ -1256,11 +1257,11 @@ checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
|
|||
|
||||
[[package]]
|
||||
name = "inotify"
|
||||
version = "0.10.2"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdd168d97690d0b8c412d6b6c10360277f4d7ee495c5d0d5d5fe0854923255cc"
|
||||
checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags 2.8.0",
|
||||
"inotify-sys",
|
||||
"libc",
|
||||
]
|
||||
|
|
@ -1276,9 +1277,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "instability"
|
||||
version = "0.3.6"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "894813a444908c0c8c0e221b041771d107c4a21de1d317dc49bcc66e3c9e5b3f"
|
||||
checksum = "0bf9fed6d91cfb734e7476a06bde8300a1b94e217e1b523b6f0cd1a01998c71d"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"indoc",
|
||||
|
|
@ -1287,15 +1288,6 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "interpolate_name"
|
||||
version = "0.2.4"
|
||||
|
|
@ -1348,9 +1340,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.76"
|
||||
version = "0.3.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7"
|
||||
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
|
|
@ -1410,16 +1402,16 @@ version = "0.1.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.8.0",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.14"
|
||||
version = "0.4.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
||||
|
||||
[[package]]
|
||||
name = "litemap"
|
||||
|
|
@ -1439,9 +1431,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
version = "0.4.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
|
||||
|
||||
[[package]]
|
||||
name = "loop9"
|
||||
|
|
@ -1480,6 +1472,15 @@ dependencies = [
|
|||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "malloc_buf"
|
||||
version = "0.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.1.0"
|
||||
|
|
@ -1522,9 +1523,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.2"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394"
|
||||
checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
"simd-adler32",
|
||||
|
|
@ -1614,11 +1615,11 @@ checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
|
|||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "7.0.0"
|
||||
version = "8.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c533b4c39709f9ba5005d8002048266593c1cfaf3c5f0739d5b8ab0c6c504009"
|
||||
checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.8.0",
|
||||
"filetime",
|
||||
"fsevent-sys",
|
||||
"inotify",
|
||||
|
|
@ -1628,17 +1629,14 @@ dependencies = [
|
|||
"mio",
|
||||
"notify-types",
|
||||
"walkdir",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify-types"
|
||||
version = "1.0.1"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "585d3cb5e12e01aed9e8a1f70d5c6b5e86fe2a6e48fc8cd0b3e0b8df6f6eb174"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d"
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
|
|
@ -1715,6 +1713,15 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
|
||||
dependencies = [
|
||||
"malloc_buf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc-sys"
|
||||
version = "0.3.5"
|
||||
|
|
@ -1743,7 +1750,7 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.8.0",
|
||||
"block2",
|
||||
"libc",
|
||||
"objc2",
|
||||
|
|
@ -1833,7 +1840,7 @@ dependencies = [
|
|||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1850,9 +1857,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
|||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.15"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
|
||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
|
|
@ -1931,9 +1938,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.92"
|
||||
version = "1.0.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
|
||||
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
|
@ -2026,7 +2033,7 @@ version = "0.29.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.8.0",
|
||||
"cassowary",
|
||||
"compact_str",
|
||||
"crossterm",
|
||||
|
|
@ -2071,7 +2078,7 @@ dependencies = [
|
|||
"rand_chacha",
|
||||
"simd_helpers",
|
||||
"system-deps",
|
||||
"thiserror",
|
||||
"thiserror 1.0.69",
|
||||
"v_frame",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
|
@ -2106,18 +2113,18 @@ version = "0.5.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.6"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
|
||||
checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"libredox",
|
||||
"thiserror",
|
||||
"thiserror 2.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2193,11 +2200,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.42"
|
||||
version = "0.38.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85"
|
||||
checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.8.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
|
|
@ -2269,9 +2276,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.134"
|
||||
version = "1.0.135"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d"
|
||||
checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
|
|
@ -2439,9 +2446,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.95"
|
||||
version = "2.0.96"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a"
|
||||
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -2476,7 +2483,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"thiserror 1.0.69",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
|
|
@ -2505,7 +2512,16 @@ version = "1.0.69"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
"thiserror-impl 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
|
||||
dependencies = [
|
||||
"thiserror-impl 2.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2519,6 +2535,17 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.8"
|
||||
|
|
@ -2594,9 +2621,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.42.0"
|
||||
version = "1.43.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551"
|
||||
checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
|
|
@ -2612,9 +2639,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.4.0"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
||||
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -2697,7 +2724,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"thiserror",
|
||||
"thiserror 1.0.69",
|
||||
"time",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
|
@ -2920,9 +2947,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
|||
|
||||
[[package]]
|
||||
name = "vergen"
|
||||
version = "9.0.2"
|
||||
version = "9.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31f25fc8f8f05df455c7941e87f093ad22522a9ff33d7a027774815acf6f0639"
|
||||
checksum = "e0d2f179f8075b805a43a2a21728a46f0cc2921b3c58695b28fa8817e103cd9a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"derive_builder",
|
||||
|
|
@ -2934,9 +2961,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "vergen-gitcl"
|
||||
version = "1.0.2"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0227006d09f98ab00ea69e9a5e055e676a813cfbed4232986176c86a6080b997"
|
||||
checksum = "b2f89d70a58a4506a6079cedf575c64cf51649ccbb4e02a63dac539b264b7711"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"derive_builder",
|
||||
|
|
@ -2948,9 +2975,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "vergen-lib"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0c767e6751c09fc85cde58722cf2f1007e80e4c8d5a4321fc90d83dc54ca147"
|
||||
checksum = "9b07e6010c0f3e59fcb164e0163834597da68d1f864e2b8ca49f74de01e9c166"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"derive_builder",
|
||||
|
|
@ -2987,20 +3014,21 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.99"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396"
|
||||
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"rustversion",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.99"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79"
|
||||
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
|
|
@ -3012,9 +3040,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.99"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe"
|
||||
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
|
|
@ -3022,9 +3050,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.99"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
|
||||
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -3035,9 +3063,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.99"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6"
|
||||
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
|
|
@ -3095,7 +3126,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132"
|
||||
dependencies = [
|
||||
"windows-core 0.56.0",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3104,7 +3135,7 @@ version = "0.52.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3116,7 +3147,7 @@ dependencies = [
|
|||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-result",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3147,16 +3178,7 @@ version = "0.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3165,7 +3187,7 @@ version = "0.52.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3174,22 +3196,7 @@ version = "0.59.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3198,46 +3205,28 @@ version = "0.52.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
|
|
@ -3250,48 +3239,24 @@ version = "0.52.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
|
|
@ -3300,9 +3265,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
|||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.22"
|
||||
version = "0.6.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980"
|
||||
checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
|
@ -3399,7 +3364,7 @@ name = "yazi-config"
|
|||
version = "0.4.3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.8.0",
|
||||
"crossterm",
|
||||
"globset",
|
||||
"indexmap",
|
||||
|
|
@ -3419,7 +3384,7 @@ name = "yazi-core"
|
|||
version = "0.4.3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.8.0",
|
||||
"crossterm",
|
||||
"dirs",
|
||||
"futures",
|
||||
|
|
@ -3468,6 +3433,17 @@ dependencies = [
|
|||
"yazi-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yazi-ffi"
|
||||
version = "0.4.3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"objc",
|
||||
"yazi-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yazi-fm"
|
||||
version = "0.4.3"
|
||||
|
|
@ -3508,15 +3484,21 @@ version = "0.4.3"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"arc-swap",
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.8.0",
|
||||
"core-foundation-sys",
|
||||
"dirs",
|
||||
"futures",
|
||||
"libc",
|
||||
"objc",
|
||||
"parking_lot",
|
||||
"regex",
|
||||
"scopeguard",
|
||||
"serde",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"uzers",
|
||||
"windows-sys 0.59.0",
|
||||
"yazi-ffi",
|
||||
"yazi-macro",
|
||||
"yazi-shared",
|
||||
]
|
||||
|
|
|
|||
56
Cargo.toml
56
Cargo.toml
|
|
@ -10,30 +10,32 @@ panic = "abort"
|
|||
strip = true
|
||||
|
||||
[workspace.dependencies]
|
||||
ansi-to-tui = "7.0.0"
|
||||
anyhow = "1.0.95"
|
||||
base64 = "0.22.1"
|
||||
bitflags = "2.6.0"
|
||||
clap = { version = "4.5.23", features = [ "derive" ] }
|
||||
crossterm = { version = "0.28.1", features = [ "event-stream" ] }
|
||||
dirs = "5.0.1"
|
||||
futures = "0.3.31"
|
||||
globset = "0.4.15"
|
||||
libc = "0.2.169"
|
||||
md-5 = "0.10.6"
|
||||
mlua = { version = "0.10.2", features = [ "anyhow", "async", "error-send", "lua54", "macros", "serialize" ] }
|
||||
parking_lot = "0.12.3"
|
||||
ratatui = { version = "0.29.0", features = [ "unstable-rendered-line-info" ] }
|
||||
regex = "1.11.1"
|
||||
scopeguard = "1.2.0"
|
||||
serde = { version = "1.0.217", features = [ "derive" ] }
|
||||
serde_json = "1.0.134"
|
||||
shell-words = "1.1.0"
|
||||
tokio = { version = "1.42.0", features = [ "full" ] }
|
||||
tokio-stream = "0.1.17"
|
||||
tokio-util = "0.7.13"
|
||||
toml = { version = "0.8.19" }
|
||||
tracing = { version = "0.1.41", features = [ "max_level_debug", "release_max_level_debug" ] }
|
||||
twox-hash = { version = "2.1.0", default-features = false, features = [ "std", "random", "xxhash3_128" ] }
|
||||
unicode-width = "0.2.0"
|
||||
uzers = "0.12.1"
|
||||
ansi-to-tui = "7.0.0"
|
||||
anyhow = "1.0.95"
|
||||
base64 = "0.22.1"
|
||||
bitflags = "2.8.0"
|
||||
clap = { version = "4.5.26", features = [ "derive" ] }
|
||||
core-foundation-sys = "0.8.7"
|
||||
crossterm = { version = "0.28.1", features = [ "event-stream" ] }
|
||||
dirs = "6.0.0"
|
||||
futures = "0.3.31"
|
||||
globset = "0.4.15"
|
||||
libc = "0.2.169"
|
||||
md-5 = "0.10.6"
|
||||
mlua = { version = "0.10.2", features = [ "anyhow", "async", "error-send", "lua54", "macros", "serialize" ] }
|
||||
objc = "0.2.7"
|
||||
parking_lot = "0.12.3"
|
||||
ratatui = { version = "0.29.0", features = [ "unstable-rendered-line-info" ] }
|
||||
regex = "1.11.1"
|
||||
scopeguard = "1.2.0"
|
||||
serde = { version = "1.0.217", features = [ "derive" ] }
|
||||
serde_json = "1.0.135"
|
||||
shell-words = "1.1.0"
|
||||
tokio = { version = "1.43.0", features = [ "full" ] }
|
||||
tokio-stream = "0.1.17"
|
||||
tokio-util = "0.7.13"
|
||||
toml = { version = "0.8.19" }
|
||||
tracing = { version = "0.1.41", features = [ "max_level_debug", "release_max_level_debug" ] }
|
||||
twox-hash = { version = "2.1.0", default-features = false, features = [ "std", "random", "xxhash3_128" ] }
|
||||
unicode-width = "0.2.0"
|
||||
uzers = "0.12.1"
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ Yazi (means "duck") is a terminal file manager written in Rust, based on non-blo
|
|||
- 🧰 Integration with ripgrep, fd, fzf, zoxide
|
||||
- 💫 Vim-like input/pick/confirm/which/notify component, auto-completion for cd paths
|
||||
- 🏷️ Multi-Tab Support, Cross-directory selection, Scrollable Preview (for videos, PDFs, archives, code, directories, etc.)
|
||||
- 🔄 Bulk Renaming, Visual Mode, File Chooser
|
||||
- 🔄 Bulk Renaming, Visual Mode, File Chooser, [Git Integration](https://github.com/yazi-rs/plugins/tree/main/git.yazi), [Mount Manager](https://github.com/yazi-rs/plugins/tree/main/mount.yazi)
|
||||
- 🎨 Theme System, Mouse Support, Trash Bin, Custom Layouts, CSI u, OSC 52
|
||||
- ... and more!
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ See https://yazi-rs.github.io/docs/image-preview for details.
|
|||
<!-- Protocols -->
|
||||
|
||||
[kgp]: https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders
|
||||
[kgp-old]: https://github.com/sxyazi/yazi/blob/main/yazi-adapter/src/kgp_old.rs
|
||||
[kgp-old]: https://github.com/sxyazi/yazi/blob/main/yazi-adapter/src/drivers/kgp_old.rs
|
||||
[iip]: https://iterm2.com/documentation-images.html
|
||||
[sixel]: https://www.vt100.net/docs/vt3xx-gp/chapter14.html
|
||||
[ascii-art]: https://en.wikipedia.org/wiki/ASCII_art
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK","btime","nsec","codegen","gethostname","fchmod","fdfind","Rustc","rustc","Sysinfo","ffprobe","vframes","luma","obase","outln","errln","tmtheme","twox"],"version":"0.2","language":"en","flagWords":[]}
|
||||
{"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK","btime","nsec","codegen","gethostname","fchmod","fdfind","Rustc","rustc","Sysinfo","ffprobe","vframes","luma","obase","outln","errln","tmtheme","twox","cfgs","fstype","objc","rdev","runloop","exfat","rclone"],"version":"0.2","language":"en","flagWords":[]}
|
||||
158
flake.lock
generated
158
flake.lock
generated
|
|
@ -1,80 +1,82 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1726560853,
|
||||
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1729265718,
|
||||
"narHash": "sha256-4HQI+6LsO3kpWTYuVGIzhJs1cetFcwT7quWCk/6rqeo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ccc0c2126893dd20963580b6478d1a10a4512185",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"rust-overlay": "rust-overlay"
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"nixpkgs": ["nixpkgs"]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1729391507,
|
||||
"narHash": "sha256-as0I9xieJUHf7kiK2a9znDsVZQTFWhM1pLivII43Gi0=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "784981a9feeba406de38c1c9a3decf966d853cca",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1737003892,
|
||||
"narHash": "sha256-RCzJE9wKByLCXmRBp+z8LK9EgdW+K+W/DXnJS4S/NVo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ae06b9c2d83cb5c8b12d7d0e32692e93d1379713",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"rust-overlay": "rust-overlay"
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737080704,
|
||||
"narHash": "sha256-n+J2h9GM9ZpFOQUmtZoCr1+DFF/iO5UlmLJeHIxbZGY=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "f9953fe89f8b65401fc4d4a288940bc2cb072949",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ serde = { workspace = true }
|
|||
|
||||
[build-dependencies]
|
||||
clap = { workspace = true }
|
||||
clap_complete = "4.5.40"
|
||||
clap_complete = "4.5.42"
|
||||
clap_complete_fig = "4.5.2"
|
||||
clap_complete_nushell = "4.5.5"
|
||||
vergen-gitcl = { version = "1.0.2", features = [ "build", "rustc" ] }
|
||||
vergen-gitcl = { version = "1.0.5", features = [ "build", "rustc" ] }
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@ yazi-shared = { path = "../yazi-shared", version = "0.4.3" }
|
|||
# External build dependencies
|
||||
anyhow = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
clap_complete = "4.5.40"
|
||||
clap_complete = "4.5.42"
|
||||
clap_complete_fig = "4.5.2"
|
||||
clap_complete_nushell = "4.5.5"
|
||||
serde_json = { workspace = true }
|
||||
vergen-gitcl = { version = "1.0.2", features = [ "build" ] }
|
||||
vergen-gitcl = { version = "1.0.5", features = [ "build" ] }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
crossterm = { workspace = true, features = [ "use-dev-tty", "libc" ] }
|
||||
|
|
|
|||
|
|
@ -13,5 +13,5 @@ proc-macro = true
|
|||
|
||||
[dependencies]
|
||||
# External dependencies
|
||||
syn = { version = "2.0.95", features = [ "full" ] }
|
||||
syn = { version = "2.0.96", features = [ "full" ] }
|
||||
quote = "1.0.38"
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ bitflags = { workspace = true }
|
|||
crossterm = { workspace = true }
|
||||
dirs = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
notify = { version = "7.0.0", default-features = false, features = [ "macos_fsevent" ] }
|
||||
notify = { version = "8.0.0", default-features = false, features = [ "macos_fsevent" ] }
|
||||
parking_lot = { workspace = true }
|
||||
ratatui = { workspace = true }
|
||||
scopeguard = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ use tokio::{fs, pin, sync::{mpsc::{self, UnboundedReceiver}, watch}};
|
|||
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
|
||||
use tracing::error;
|
||||
use yazi_config::PLUGIN;
|
||||
use yazi_fs::{Cha, File, Files, FilesOp, realname_unchecked};
|
||||
use yazi_dds::Pubsub;
|
||||
use yazi_fs::{Cha, File, Files, FilesOp, mounts::PARTITIONS, realname_unchecked};
|
||||
use yazi_plugin::isolate;
|
||||
use yazi_proxy::WATCHER;
|
||||
use yazi_shared::{RoCell, event::CmdCow, url::Url};
|
||||
|
|
@ -44,6 +45,9 @@ impl Watcher {
|
|||
tokio::spawn(Self::fan_in(in_rx, RecommendedWatcher::new(handler, config).unwrap()));
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
yazi_fs::mounts::Partitions::monitor(PARTITIONS.clone(), Pubsub::pub_from_mount);
|
||||
|
||||
tokio::spawn(Self::fan_out(out_rx));
|
||||
Self { in_tx, out_tx }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,9 +46,7 @@ impl Preview {
|
|||
let Some(cwd) = cwd else { return };
|
||||
self.folder_loader.take().map(|h| h.abort());
|
||||
self.folder_loader = Some(tokio::spawn(async move {
|
||||
let Some(new) = Files::assert_stale(&cwd, dir.unwrap_or(Cha::dummy())).await else {
|
||||
return;
|
||||
};
|
||||
let Some(new) = Files::assert_stale(&cwd, dir.unwrap_or(Cha::dummy())).await else { return };
|
||||
let Ok(rx) = Files::from_dir(&cwd).await else { return };
|
||||
|
||||
let stream =
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ tokio-util = { workspace = true }
|
|||
tracing = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
vergen-gitcl = { version = "1.0.2", features = [ "build" ] }
|
||||
vergen-gitcl = { version = "1.0.5", features = [ "build" ] }
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
uzers = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use anyhow::{Result, bail};
|
|||
use mlua::{ExternalResult, IntoLua, Lua, Value};
|
||||
use serde::Serialize;
|
||||
|
||||
use super::{BodyBulk, BodyBye, BodyCd, BodyCustom, BodyDelete, BodyHey, BodyHi, BodyHover, BodyLoad, BodyMove, BodyRename, BodyTab, BodyTrash, BodyYank};
|
||||
use super::{BodyBulk, BodyBye, BodyCd, BodyCustom, BodyDelete, BodyHey, BodyHi, BodyHover, BodyLoad, BodyMount, BodyMove, BodyRename, BodyTab, BodyTrash, BodyYank};
|
||||
use crate::Payload;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
|
|
@ -21,6 +21,7 @@ pub enum Body<'a> {
|
|||
Move(BodyMove<'a>),
|
||||
Trash(BodyTrash<'a>),
|
||||
Delete(BodyDelete<'a>),
|
||||
Mount(BodyMount),
|
||||
Custom(BodyCustom),
|
||||
}
|
||||
|
||||
|
|
@ -40,6 +41,7 @@ impl Body<'static> {
|
|||
"move" => Self::Move(serde_json::from_str(body)?),
|
||||
"trash" => Self::Trash(serde_json::from_str(body)?),
|
||||
"delete" => Self::Delete(serde_json::from_str(body)?),
|
||||
"mount" => Self::Mount(serde_json::from_str(body)?),
|
||||
_ => BodyCustom::from_str(kind, body)?,
|
||||
})
|
||||
}
|
||||
|
|
@ -65,6 +67,7 @@ impl Body<'static> {
|
|||
| "move"
|
||||
| "trash"
|
||||
| "delete"
|
||||
| "mount"
|
||||
) {
|
||||
bail!("Cannot construct system event");
|
||||
}
|
||||
|
|
@ -98,6 +101,7 @@ impl<'a> Body<'a> {
|
|||
Self::Move(_) => "move",
|
||||
Self::Trash(_) => "trash",
|
||||
Self::Delete(_) => "delete",
|
||||
Self::Mount(_) => "mount",
|
||||
Self::Custom(b) => b.kind.as_str(),
|
||||
}
|
||||
}
|
||||
|
|
@ -127,6 +131,7 @@ impl IntoLua for Body<'static> {
|
|||
Self::Move(b) => b.into_lua(lua),
|
||||
Self::Trash(b) => b.into_lua(lua),
|
||||
Self::Delete(b) => b.into_lua(lua),
|
||||
Self::Mount(b) => b.into_lua(lua),
|
||||
Self::Custom(b) => b.into_lua(lua),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#![allow(clippy::module_inception)]
|
||||
|
||||
yazi_macro::mod_flat!(
|
||||
body bulk bye cd custom delete hey hi hover load move_ rename tab trash yank
|
||||
body bulk bye cd custom delete hey hi hover load mount move_ rename tab trash yank
|
||||
);
|
||||
|
|
|
|||
20
yazi-dds/src/body/mount.rs
Normal file
20
yazi-dds/src/body/mount.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
use mlua::{IntoLua, Lua, Value};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::Body;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct BodyMount;
|
||||
|
||||
impl BodyMount {
|
||||
#[inline]
|
||||
pub fn owned() -> Body<'static> { Self.into() }
|
||||
}
|
||||
|
||||
impl From<BodyMount> for Body<'_> {
|
||||
fn from(value: BodyMount) -> Self { Self::Mount(value) }
|
||||
}
|
||||
|
||||
impl IntoLua for BodyMount {
|
||||
fn into_lua(self, _: &Lua) -> mlua::Result<Value> { Ok(Value::Nil) }
|
||||
}
|
||||
|
|
@ -91,6 +91,7 @@ impl Display for Payload<'_> {
|
|||
Body::Move(b) => serde_json::to_string(b),
|
||||
Body::Trash(b) => serde_json::to_string(b),
|
||||
Body::Delete(b) => serde_json::to_string(b),
|
||||
Body::Mount(b) => serde_json::to_string(b),
|
||||
Body::Custom(b) => serde_json::to_string(b),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use yazi_boot::BOOT;
|
|||
use yazi_fs::FolderStage;
|
||||
use yazi_shared::{Id, RoCell, url::Url};
|
||||
|
||||
use crate::{Client, ID, PEERS, body::{Body, BodyBulk, BodyCd, BodyDelete, BodyHi, BodyHover, BodyLoad, BodyMove, BodyMoveItem, BodyRename, BodyTab, BodyTrash, BodyYank}};
|
||||
use crate::{Client, ID, PEERS, body::{Body, BodyBulk, BodyCd, BodyDelete, BodyHi, BodyHover, BodyLoad, BodyMount, BodyMove, BodyMoveItem, BodyRename, BodyTab, BodyTrash, BodyYank}};
|
||||
|
||||
pub static LOCAL: RoCell<RwLock<HashMap<String, HashMap<String, Function>>>> = RoCell::new();
|
||||
|
||||
|
|
@ -205,6 +205,18 @@ impl Pubsub {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn pub_from_mount() {
|
||||
if LOCAL.read().contains_key("mount") {
|
||||
Self::pub_(BodyMount::owned());
|
||||
}
|
||||
if PEERS.read().values().any(|p| p.able("mount")) {
|
||||
Client::push(BodyMount::owned());
|
||||
}
|
||||
if BOOT.local_events.contains("mount") {
|
||||
BodyMount::owned().with_receiver(*ID).flush();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn any_remote_own(kind: &str) -> bool {
|
||||
REMOTE.read().contains_key(kind) // Owned abilities
|
||||
|
|
|
|||
22
yazi-ffi/Cargo.toml
Normal file
22
yazi-ffi/Cargo.toml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
[package]
|
||||
name = "yazi-ffi"
|
||||
version = "0.4.3"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
description = "Yazi foreign function interface"
|
||||
homepage = "https://yazi-rs.github.io"
|
||||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-macro = { path = "../yazi-macro", version = "0.4.3" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
libc = { workspace = true }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
core-foundation-sys = { workspace = true }
|
||||
objc = { workspace = true }
|
||||
53
yazi-ffi/src/cf_dict.rs
Normal file
53
yazi-ffi/src/cf_dict.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
use std::{ffi::{CStr, OsStr, OsString, c_char, c_void}, mem::ManuallyDrop, os::unix::ffi::OsStrExt, path::PathBuf};
|
||||
|
||||
use anyhow::{Result, bail};
|
||||
use core_foundation_sys::{base::{CFRelease, TCFTypeRef}, dictionary::{CFDictionaryGetValueIfPresent, CFDictionaryRef}, string::CFStringRef};
|
||||
use objc::{msg_send, runtime::Object, sel, sel_impl};
|
||||
|
||||
use super::cf_string::CFString;
|
||||
|
||||
pub struct CFDict(CFDictionaryRef);
|
||||
|
||||
impl CFDict {
|
||||
pub fn take(dict: CFDictionaryRef) -> Result<Self> {
|
||||
if dict.is_null() {
|
||||
bail!("Cannot take a null pointer");
|
||||
}
|
||||
Ok(Self(dict))
|
||||
}
|
||||
|
||||
pub fn value(&self, key: &str) -> Result<*const c_void> {
|
||||
let key_ = CFString::new(key)?;
|
||||
let mut value = std::ptr::null();
|
||||
if unsafe { CFDictionaryGetValueIfPresent(self.0, key_.as_void_ptr(), &mut value) } == 0
|
||||
|| value.is_null()
|
||||
{
|
||||
bail!("Cannot get the value for the key `{key}`");
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn integer(&self, key: &str) -> Result<i64> {
|
||||
let value = self.value(key)?;
|
||||
#[allow(unexpected_cfgs)]
|
||||
Ok(unsafe { msg_send![value as *const Object, longLongValue] })
|
||||
}
|
||||
|
||||
pub fn os_string(&self, key: &str) -> Result<OsString> {
|
||||
ManuallyDrop::new(CFString(self.value(key)? as CFStringRef)).os_string()
|
||||
}
|
||||
|
||||
pub fn path_buf(&self, key: &str) -> Result<PathBuf> {
|
||||
let url = self.value(key)? as *const Object;
|
||||
#[allow(unexpected_cfgs)]
|
||||
let cstr: *const c_char = unsafe {
|
||||
let nss: *const Object = msg_send![url, path];
|
||||
msg_send![nss, UTF8String]
|
||||
};
|
||||
Ok(OsStr::from_bytes(unsafe { CStr::from_ptr(cstr) }.to_bytes()).into())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for CFDict {
|
||||
fn drop(&mut self) { unsafe { CFRelease(self.0 as _) } }
|
||||
}
|
||||
58
yazi-ffi/src/cf_string.rs
Normal file
58
yazi-ffi/src/cf_string.rs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
use std::{ffi::OsString, ops::Deref, os::unix::ffi::OsStringExt};
|
||||
|
||||
use anyhow::{Result, bail};
|
||||
use core_foundation_sys::{base::{CFRelease, kCFAllocatorDefault, kCFAllocatorNull}, string::{CFStringCreateWithBytesNoCopy, CFStringGetCString, CFStringGetLength, CFStringGetMaximumSizeForEncoding, CFStringRef, kCFStringEncodingUTF8}};
|
||||
use libc::strlen;
|
||||
|
||||
pub struct CFString(pub(super) CFStringRef);
|
||||
|
||||
impl CFString {
|
||||
pub fn new(s: &str) -> Result<Self> {
|
||||
let key = unsafe {
|
||||
CFStringCreateWithBytesNoCopy(
|
||||
kCFAllocatorDefault,
|
||||
s.as_ptr(),
|
||||
s.len() as _,
|
||||
kCFStringEncodingUTF8,
|
||||
false as _,
|
||||
kCFAllocatorNull,
|
||||
)
|
||||
};
|
||||
if key.is_null() {
|
||||
bail!("Allocation failed while creating CFString");
|
||||
}
|
||||
Ok(Self(key))
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize { unsafe { CFStringGetLength(self.0) as _ } }
|
||||
|
||||
pub fn is_empty(&self) -> bool { self.len() == 0 }
|
||||
|
||||
pub fn os_string(&self) -> Result<OsString> {
|
||||
let len = self.len();
|
||||
let capacity =
|
||||
unsafe { CFStringGetMaximumSizeForEncoding(len as _, kCFStringEncodingUTF8) } + 1;
|
||||
|
||||
let mut out: Vec<u8> = Vec::with_capacity(capacity as usize);
|
||||
let result = unsafe {
|
||||
CFStringGetCString(self.0, out.as_mut_ptr().cast(), capacity, kCFStringEncodingUTF8)
|
||||
};
|
||||
if result == 0 {
|
||||
bail!("Failed to get the C string from CFString");
|
||||
}
|
||||
|
||||
unsafe { out.set_len(strlen(out.as_ptr().cast())) };
|
||||
out.shrink_to_fit();
|
||||
Ok(OsString::from_vec(out))
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for CFString {
|
||||
type Target = CFStringRef;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.0 }
|
||||
}
|
||||
|
||||
impl Drop for CFString {
|
||||
fn drop(&mut self) { unsafe { CFRelease(self.0 as _) }; }
|
||||
}
|
||||
44
yazi-ffi/src/disk_arbitration.rs
Normal file
44
yazi-ffi/src/disk_arbitration.rs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
use std::ffi::{c_char, c_void};
|
||||
|
||||
use core_foundation_sys::{array::CFArrayRef, base::CFAllocatorRef, dictionary::CFDictionaryRef, runloop::CFRunLoopRef, string::CFStringRef};
|
||||
|
||||
#[link(name = "DiskArbitration", kind = "framework")]
|
||||
extern "C" {
|
||||
pub fn DASessionCreate(allocator: CFAllocatorRef) -> *const c_void;
|
||||
|
||||
pub fn DADiskCreateFromBSDName(
|
||||
allocator: CFAllocatorRef,
|
||||
session: *const c_void,
|
||||
path: *const c_char,
|
||||
) -> *const c_void;
|
||||
|
||||
pub fn DADiskCopyDescription(disk: *const c_void) -> CFDictionaryRef;
|
||||
|
||||
pub fn DARegisterDiskAppearedCallback(
|
||||
session: *const c_void,
|
||||
match_: CFDictionaryRef,
|
||||
callback: extern "C" fn(disk: *const c_void, context: *mut c_void),
|
||||
context: *mut c_void,
|
||||
);
|
||||
|
||||
pub fn DARegisterDiskDescriptionChangedCallback(
|
||||
session: *const c_void,
|
||||
match_: CFDictionaryRef,
|
||||
watch: CFArrayRef,
|
||||
callback: extern "C" fn(disk: *const c_void, keys: CFArrayRef, context: *mut c_void),
|
||||
context: *mut c_void,
|
||||
);
|
||||
|
||||
pub fn DARegisterDiskDisappearedCallback(
|
||||
session: *const c_void,
|
||||
match_: CFDictionaryRef,
|
||||
callback: extern "C" fn(disk: *const c_void, context: *mut c_void),
|
||||
context: *mut c_void,
|
||||
);
|
||||
|
||||
pub fn DASessionScheduleWithRunLoop(
|
||||
session: *const c_void,
|
||||
runLoop: CFRunLoopRef,
|
||||
runLoopMode: CFStringRef,
|
||||
);
|
||||
}
|
||||
26
yazi-ffi/src/io_kit.rs
Normal file
26
yazi-ffi/src/io_kit.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
use std::ffi::c_char;
|
||||
|
||||
use core_foundation_sys::{base::{CFAllocatorRef, CFTypeRef, mach_port_t}, dictionary::CFMutableDictionaryRef, string::CFStringRef};
|
||||
use libc::kern_return_t;
|
||||
|
||||
#[link(name = "IOKit", kind = "framework")]
|
||||
extern "C" {
|
||||
pub fn IOServiceGetMatchingServices(
|
||||
mainPort: mach_port_t,
|
||||
matching: CFMutableDictionaryRef,
|
||||
existing: *mut mach_port_t,
|
||||
) -> kern_return_t;
|
||||
|
||||
pub fn IOServiceMatching(a: *const c_char) -> CFMutableDictionaryRef;
|
||||
|
||||
pub fn IOIteratorNext(iterator: mach_port_t) -> mach_port_t;
|
||||
|
||||
pub fn IORegistryEntryCreateCFProperty(
|
||||
entry: mach_port_t,
|
||||
key: CFStringRef,
|
||||
allocator: CFAllocatorRef,
|
||||
options: u32,
|
||||
) -> CFTypeRef;
|
||||
|
||||
pub fn IOObjectRelease(obj: mach_port_t) -> kern_return_t;
|
||||
}
|
||||
2
yazi-ffi/src/lib.rs
Normal file
2
yazi-ffi/src/lib.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#[cfg(target_os = "macos")]
|
||||
yazi_macro::mod_flat!(cf_dict cf_string disk_arbitration io_kit);
|
||||
|
|
@ -1 +1 @@
|
|||
yazi_macro::mod_flat!(preview);
|
||||
yazi_macro::mod_flat!(modal preview);
|
||||
|
|
|
|||
30
yazi-fm/src/manager/modal.rs
Normal file
30
yazi-fm/src/manager/modal.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
use mlua::{ObjectLike, Table};
|
||||
use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget};
|
||||
use tracing::error;
|
||||
use yazi_plugin::{LUA, elements::render_once};
|
||||
|
||||
use crate::Ctx;
|
||||
|
||||
pub(crate) struct Modal<'a> {
|
||||
cx: &'a Ctx,
|
||||
}
|
||||
|
||||
impl<'a> Modal<'a> {
|
||||
#[inline]
|
||||
pub(crate) fn new(cx: &'a Ctx) -> Self { Self { cx } }
|
||||
}
|
||||
|
||||
impl Widget for Modal<'_> {
|
||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||
let mut f = || {
|
||||
let area = yazi_plugin::elements::Rect::from(area);
|
||||
let root = LUA.globals().raw_get::<Table>("Modal")?.call_method::<Table>("new", area)?;
|
||||
|
||||
render_once(root.call_method("children_redraw", ())?, buf, |p| self.cx.manager.area(p));
|
||||
Ok::<_, mlua::Error>(())
|
||||
};
|
||||
if let Err(e) = f() {
|
||||
error!("Failed to redraw the `Modal` component:\n{e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@ impl Widget for Root<'_> {
|
|||
}
|
||||
|
||||
manager::Preview::new(self.cx).render(area, buf);
|
||||
manager::Modal::new(self.cx).render(area, buf);
|
||||
|
||||
if self.cx.tasks.visible {
|
||||
tasks::Tasks::new(self.cx).render(area, buf);
|
||||
|
|
|
|||
|
|
@ -9,18 +9,22 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-ffi = { path = "../yazi-ffi", version = "0.4.3" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "0.4.3" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.4.3" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
arc-swap = "1.7.1"
|
||||
bitflags = { workspace = true }
|
||||
dirs = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
regex = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
anyhow = { workspace = true }
|
||||
arc-swap = "1.7.1"
|
||||
bitflags = { workspace = true }
|
||||
dirs = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
parking_lot = { workspace = true }
|
||||
regex = { workspace = true }
|
||||
scopeguard = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
libc = { workspace = true }
|
||||
|
|
@ -28,3 +32,7 @@ uzers = { workspace = true }
|
|||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
windows-sys = { version = "0.59.0", features = [ "Win32_Storage_FileSystem" ] }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
core-foundation-sys = { workspace = true }
|
||||
objc = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ pub struct Cha {
|
|||
#[cfg(unix)]
|
||||
pub mode: libc::mode_t,
|
||||
#[cfg(unix)]
|
||||
pub dev: libc::dev_t,
|
||||
#[cfg(unix)]
|
||||
pub uid: libc::uid_t,
|
||||
#[cfg(unix)]
|
||||
pub gid: libc::gid_t,
|
||||
|
|
@ -64,6 +66,11 @@ impl From<Metadata> for Cha {
|
|||
m.permissions().mode() as _
|
||||
},
|
||||
#[cfg(unix)]
|
||||
dev: {
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
m.dev() as _
|
||||
},
|
||||
#[cfg(unix)]
|
||||
uid: {
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
m.uid() as _
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use tokio::{fs::{self, DirEntry}, select, sync::mpsc::{self, UnboundedReceiver}}
|
|||
use yazi_shared::{Id, url::{Url, Urn, UrnBuf}};
|
||||
|
||||
use super::{FilesSorter, Filter};
|
||||
use crate::{Cha, FILES_TICKET, File, FilesOp, SortBy, maybe_exists};
|
||||
use crate::{Cha, FILES_TICKET, File, FilesOp, SortBy, maybe_exists, mounts::PARTITIONS};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Files {
|
||||
|
|
@ -84,10 +84,9 @@ impl Files {
|
|||
pub async fn assert_stale(cwd: &Url, cha: Cha) -> Option<Cha> {
|
||||
match fs::metadata(cwd).await.map(Cha::from) {
|
||||
Ok(c) if !c.is_dir() => {
|
||||
// TODO: use `ErrorKind::NotADirectory` instead once it gets stabilized
|
||||
FilesOp::IOErr(cwd.clone(), std::io::ErrorKind::AlreadyExists).emit();
|
||||
FilesOp::IOErr(cwd.clone(), std::io::ErrorKind::NotADirectory).emit();
|
||||
}
|
||||
Ok(c) if c.hits(cha) => {}
|
||||
Ok(c) if c.hits(cha) && PARTITIONS.read().heuristic(cha) => {}
|
||||
Ok(c) => return Some(c),
|
||||
Err(e) => {
|
||||
if maybe_exists(cwd).await {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
#![allow(clippy::if_same_then_else, clippy::option_map_unit_fn)]
|
||||
|
||||
yazi_macro::mod_pub!(mounts);
|
||||
|
||||
yazi_macro::mod_flat!(cha cwd file files filter fns op path sorter sorting stage step xdg);
|
||||
|
||||
pub fn init() { CWD.init(<_>::default()); }
|
||||
pub fn init() {
|
||||
CWD.init(<_>::default());
|
||||
|
||||
mounts::init();
|
||||
}
|
||||
|
|
|
|||
151
yazi-fs/src/mounts/linux.rs
Normal file
151
yazi-fs/src/mounts/linux.rs
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
use std::{borrow::Cow, collections::{HashMap, HashSet}, ffi::{OsStr, OsString}, os::{fd::AsFd, unix::{ffi::OsStrExt, fs::MetadataExt}}, time::Duration};
|
||||
|
||||
use anyhow::Result;
|
||||
use tokio::{io::{Interest, unix::AsyncFd}, time::sleep};
|
||||
use tracing::error;
|
||||
use yazi_shared::replace_cow;
|
||||
|
||||
use super::{Locked, Partition, Partitions};
|
||||
|
||||
impl Partitions {
|
||||
pub fn monitor<F>(me: Locked, cb: F)
|
||||
where
|
||||
F: Fn() + Copy + Send + 'static,
|
||||
{
|
||||
async fn wait_mounts(me: Locked, cb: impl Fn()) -> Result<()> {
|
||||
let f = std::fs::File::open("/proc/mounts")?;
|
||||
let fd = AsyncFd::with_interest(f.as_fd(), Interest::READABLE)?;
|
||||
loop {
|
||||
let mut guard = fd.readable().await?;
|
||||
guard.clear_ready();
|
||||
Partitions::update(me.clone()).await;
|
||||
cb();
|
||||
}
|
||||
}
|
||||
|
||||
async fn wait_partitions(me: Locked, cb: impl Fn()) -> Result<()> {
|
||||
loop {
|
||||
let partitions = Partitions::partitions()?;
|
||||
if me.read().linux_cache == partitions {
|
||||
sleep(Duration::from_secs(3)).await;
|
||||
continue;
|
||||
}
|
||||
|
||||
me.write().linux_cache = partitions;
|
||||
Partitions::update(me.clone()).await;
|
||||
|
||||
cb();
|
||||
sleep(Duration::from_secs(3)).await;
|
||||
}
|
||||
}
|
||||
|
||||
let me_ = me.clone();
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
if let Err(e) = wait_mounts(me_.clone(), cb).await {
|
||||
error!("Error encountered while monitoring `/proc/mounts`: {e:?}");
|
||||
}
|
||||
sleep(Duration::from_secs(5)).await;
|
||||
}
|
||||
});
|
||||
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
if let Err(e) = wait_partitions(me.clone(), cb).await {
|
||||
error!("Error encountered while monitoring `/proc/partitions`: {e:?}");
|
||||
}
|
||||
sleep(Duration::from_secs(5)).await;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async fn update(me: Locked) {
|
||||
_ = tokio::task::spawn_blocking(move || {
|
||||
let mut guard = me.write();
|
||||
match Self::all(&guard) {
|
||||
Ok(new) => guard.inner = new,
|
||||
Err(e) => error!("Error encountered while updating mount points: {e:?}"),
|
||||
};
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
fn all(&self) -> Result<Vec<Partition>> {
|
||||
let mut mounts = Self::mounts()?;
|
||||
{
|
||||
let set = &self.linux_cache;
|
||||
let mut set: HashSet<&OsStr> = set.iter().map(AsRef::as_ref).collect();
|
||||
mounts.iter().filter_map(|p| p.dev_name()).for_each(|s| _ = set.remove(s));
|
||||
mounts.extend(set.into_iter().map(Partition::new));
|
||||
};
|
||||
|
||||
let labels = Self::labels()?;
|
||||
for mount in &mut mounts {
|
||||
if !mount.src.as_bytes().starts_with(b"/dev/") {
|
||||
continue;
|
||||
}
|
||||
if let Ok(meta) = std::fs::metadata(&mount.src) {
|
||||
mount.rdev = Some(meta.rdev() as _);
|
||||
mount.label = labels.get(&(meta.dev(), meta.ino())).cloned();
|
||||
}
|
||||
}
|
||||
Ok(mounts)
|
||||
}
|
||||
|
||||
fn mounts() -> Result<Vec<Partition>> {
|
||||
let mut vec = vec![];
|
||||
let s = std::fs::read_to_string("/proc/mounts")?;
|
||||
for line in s.lines() {
|
||||
let mut it = line.split_whitespace();
|
||||
let Some(src) = it.next() else { continue };
|
||||
let Some(dist) = it.next() else { continue };
|
||||
let Some(fstype) = it.next() else { continue };
|
||||
vec.push(Partition {
|
||||
src: Self::unmangle_octal(src).into_owned().into(),
|
||||
dist: Some(Self::unmangle_octal(dist).into_owned().into()),
|
||||
fstype: Some(Self::unmangle_octal(fstype).into_owned().into()),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
|
||||
fn partitions() -> Result<HashSet<String>> {
|
||||
let mut set = HashSet::new();
|
||||
let s = std::fs::read_to_string("/proc/partitions")?;
|
||||
for line in s.lines().skip(2) {
|
||||
let mut it = line.split_whitespace();
|
||||
let Some(Ok(_major)) = it.next().map(|s| s.parse::<u16>()) else { continue };
|
||||
let Some(Ok(_minor)) = it.next().map(|s| s.parse::<u16>()) else { continue };
|
||||
let Some(Ok(_blocks)) = it.next().map(|s| s.parse::<u16>()) else { continue };
|
||||
if let Some(name) = it.next() {
|
||||
set.insert(Self::unmangle_octal(name).into_owned());
|
||||
}
|
||||
}
|
||||
Ok(set)
|
||||
}
|
||||
|
||||
fn labels() -> Result<HashMap<(u64, u64), OsString>> {
|
||||
let mut map = HashMap::new();
|
||||
for entry in std::fs::read_dir("/dev/disk/by-label")?.flatten() {
|
||||
let meta = std::fs::metadata(entry.path())?;
|
||||
map.insert((meta.dev(), meta.ino()), entry.file_name());
|
||||
}
|
||||
Ok(map)
|
||||
}
|
||||
|
||||
// Unmangle '\t', '\n', ' ', '#', and r'\'
|
||||
// https://elixir.bootlin.com/linux/v6.13-rc3/source/fs/proc_namespace.c#L89
|
||||
fn unmangle_octal(s: &str) -> Cow<str> {
|
||||
let mut s = Cow::Borrowed(s);
|
||||
for (a, b) in
|
||||
[(r"\011", "\t"), (r"\012", "\n"), (r"\040", " "), (r"\043", "#"), (r"\134", r"\")]
|
||||
{
|
||||
s = match replace_cow(&s, a, b) {
|
||||
Cow::Borrowed(_) => s,
|
||||
Cow::Owned(new) => Cow::Owned(new),
|
||||
};
|
||||
}
|
||||
s
|
||||
}
|
||||
}
|
||||
169
yazi-fs/src/mounts/macos.rs
Normal file
169
yazi-fs/src/mounts/macos.rs
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
use std::{ffi::{CStr, CString, OsString, c_void}, mem, os::unix::{ffi::OsStringExt, fs::MetadataExt}};
|
||||
|
||||
use anyhow::{Result, bail};
|
||||
use core_foundation_sys::{array::CFArrayRef, base::{CFRelease, kCFAllocatorDefault}, runloop::{CFRunLoopGetCurrent, CFRunLoopRun, kCFRunLoopDefaultMode}};
|
||||
use libc::{c_char, mach_port_t};
|
||||
use objc::{msg_send, runtime::Object, sel, sel_impl};
|
||||
use scopeguard::defer;
|
||||
use tracing::error;
|
||||
use yazi_ffi::{CFDict, CFString, DADiskCopyDescription, DADiskCreateFromBSDName, DARegisterDiskAppearedCallback, DARegisterDiskDescriptionChangedCallback, DARegisterDiskDisappearedCallback, DASessionCreate, DASessionScheduleWithRunLoop, IOIteratorNext, IOObjectRelease, IORegistryEntryCreateCFProperty, IOServiceGetMatchingServices, IOServiceMatching};
|
||||
|
||||
use super::{Locked, Partition, Partitions};
|
||||
|
||||
impl Partitions {
|
||||
pub fn monitor<F>(me: Locked, cb: F)
|
||||
where
|
||||
F: Fn() + Copy + Send + 'static,
|
||||
{
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let session = unsafe { DASessionCreate(kCFAllocatorDefault) };
|
||||
if session.is_null() {
|
||||
return error!("Cannot create a disk arbitration session");
|
||||
}
|
||||
defer! { unsafe { CFRelease(session) } };
|
||||
|
||||
extern "C" fn on_appeared(_disk: *const c_void, context: *mut c_void) {
|
||||
let boxed = context as *mut Box<dyn Fn()>;
|
||||
unsafe { (*boxed)() }
|
||||
}
|
||||
|
||||
extern "C" fn on_changed(_disk: *const c_void, _keys: CFArrayRef, context: *mut c_void) {
|
||||
let boxed = context as *mut Box<dyn Fn()>;
|
||||
unsafe { (*boxed)() }
|
||||
}
|
||||
|
||||
extern "C" fn on_disappeared(_disk: *const c_void, context: *mut c_void) {
|
||||
let boxed = context as *mut Box<dyn Fn()>;
|
||||
unsafe { (*boxed)() }
|
||||
}
|
||||
|
||||
let create_context = || {
|
||||
let me = me.clone();
|
||||
let boxed: Box<dyn Fn()> = Box::new(move || {
|
||||
if mem::replace(&mut me.write().need_update, true) {
|
||||
return;
|
||||
}
|
||||
Self::update(me.clone(), cb);
|
||||
});
|
||||
Box::into_raw(Box::new(boxed)) as *mut c_void
|
||||
};
|
||||
|
||||
unsafe {
|
||||
DARegisterDiskAppearedCallback(session, std::ptr::null(), on_appeared, create_context());
|
||||
DARegisterDiskDescriptionChangedCallback(
|
||||
session,
|
||||
std::ptr::null(),
|
||||
std::ptr::null(),
|
||||
on_changed,
|
||||
create_context(),
|
||||
);
|
||||
DARegisterDiskDisappearedCallback(
|
||||
session,
|
||||
std::ptr::null(),
|
||||
on_disappeared,
|
||||
create_context(),
|
||||
);
|
||||
DASessionScheduleWithRunLoop(session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
CFRunLoopRun();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn update(me: Locked, cb: impl Fn() + Send + 'static) {
|
||||
_ = tokio::task::spawn_blocking(move || {
|
||||
let result = Self::all_names().and_then(Self::all_partitions);
|
||||
if let Err(ref e) = result {
|
||||
error!("Error encountered while updating mount points: {e:?}");
|
||||
}
|
||||
|
||||
let mut guard = me.write();
|
||||
if let Ok(new) = result {
|
||||
guard.inner = new;
|
||||
}
|
||||
guard.need_update = false;
|
||||
|
||||
drop(guard);
|
||||
cb();
|
||||
});
|
||||
}
|
||||
|
||||
fn all_partitions(names: Vec<CString>) -> Result<Vec<Partition>> {
|
||||
let session = unsafe { DASessionCreate(kCFAllocatorDefault) };
|
||||
if session.is_null() {
|
||||
bail!("Cannot create a disk arbitration session");
|
||||
}
|
||||
defer! { unsafe { CFRelease(session) } };
|
||||
|
||||
let mut disks = Vec::with_capacity(names.len());
|
||||
for name in names {
|
||||
let disk = unsafe { DADiskCreateFromBSDName(kCFAllocatorDefault, session, name.as_ptr()) };
|
||||
if disk.is_null() {
|
||||
continue;
|
||||
}
|
||||
|
||||
defer! { unsafe { CFRelease(disk) } };
|
||||
let Ok(dict) = CFDict::take(unsafe { DADiskCopyDescription(disk) }) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let partition = Partition::new(&OsString::from_vec(name.into_bytes()));
|
||||
let rdev = std::fs::metadata(&partition.src).map(|m| m.rdev() as _).ok();
|
||||
disks.push(Partition {
|
||||
dist: dict.path_buf("DAVolumePath").ok(),
|
||||
rdev,
|
||||
fstype: dict.os_string("DAVolumeKind").ok(),
|
||||
label: dict.os_string("DAVolumeName").ok(),
|
||||
capacity: dict.integer("DAMediaSize").unwrap_or_default() as u64,
|
||||
..partition
|
||||
});
|
||||
}
|
||||
|
||||
Ok(disks)
|
||||
}
|
||||
|
||||
fn all_names() -> Result<Vec<CString>> {
|
||||
let mut iterator: mach_port_t = 0;
|
||||
let result = unsafe {
|
||||
IOServiceGetMatchingServices(0, IOServiceMatching(c"IOService".as_ptr()), &mut iterator)
|
||||
};
|
||||
|
||||
if result != 0 {
|
||||
bail!("Cannot get the IO matching services");
|
||||
}
|
||||
defer! { unsafe { IOObjectRelease(iterator); } };
|
||||
|
||||
let mut names = vec![];
|
||||
loop {
|
||||
let service = unsafe { IOIteratorNext(iterator) };
|
||||
if service == 0 {
|
||||
break;
|
||||
}
|
||||
defer! { unsafe { IOObjectRelease(service); } };
|
||||
if let Some(name) = Self::bsd_name(service).ok().filter(|s| s.as_bytes().starts_with(b"disk"))
|
||||
{
|
||||
names.push(name);
|
||||
}
|
||||
}
|
||||
|
||||
names.sort_unstable();
|
||||
Ok(names)
|
||||
}
|
||||
|
||||
fn bsd_name(service: mach_port_t) -> Result<CString> {
|
||||
let key = CFString::new("BSD Name")?;
|
||||
let property =
|
||||
unsafe { IORegistryEntryCreateCFProperty(service, *key, kCFAllocatorDefault, 1) };
|
||||
if property.is_null() {
|
||||
bail!("Cannot get the name property");
|
||||
}
|
||||
defer! { unsafe { CFRelease(property) } };
|
||||
|
||||
#[allow(unexpected_cfgs)]
|
||||
let cstr: *const c_char = unsafe { msg_send![property as *const Object, UTF8String] };
|
||||
Ok(if cstr.is_null() {
|
||||
bail!("Invalid value for the name property");
|
||||
} else {
|
||||
CString::from(unsafe { CStr::from_ptr(cstr) })
|
||||
})
|
||||
}
|
||||
}
|
||||
9
yazi-fs/src/mounts/mod.rs
Normal file
9
yazi-fs/src/mounts/mod.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
yazi_macro::mod_flat!(partition partitions);
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
yazi_macro::mod_flat!(linux);
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
yazi_macro::mod_flat!(macos);
|
||||
|
||||
pub(super) fn init() { PARTITIONS.init(<_>::default()); }
|
||||
50
yazi-fs/src/mounts/partition.rs
Normal file
50
yazi-fs/src/mounts/partition.rs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
use std::{ffi::{OsStr, OsString}, path::PathBuf};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Partition {
|
||||
pub src: OsString,
|
||||
pub dist: Option<PathBuf>,
|
||||
#[cfg(unix)]
|
||||
pub rdev: Option<libc::dev_t>,
|
||||
pub label: Option<OsString>,
|
||||
pub fstype: Option<OsString>,
|
||||
pub capacity: u64,
|
||||
}
|
||||
|
||||
impl Partition {
|
||||
pub fn heuristic(&self) -> bool {
|
||||
let b: &[u8] = self.fstype.as_ref().map_or(b"", |s| s.as_encoded_bytes());
|
||||
!matches!(b, b"exfat" | b"fuse.rclone")
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub fn systemic(&self) -> bool {
|
||||
let b: &[u8] = self.fstype.as_ref().map_or(b"", |s| s.as_encoded_bytes());
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
matches!(b, b"autofs" | b"binfmt_misc" | b"bpf" | b"cgroup2" | b"configfs" | b"debugfs" | b"devpts" | b"devtmpfs" | b"fuse.gvfsd-fuse" | b"fusectl" | b"hugetlbfs" | b"mqueue" | b"proc" | b"ramfs" | b"securityfs" | b"sysfs" | b"tmpfs")
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
b.is_empty()
|
||||
}
|
||||
#[cfg(not(any(target_os = "linux", target_os = "macos")))]
|
||||
{
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Partition {
|
||||
#[inline]
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
pub(super) fn new(name: &OsStr) -> Self {
|
||||
Self { src: std::path::Path::new("/dev/").join(name).into(), ..Default::default() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_os = "linux")]
|
||||
pub(super) fn dev_name(&self) -> Option<&OsStr> {
|
||||
std::path::Path::new(&self.src).strip_prefix("/dev/").ok().map(|p| p.as_os_str())
|
||||
}
|
||||
}
|
||||
45
yazi-fs/src/mounts/partitions.rs
Normal file
45
yazi-fs/src/mounts/partitions.rs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
use std::{ops::Deref, sync::Arc};
|
||||
|
||||
use parking_lot::RwLock;
|
||||
use yazi_shared::RoCell;
|
||||
|
||||
use super::Partition;
|
||||
use crate::Cha;
|
||||
|
||||
pub(super) type Locked = Arc<RwLock<Partitions>>;
|
||||
|
||||
pub static PARTITIONS: RoCell<Locked> = RoCell::new();
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Partitions {
|
||||
pub(super) inner: Vec<Partition>,
|
||||
#[cfg(target_os = "linux")]
|
||||
pub(super) linux_cache: std::collections::HashSet<String>,
|
||||
#[cfg(target_os = "macos")]
|
||||
pub(super) need_update: bool,
|
||||
}
|
||||
|
||||
impl Deref for Partitions {
|
||||
type Target = Vec<Partition>;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
|
||||
impl Partitions {
|
||||
#[inline]
|
||||
#[cfg(unix)]
|
||||
pub fn by_dev(&self, dev: libc::dev_t) -> Option<&Partition> {
|
||||
self.inner.iter().find(|p| p.rdev == Some(dev))
|
||||
}
|
||||
|
||||
pub fn heuristic(&self, cha: Cha) -> bool {
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
{
|
||||
self.by_dev(cha.dev).is_none_or(|p| p.heuristic())
|
||||
}
|
||||
#[cfg(not(any(target_os = "linux", target_os = "macos")))]
|
||||
{
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,13 +15,7 @@ function Modal:reflow()
|
|||
return components
|
||||
end
|
||||
|
||||
function Modal:redraw()
|
||||
local elements = {}
|
||||
for _, child in ipairs(self._children) do
|
||||
elements = ya.list_merge(elements, ya.redraw_with(child[1]:new(self._area)))
|
||||
end
|
||||
return elements
|
||||
end
|
||||
function Modal:redraw() return {} end
|
||||
|
||||
-- Children
|
||||
function Modal:children_add(tbl, order)
|
||||
|
|
@ -40,3 +34,11 @@ function Modal:children_remove(id)
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Modal:children_redraw()
|
||||
local elements = {}
|
||||
for _, child in ipairs(self._children) do
|
||||
elements = ya.list_merge(elements, ya.redraw_with(child[1]:new(self._area)))
|
||||
end
|
||||
return elements
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{ops::Deref, time::{Duration, SystemTime, UNIX_EPOCH}};
|
||||
use std::{ops::{Deref, Not}, time::{Duration, SystemTime, UNIX_EPOCH}};
|
||||
|
||||
use mlua::{ExternalError, FromLua, IntoLua, Lua, Table, UserData, UserDataFields, UserDataMethods};
|
||||
use yazi_fs::ChaKind;
|
||||
|
|
@ -44,6 +44,8 @@ impl Cha {
|
|||
#[cfg(unix)]
|
||||
mode: t.raw_get("mode").unwrap_or_default(),
|
||||
#[cfg(unix)]
|
||||
dev: t.raw_get("dev").unwrap_or_default(),
|
||||
#[cfg(unix)]
|
||||
uid: t.raw_get("uid").unwrap_or_default(),
|
||||
#[cfg(unix)]
|
||||
gid: t.raw_get("gid").unwrap_or_default(),
|
||||
|
|
@ -72,9 +74,10 @@ impl UserData for Cha {
|
|||
|
||||
#[cfg(unix)]
|
||||
{
|
||||
fields.add_field_method_get("uid", |_, me| Ok((!me.is_dummy()).then_some(me.uid)));
|
||||
fields.add_field_method_get("gid", |_, me| Ok((!me.is_dummy()).then_some(me.gid)));
|
||||
fields.add_field_method_get("nlink", |_, me| Ok((!me.is_dummy()).then_some(me.nlink)));
|
||||
fields.add_field_method_get("dev", |_, me| Ok(me.is_dummy().not().then_some(me.dev)));
|
||||
fields.add_field_method_get("uid", |_, me| Ok(me.is_dummy().not().then_some(me.uid)));
|
||||
fields.add_field_method_get("gid", |_, me| Ok(me.is_dummy().not().then_some(me.gid)));
|
||||
fields.add_field_method_get("nlink", |_, me| Ok(me.is_dummy().not().then_some(me.nlink)));
|
||||
}
|
||||
|
||||
fields.add_field_method_get("len", |_, me| Ok(me.len));
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ pub struct MpscUnboundedRx(pub tokio::sync::mpsc::UnboundedReceiver<Value>);
|
|||
impl UserData for MpscUnboundedTx {
|
||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_method("send", |lua, me, value: Value| match me.0.send(value) {
|
||||
Ok(()) => (true, Value::Nil).into_lua_multi(&lua),
|
||||
Err(e) => (false, Error::Custom(e.to_string())).into_lua_multi(&lua),
|
||||
Ok(()) => (true, Value::Nil).into_lua_multi(lua),
|
||||
Err(e) => (false, Error::Custom(e.to_string())).into_lua_multi(lua),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -60,10 +60,8 @@ impl UserData for OneshotTx {
|
|||
return Err("Oneshot sender already used".into_lua_err());
|
||||
};
|
||||
match tx.send(value) {
|
||||
Ok(()) => (true, Value::Nil).into_lua_multi(&lua),
|
||||
Err(_) => {
|
||||
(false, Error::Custom("Oneshot receiver closed".to_string())).into_lua_multi(&lua)
|
||||
}
|
||||
Ok(()) => (true, Value::Nil).into_lua_multi(lua),
|
||||
Err(_) => (false, Error::Custom("Oneshot receiver closed".to_string())).into_lua_multi(lua),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use globset::GlobBuilder;
|
||||
use mlua::{ExternalError, ExternalResult, Function, IntoLua, IntoLuaMulti, Lua, MetaMethod, Table, Value};
|
||||
use tokio::fs;
|
||||
use yazi_fs::remove_dir_clean;
|
||||
use yazi_fs::{mounts::PARTITIONS, remove_dir_clean};
|
||||
|
||||
use crate::{Error, bindings::{Cast, Cha}, file::File, url::{Url, UrlRef}};
|
||||
|
||||
|
|
@ -15,6 +15,7 @@ pub fn compose(lua: &Lua) -> mlua::Result<Table> {
|
|||
b"remove" => remove(lua)?,
|
||||
b"read_dir" => read_dir(lua)?,
|
||||
b"unique_name" => unique_name(lua)?,
|
||||
b"partitions" => partitions(lua)?,
|
||||
_ => return Ok(Value::Nil),
|
||||
}
|
||||
.into_lua(lua)?;
|
||||
|
|
@ -156,3 +157,21 @@ fn unique_name(lua: &Lua) -> mlua::Result<Function> {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn partitions(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_async_function(|lua, ()| async move {
|
||||
PARTITIONS
|
||||
.read()
|
||||
.iter()
|
||||
.filter(|&p| !p.systemic())
|
||||
.map(|p| {
|
||||
lua.create_table_from([
|
||||
("src", p.src.clone().into_lua(&lua)?),
|
||||
("dist", p.dist.clone().into_lua(&lua)?),
|
||||
("label", p.label.clone().into_lua(&lua)?),
|
||||
("fstype", p.fstype.clone().into_lua(&lua)?),
|
||||
])
|
||||
})
|
||||
.collect::<mlua::Result<Vec<Table>>>()
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
|||
description = "Yazi shared library"
|
||||
homepage = "https://yazi-rs.github.io"
|
||||
repository = "https://github.com/sxyazi/yazi"
|
||||
rust-version = "1.78.0"
|
||||
rust-version = "1.83.0"
|
||||
|
||||
[dependencies]
|
||||
yazi-macro = { path = "../yazi-macro", version = "0.4.3" }
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue