mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: prepare for Windows (#44)
This commit is contained in:
parent
b70f83ced7
commit
47846932d4
30 changed files with 376 additions and 192 deletions
169
Cargo.lock
generated
169
Cargo.lock
generated
|
|
@ -118,9 +118,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.73"
|
||||
version = "1.0.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f768393e7fabd388fe8409b13faa4d93ab0fef35db1508438dfdb066918bcf38"
|
||||
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||
|
||||
[[package]]
|
||||
name = "app"
|
||||
|
|
@ -277,9 +277,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.3.21"
|
||||
version = "4.3.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c27cdf28c0f604ba3f512b0c9a409f8de8513e4816705deb0498b627e7c3a3fd"
|
||||
checksum = "b417ae4361bca3f5de378294fc7472d3c4ed86a5ef9f49e93ae722f432aae8d2"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
|
@ -288,9 +288,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.3.21"
|
||||
version = "4.3.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08a9f1ab5e9f01a9b81f202e8562eb9a10de70abf9eaeac1be465c28b75aa4aa"
|
||||
checksum = "9c90dc0f0e42c64bff177ca9d7be6fcc9ddb0f26a6e062174a61c84dd6c644d4"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
|
@ -307,7 +307,7 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -344,6 +344,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"clap",
|
||||
"crossterm 0.27.0",
|
||||
"dirs",
|
||||
"futures",
|
||||
"glob",
|
||||
"indexmap 2.0.0",
|
||||
|
|
@ -355,7 +356,6 @@ dependencies = [
|
|||
"shell-words",
|
||||
"toml",
|
||||
"validator",
|
||||
"xdg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -515,6 +515,27 @@ dependencies = [
|
|||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.9.0"
|
||||
|
|
@ -587,7 +608,7 @@ checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0"
|
|||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"redox_syscall 0.3.5",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
|
|
@ -694,7 +715,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1212,6 +1233,12 @@ dependencies = [
|
|||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "option-ext"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
|
|
@ -1236,9 +1263,9 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
|
|||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"redox_syscall 0.3.5",
|
||||
"smallvec",
|
||||
"windows-targets 0.48.2",
|
||||
"windows-targets 0.48.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1270,7 +1297,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1371,9 +1398,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.32"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
|
@ -1415,6 +1442,15 @@ dependencies = [
|
|||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.3.5"
|
||||
|
|
@ -1424,6 +1460,17 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall 0.2.16",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.9.3"
|
||||
|
|
@ -1516,14 +1563,14 @@ checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.104"
|
||||
version = "1.0.105"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c"
|
||||
checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
|
@ -1667,9 +1714,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.28"
|
||||
version = "2.0.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567"
|
||||
checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -1699,22 +1746,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.45"
|
||||
version = "1.0.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dedd246497092a89beedfe2c9f176d44c1b672ea6090edc20544ade01fbb7ea0"
|
||||
checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.45"
|
||||
version = "1.0.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d7b1fadccbbc7e19ea64708629f9d8dccd007c260d66485f20a6d41bc1cf4b3"
|
||||
checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1783,9 +1830,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.31.0"
|
||||
version = "1.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40de3a2ba249dcb097e01be5e67a5ff53cf250397715a071a81543e8a832a920"
|
||||
checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
|
|
@ -1808,7 +1855,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1877,7 +1924,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2078,7 +2125,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
|
@ -2100,7 +2147,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
|
@ -2163,7 +2210,7 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.2",
|
||||
"windows-targets 0.48.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2181,7 +2228,7 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.2",
|
||||
"windows-targets 0.48.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2201,17 +2248,17 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.2"
|
||||
version = "0.48.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1eeca1c172a285ee6c2c84c341ccea837e7c01b12fbb2d0fe3c9e550ce49ec8"
|
||||
checksum = "27f51fb4c64f8b770a823c043c7fad036323e1c48f55287b7bbb7987b2fcdf3b"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.2",
|
||||
"windows_aarch64_msvc 0.48.2",
|
||||
"windows_i686_gnu 0.48.2",
|
||||
"windows_i686_msvc 0.48.2",
|
||||
"windows_x86_64_gnu 0.48.2",
|
||||
"windows_x86_64_gnullvm 0.48.2",
|
||||
"windows_x86_64_msvc 0.48.2",
|
||||
"windows_aarch64_gnullvm 0.48.3",
|
||||
"windows_aarch64_msvc 0.48.3",
|
||||
"windows_i686_gnu 0.48.3",
|
||||
"windows_i686_msvc 0.48.3",
|
||||
"windows_x86_64_gnu 0.48.3",
|
||||
"windows_x86_64_gnullvm 0.48.3",
|
||||
"windows_x86_64_msvc 0.48.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2222,9 +2269,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
|||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.2"
|
||||
version = "0.48.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b10d0c968ba7f6166195e13d593af609ec2e3d24f916f081690695cf5eaffb2f"
|
||||
checksum = "fde1bb55ae4ce76a597a8566d82c57432bc69c039449d61572a7a353da28f68c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
|
|
@ -2234,9 +2281,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
|||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.2"
|
||||
version = "0.48.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "571d8d4e62f26d4932099a9efe89660e8bd5087775a2ab5cdd8b747b811f1058"
|
||||
checksum = "1513e8d48365a78adad7322fd6b5e4c4e99d92a69db8df2d435b25b1f1f286d4"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
|
|
@ -2246,9 +2293,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
|||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.2"
|
||||
version = "0.48.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2229ad223e178db5fbbc8bd8d3835e51e566b8474bfca58d2e6150c48bb723cd"
|
||||
checksum = "60587c0265d2b842298f5858e1a5d79d146f9ee0c37be5782e92a6eb5e1d7a83"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
|
|
@ -2258,9 +2305,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
|||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.2"
|
||||
version = "0.48.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "600956e2d840c194eedfc5d18f8242bc2e17c7775b6684488af3a9fff6fe3287"
|
||||
checksum = "224fe0e0ffff5d2ea6a29f82026c8f43870038a0ffc247aa95a52b47df381ac4"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
|
|
@ -2270,9 +2317,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
|||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.2"
|
||||
version = "0.48.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea99ff3f8b49fb7a8e0d305e5aec485bd068c2ba691b6e277d29eaeac945868a"
|
||||
checksum = "62fc52a0f50a088de499712cbc012df7ebd94e2d6eb948435449d76a6287e7ad"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
|
|
@ -2282,9 +2329,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
|||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.2"
|
||||
version = "0.48.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f1a05a1ece9a7a0d5a7ccf30ba2c33e3a61a30e042ffd247567d1de1d94120d"
|
||||
checksum = "2093925509d91ea3d69bcd20238f4c2ecdb1a29d3c281d026a09705d0dd35f3d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
|
|
@ -2294,25 +2341,19 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
|||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.2"
|
||||
version = "0.48.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d419259aba16b663966e29e6d7c6ecfa0bb8425818bb96f6f1f3c3eb71a6e7b9"
|
||||
checksum = "b6ade45bc8bf02ae2aa34a9d54ba660a1a58204da34ba793c00d83ca3730b5f1"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.10"
|
||||
version = "0.5.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5504cc7644f4b593cbc05c4a55bf9bd4e94b867c3c0bd440934174d50482427d"
|
||||
checksum = "d09770118a7eb1ccaf4a594a221334119a44a814fcb0d31c5b85e83e97227a97"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xdg"
|
||||
version = "2.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546"
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
|
|
|
|||
|
|
@ -19,10 +19,6 @@ pub struct Adaptor;
|
|||
|
||||
impl Adaptor {
|
||||
pub async fn image_show(mut path: &Path, rect: Rect) -> Result<()> {
|
||||
if IMAGE_SHOWN.swap(true, Ordering::Relaxed) {
|
||||
Self::image_hide(rect).ok();
|
||||
}
|
||||
|
||||
let cache = BOOT.cache(path);
|
||||
if fs::metadata(&cache).await.is_ok() {
|
||||
path = cache.as_path();
|
||||
|
|
@ -35,7 +31,9 @@ impl Adaptor {
|
|||
_ => Ok(if let Some(tx) = &*UEBERZUG {
|
||||
tx.send(Some((path.to_path_buf(), rect)))?;
|
||||
}),
|
||||
}
|
||||
}?;
|
||||
|
||||
Ok(IMAGE_SHOWN.store(true, Ordering::Relaxed))
|
||||
}
|
||||
|
||||
pub fn image_hide(rect: Rect) -> Result<()> {
|
||||
|
|
|
|||
|
|
@ -3,18 +3,19 @@ use std::{path::Path, sync::Arc};
|
|||
use anyhow::Result;
|
||||
use config::PREVIEW;
|
||||
use image::{imageops::FilterType, DynamicImage, ImageFormat};
|
||||
use shared::tty_ratio;
|
||||
use shared::Term;
|
||||
use tokio::fs;
|
||||
|
||||
pub struct Image;
|
||||
|
||||
impl Image {
|
||||
pub(super) async fn crop(path: &Path, size: (u16, u16)) -> Result<DynamicImage> {
|
||||
let (w, h) = {
|
||||
let r = tty_ratio();
|
||||
let (w, h) = ((size.0 as f64 * r.0) as u32, (size.1 as f64 * r.1) as u32);
|
||||
(w.min(PREVIEW.max_width), h.min(PREVIEW.max_height))
|
||||
};
|
||||
let (w, h) = Term::ratio()
|
||||
.map(|(w, h)| {
|
||||
let (w, h) = ((size.0 as f64 * w) as u32, (size.1 as f64 * h) as u32);
|
||||
(w.min(PREVIEW.max_width), h.min(PREVIEW.max_height))
|
||||
})
|
||||
.unwrap_or((PREVIEW.max_width, PREVIEW.max_height));
|
||||
|
||||
let img = fs::read(path).await?;
|
||||
let img = tokio::task::spawn_blocking(move || -> Result<DynamicImage> {
|
||||
|
|
|
|||
|
|
@ -15,21 +15,19 @@ impl Iterm2 {
|
|||
let img = Image::crop(path, (rect.width, rect.height)).await?;
|
||||
let b = Self::encode(img).await?;
|
||||
|
||||
let mut stdout = stdout().lock();
|
||||
Term::move_to(&mut stdout, rect.x, rect.y)?;
|
||||
Ok(stdout.write_all(&b)?)
|
||||
Self::image_hide(rect)?;
|
||||
Term::move_lock(stdout().lock(), (rect.x, rect.y), |stdout| Ok(stdout.write_all(&b)?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn image_hide(rect: Rect) -> Result<()> {
|
||||
let s = " ".repeat(rect.width as usize);
|
||||
let mut stdout = BufWriter::new(stdout().lock());
|
||||
|
||||
for y in rect.top()..=rect.bottom() {
|
||||
Term::move_to(&mut stdout, rect.x, y)?;
|
||||
stdout.write_all(s.as_bytes())?;
|
||||
}
|
||||
Ok(())
|
||||
let stdout = BufWriter::new(stdout().lock());
|
||||
Term::move_lock(stdout, (0, 0), |stdout| {
|
||||
for y in rect.top()..rect.bottom() {
|
||||
Term::move_to(stdout, rect.x, y)?;
|
||||
Term::kill_to_end(stdout)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
async fn encode(img: DynamicImage) -> Result<Vec<u8>> {
|
||||
|
|
|
|||
|
|
@ -15,9 +15,8 @@ impl Kitty {
|
|||
let img = Image::crop(path, (rect.width, rect.height)).await?;
|
||||
let b = Self::encode(img).await?;
|
||||
|
||||
let mut stdout = stdout().lock();
|
||||
Term::move_to(&mut stdout, rect.x, rect.y)?;
|
||||
Ok(stdout.write_all(&b)?)
|
||||
Self::image_hide()?;
|
||||
Term::move_lock(stdout().lock(), (rect.x, rect.y), |stdout| Ok(stdout.write_all(&b)?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -32,7 +31,7 @@ impl Kitty {
|
|||
if let Some(first) = it.next() {
|
||||
write!(
|
||||
buf,
|
||||
"\x1b\\\x1b_Ga=d\x1b\\\x1b_Ga=T,f={},s={},v={},m={};{}\x1b\\",
|
||||
"\x1b_Ga=T,f={},s={},v={},m={};{}\x1b\\",
|
||||
format,
|
||||
size.0,
|
||||
size.1,
|
||||
|
|
|
|||
|
|
@ -15,21 +15,19 @@ impl Sixel {
|
|||
let img = Image::crop(path, (rect.width, rect.height)).await?;
|
||||
let b = Self::encode(img).await?;
|
||||
|
||||
let mut stdout = stdout().lock();
|
||||
Term::move_to(&mut stdout, rect.x, rect.y)?;
|
||||
Ok(stdout.write_all(&b)?)
|
||||
Self::image_hide(rect)?;
|
||||
Term::move_lock(stdout().lock(), (rect.x, rect.y), |stdout| Ok(stdout.write_all(&b)?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn image_hide(rect: Rect) -> Result<()> {
|
||||
let s = " ".repeat(rect.width as usize);
|
||||
let mut stdout = BufWriter::new(stdout().lock());
|
||||
|
||||
for y in rect.top()..=rect.bottom() {
|
||||
Term::move_to(&mut stdout, rect.x, y)?;
|
||||
stdout.write_all(s.as_bytes())?;
|
||||
}
|
||||
Ok(())
|
||||
let stdout = BufWriter::new(stdout().lock());
|
||||
Term::move_lock(stdout, (0, 0), |stdout| {
|
||||
for y in rect.top()..rect.bottom() {
|
||||
Term::move_to(stdout, rect.x, y)?;
|
||||
Term::kill_to_end(stdout)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
async fn encode(img: DynamicImage) -> Result<Vec<u8>> {
|
||||
|
|
|
|||
|
|
@ -10,21 +10,23 @@ core = { path = "../core" }
|
|||
shared = { path = "../shared" }
|
||||
|
||||
# External dependencies
|
||||
ansi-to-tui = "^3"
|
||||
anyhow = "^1"
|
||||
crossterm = { version = "^0", features = [ "event-stream" ] }
|
||||
futures = "^0"
|
||||
libc = "^0"
|
||||
ratatui = "^0"
|
||||
signal-hook-tokio = { version = "^0", features = [ "futures-v0_3" ] }
|
||||
tokio = { version = "^1", features = [ "parking_lot" ] }
|
||||
unicode-width = "^0"
|
||||
ansi-to-tui = "^3"
|
||||
anyhow = "^1"
|
||||
crossterm = { version = "^0", features = [ "event-stream" ] }
|
||||
futures = "^0"
|
||||
ratatui = "^0"
|
||||
tokio = { version = "^1", features = [ "parking_lot" ] }
|
||||
unicode-width = "^0"
|
||||
|
||||
# Logging
|
||||
tracing = "^0"
|
||||
tracing-appender = "^0"
|
||||
tracing-subscriber = "^0"
|
||||
|
||||
[target.'cfg(not(target_os = "windows"))'.dependencies]
|
||||
libc = "^0"
|
||||
signal-hook-tokio = { version = "^0", features = [ "futures-v0_3" ] }
|
||||
|
||||
[[bin]]
|
||||
name = "yazi"
|
||||
path = "src/main.rs"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use core::{emit, files::FilesOp, input::InputMode, Event};
|
||||
use std::{ffi::OsString, os::unix::prelude::OsStrExt};
|
||||
use std::ffi::OsString;
|
||||
|
||||
use anyhow::{Ok, Result};
|
||||
use config::{keymap::{Control, Key, KeymapLayer}, BOOT};
|
||||
|
|
@ -44,7 +44,16 @@ impl App {
|
|||
fn dispatch_quit(&mut self) {
|
||||
if let Some(p) = &BOOT.cwd_file {
|
||||
let cwd = self.cx.manager.cwd().as_os_str();
|
||||
std::fs::write(p, cwd.as_bytes()).ok();
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
std::fs::write(p, cwd.to_string_lossy().as_bytes()).ok();
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
std::fs::write(p, cwd.as_bytes()).ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -174,7 +183,15 @@ impl App {
|
|||
s
|
||||
});
|
||||
|
||||
std::fs::write(p, paths.as_bytes()).ok();
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
std::fs::write(p, paths.to_string_lossy().as_bytes()).ok();
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
std::fs::write(p, paths.as_bytes()).ok();
|
||||
}
|
||||
return emit!(Quit);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use core::{input::Input, manager::Manager, select::Select, tasks::Tasks, which::Which, Position};
|
||||
|
||||
use config::keymap::KeymapLayer;
|
||||
use libc::winsize;
|
||||
use crossterm::terminal::WindowSize;
|
||||
use ratatui::prelude::Rect;
|
||||
use shared::tty_size;
|
||||
use shared::Term;
|
||||
|
||||
pub struct Ctx {
|
||||
pub manager: Manager,
|
||||
|
|
@ -25,14 +25,14 @@ impl Ctx {
|
|||
}
|
||||
|
||||
pub(super) fn area(&self, pos: &Position) -> Rect {
|
||||
let winsize { ws_row, ws_col, .. } = tty_size();
|
||||
let WindowSize { columns, rows, .. } = Term::size();
|
||||
|
||||
let (x, y) = match pos {
|
||||
Position::None => return Rect::default(),
|
||||
Position::Top(Rect { mut x, mut y, width, height }) => {
|
||||
x = x.min(ws_col.saturating_sub(*width));
|
||||
y = y.min(ws_row.saturating_sub(*height));
|
||||
((tty_size().ws_col / 2).saturating_sub(width / 2) + x, y)
|
||||
x = x.min(columns.saturating_sub(*width));
|
||||
y = y.min(rows.saturating_sub(*height));
|
||||
((columns / 2).saturating_sub(width / 2) + x, y)
|
||||
}
|
||||
Position::Hovered(rect @ Rect { mut x, y, width, height }) => {
|
||||
let Some(r) =
|
||||
|
|
@ -41,8 +41,8 @@ impl Ctx {
|
|||
return self.area(&Position::Top(*rect));
|
||||
};
|
||||
|
||||
x = x.min(ws_col.saturating_sub(*width));
|
||||
if y + height + r.y + r.height > ws_row {
|
||||
x = x.min(columns.saturating_sub(*width));
|
||||
if y + height + r.y + r.height > rows {
|
||||
(x + r.x, r.y.saturating_sub(height.saturating_sub(1)))
|
||||
} else {
|
||||
(x + r.x, y + r.y + r.height)
|
||||
|
|
@ -51,7 +51,7 @@ impl Ctx {
|
|||
};
|
||||
|
||||
let (w, h) = pos.dimension().unwrap();
|
||||
Rect { x, y, width: w.min(ws_col.saturating_sub(x)), height: h.min(ws_row.saturating_sub(y)) }
|
||||
Rect { x, y, width: w.min(columns.saturating_sub(x)), height: h.min(rows.saturating_sub(y)) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
use core::Event;
|
||||
|
||||
use anyhow::Result;
|
||||
use crossterm::event::{Event as CrosstermEvent, EventStream};
|
||||
use crossterm::event::{Event as CrosstermEvent, EventStream, KeyEvent, KeyEventKind};
|
||||
use futures::StreamExt;
|
||||
use libc::{SIGHUP, SIGINT, SIGQUIT, SIGTERM};
|
||||
use tokio::{select, sync::{mpsc::{self, UnboundedReceiver, UnboundedSender}, oneshot}, task::JoinHandle};
|
||||
|
||||
pub(super) struct Signals {
|
||||
|
|
@ -46,7 +45,13 @@ impl Signals {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn spawn_system_task(&self) -> Result<()> { Ok(()) }
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn spawn_system_task(&self) -> Result<JoinHandle<()>> {
|
||||
use libc::{SIGHUP, SIGINT, SIGQUIT, SIGTERM};
|
||||
|
||||
let tx = self.tx.clone();
|
||||
let mut signals = signal_hook_tokio::Signals::new([SIGHUP, SIGTERM, SIGINT, SIGQUIT])?;
|
||||
|
||||
|
|
@ -76,7 +81,9 @@ impl Signals {
|
|||
_ = &mut stop_rx => break,
|
||||
Some(Ok(event)) = reader.next() => {
|
||||
let event = match event {
|
||||
CrosstermEvent::Key(key) => Event::Key(key),
|
||||
// We need to check key event kind;
|
||||
// otherwise event will be dispatched twice.
|
||||
CrosstermEvent::Key(key @ KeyEvent { kind: KeyEventKind::Press, .. }) => Event::Key(key),
|
||||
CrosstermEvent::Paste(str) => Event::Paste(str),
|
||||
CrosstermEvent::Resize(cols, rows) => Event::Resize(cols, rows),
|
||||
_ => continue,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
use std::os::unix::prelude::PermissionsExt;
|
||||
|
||||
use config::THEME;
|
||||
use ratatui::{buffer::Buffer, layout::{Alignment, Rect}, text::{Line, Span}, widgets::{Paragraph, Widget}};
|
||||
use shared::file_mode;
|
||||
|
||||
use super::Progress;
|
||||
use crate::Ctx;
|
||||
|
|
@ -14,6 +11,7 @@ pub(super) struct Right<'a> {
|
|||
impl<'a> Right<'a> {
|
||||
pub(super) fn new(cx: &'a Ctx) -> Self { Self { cx } }
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn permissions(&self, s: &str) -> Vec<Span> {
|
||||
// Colors
|
||||
let mode = self.cx.manager.active().mode();
|
||||
|
|
@ -70,8 +68,10 @@ impl Widget for Right<'_> {
|
|||
let mut spans = vec![];
|
||||
|
||||
// Permissions
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
if let Some(h) = &manager.hovered {
|
||||
spans.extend(self.permissions(&file_mode(h.meta.permissions().mode())))
|
||||
use std::os::unix::prelude::PermissionsExt;
|
||||
spans.extend(self.permissions(&shared::file_mode(h.meta.permissions().mode())))
|
||||
}
|
||||
|
||||
// Position
|
||||
|
|
|
|||
3
build.sh
3
build.sh
|
|
@ -1,11 +1,14 @@
|
|||
cargo +stable build --release --target aarch64-apple-darwin
|
||||
cargo +stable build --release --target x86_64-apple-darwin
|
||||
cargo +stable build --release --target x86_64-unknown-linux-gnu
|
||||
cargo +stable build --release --target x86_64-pc-windows-gnu
|
||||
|
||||
mv target/aarch64-apple-darwin/release/yazi yazi-aarch64-apple-darwin
|
||||
mv target/x86_64-apple-darwin/release/yazi yazi-x86_64-apple-darwin
|
||||
mv target/x86_64-unknown-linux-gnu/release/yazi yazi-x86_64-unknown-linux-gnu
|
||||
mv target/x86_64-pc-windows-gnu/release/yazi yazi-x86_64-pc-windows-gnu
|
||||
|
||||
zip -j yazi-aarch64-apple-darwin.zip yazi-aarch64-apple-darwin
|
||||
zip -j yazi-x86_64-apple-darwin.zip yazi-x86_64-apple-darwin
|
||||
zip -j yazi-x86_64-unknown-linux-gnu.zip yazi-x86_64-unknown-linux-gnu
|
||||
zip -j yazi-x86_64-pc-windows-gnu.zip yazi-x86_64-pc-windows-gnu
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ shared = { path = "../shared" }
|
|||
anyhow = "^1"
|
||||
clap = { version = "^4", features = [ "derive" ] }
|
||||
crossterm = "^0"
|
||||
dirs = "^5"
|
||||
futures = "^0"
|
||||
glob = "^0"
|
||||
indexmap = "^2"
|
||||
|
|
@ -20,4 +21,3 @@ serde = { version = "^1", features = [ "derive" ] }
|
|||
shell-words = "^1"
|
||||
toml = { version = "^0", features = [ "preserve_order" ] }
|
||||
validator = { version = "^0", features = [ "derive" ] }
|
||||
xdg = "^2"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
use std::{env, fs, os::unix::prelude::OsStrExt, path::{Path, PathBuf}, time::{self, SystemTime}};
|
||||
use std::{env, fs, path::{Path, PathBuf}, time::{self, SystemTime}};
|
||||
|
||||
use clap::{command, Parser};
|
||||
use md5::{Digest, Md5};
|
||||
use shared::absolute_path;
|
||||
|
||||
use crate::Xdg;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Boot {
|
||||
pub cwd: PathBuf,
|
||||
|
|
@ -43,7 +45,7 @@ impl Default for Boot {
|
|||
let boot = Self {
|
||||
cwd: cwd.unwrap_or("/".into()),
|
||||
cache_dir: env::temp_dir().join("yazi"),
|
||||
state_dir: xdg::BaseDirectories::with_prefix("yazi").unwrap().get_state_home(),
|
||||
state_dir: Xdg::state_dir().unwrap(),
|
||||
|
||||
cwd_file: args.cwd_file,
|
||||
chooser_file: args.chooser_file,
|
||||
|
|
@ -63,9 +65,16 @@ impl Default for Boot {
|
|||
impl Boot {
|
||||
#[inline]
|
||||
pub fn cache(&self, path: &Path) -> PathBuf {
|
||||
self
|
||||
.cache_dir
|
||||
.join(format!("{:x}", Md5::new_with_prefix(path.as_os_str().as_bytes()).finalize()))
|
||||
#[cfg(target_os = "windows")]
|
||||
let h = Md5::new_with_prefix(path.to_string_lossy().as_bytes());
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let h = {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
Md5::new_with_prefix(path.as_os_str().as_bytes())
|
||||
};
|
||||
|
||||
self.cache_dir.join(format!("{:x}", h.finalize()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -13,9 +13,11 @@ pub mod preview;
|
|||
pub mod tasks;
|
||||
pub mod theme;
|
||||
mod validation;
|
||||
mod xdg;
|
||||
|
||||
pub(crate) use pattern::*;
|
||||
pub(crate) use preset::*;
|
||||
pub(crate) use xdg::*;
|
||||
|
||||
static MERGED_KEYMAP: RoCell<String> = RoCell::new();
|
||||
static MERGED_THEME: RoCell<String> = RoCell::new();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use std::fs;
|
||||
|
||||
use toml::Table;
|
||||
use xdg::BaseDirectories;
|
||||
|
||||
use crate::xdg::Xdg;
|
||||
|
||||
pub(crate) struct Preset;
|
||||
|
||||
|
|
@ -28,7 +29,7 @@ impl Preset {
|
|||
}
|
||||
|
||||
fn merge_str(user: &str, base: &str) -> String {
|
||||
let path = BaseDirectories::new().unwrap().get_config_file(user);
|
||||
let path = Xdg::config_dir().unwrap().join(user);
|
||||
let mut user = fs::read_to_string(path).unwrap_or_default().parse::<Table>().unwrap();
|
||||
|
||||
let base = base.parse::<Table>().unwrap();
|
||||
|
|
@ -38,16 +39,16 @@ impl Preset {
|
|||
|
||||
#[inline]
|
||||
pub(crate) fn keymap() -> String {
|
||||
Self::merge_str("yazi/keymap.toml", include_str!("../preset/keymap.toml"))
|
||||
Self::merge_str("keymap.toml", include_str!("../preset/keymap.toml"))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn theme() -> String {
|
||||
Self::merge_str("yazi/theme.toml", include_str!("../preset/theme.toml"))
|
||||
Self::merge_str("theme.toml", include_str!("../preset/theme.toml"))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn yazi() -> String {
|
||||
Self::merge_str("yazi/yazi.toml", include_str!("../preset/yazi.toml"))
|
||||
Self::merge_str("yazi.toml", include_str!("../preset/yazi.toml"))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ impl Default for PreviewAdaptor {
|
|||
}
|
||||
match env::var("TERM_PROGRAM").unwrap_or_default().as_str() {
|
||||
"iTerm.app" => return Self::Iterm2,
|
||||
"WezTerm" => return Self::Kitty,
|
||||
"WezTerm" => return if cfg!(windows) { Self::Iterm2 } else { Self::Kitty },
|
||||
"vscode" => return Self::Sixel,
|
||||
"Hyper" => return Self::Sixel,
|
||||
_ => {}
|
||||
|
|
|
|||
35
config/src/xdg.rs
Normal file
35
config/src/xdg.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
pub(super) struct Xdg;
|
||||
|
||||
impl Xdg {
|
||||
pub(super) fn config_dir() -> Option<PathBuf> {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
dirs::config_dir().map(|p| p.join("yazi").join("config"))
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
std::env::var_os("XDG_CONFIG_HOME")
|
||||
.map(PathBuf::from)
|
||||
.and_then(|p| p.is_absolute().then_some(p))
|
||||
.or_else(|| dirs::home_dir().map(|h| h.join(".config")))
|
||||
.map(|p| p.join("yazi"))
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn state_dir() -> Option<PathBuf> {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
dirs::data_dir().map(|p| p.join("yazi").join("state"))
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
std::env::var_os("XDG_STATE_HOME")
|
||||
.map(PathBuf::from)
|
||||
.and_then(|p| p.is_absolute().then_some(p))
|
||||
.or_else(|| dirs::home_dir().map(|h| h.join(".local/state")))
|
||||
.map(|p| p.join("yazi"))
|
||||
}
|
||||
}
|
||||
}
|
||||
2
core/src/external/file.rs
vendored
2
core/src/external/file.rs
vendored
|
|
@ -10,7 +10,7 @@ pub async fn file(files: &[impl AsRef<OsStr>]) -> Result<BTreeMap<PathBuf, Strin
|
|||
}
|
||||
|
||||
let output = Command::new("file")
|
||||
.args(["-bL", "--mime-type"])
|
||||
.args(["-b", "--mime-type"])
|
||||
.args(files)
|
||||
.kill_on_drop(true)
|
||||
.output()
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crossterm::terminal::WindowSize;
|
||||
use indexmap::map::Slice;
|
||||
use ratatui::layout::Rect;
|
||||
use shared::tty_size;
|
||||
use shared::Term;
|
||||
|
||||
use super::{ALL_RATIO, CURRENT_RATIO, DIR_PADDING, PARENT_RATIO};
|
||||
use crate::{emit, files::{File, Files, FilesOp}};
|
||||
|
|
@ -27,7 +28,7 @@ impl Folder {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn limit() -> usize { tty_size().ws_row.saturating_sub(DIR_PADDING) as usize }
|
||||
pub fn limit() -> usize { Term::size().rows.saturating_sub(DIR_PADDING) as usize }
|
||||
|
||||
pub fn update(&mut self, op: FilesOp) -> bool {
|
||||
let b = match op {
|
||||
|
|
@ -183,12 +184,12 @@ impl Folder {
|
|||
|
||||
pub fn rect_current(&self, path: &Path) -> Option<Rect> {
|
||||
let pos = self.position(path)? - self.offset;
|
||||
let s = tty_size();
|
||||
let WindowSize { columns, .. } = Term::size();
|
||||
|
||||
Some(Rect {
|
||||
x: (s.ws_col as u32 * PARENT_RATIO / ALL_RATIO) as u16,
|
||||
x: (columns as u32 * PARENT_RATIO / ALL_RATIO) as u16,
|
||||
y: pos as u16,
|
||||
width: (s.ws_col as u32 * CURRENT_RATIO / ALL_RATIO) as u16,
|
||||
width: (columns as u32 * CURRENT_RATIO / ALL_RATIO) as u16,
|
||||
height: 1,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{collections::{BTreeMap, BTreeSet, HashMap, HashSet}, env, ffi::OsStr, io::{stdout, BufWriter, Write}, mem, os::unix::prelude::OsStrExt, path::{Path, PathBuf}};
|
||||
use std::{collections::{BTreeMap, BTreeSet, HashMap, HashSet}, env, ffi::OsStr, io::{stdout, BufWriter, Write}, mem, path::{Path, PathBuf}};
|
||||
|
||||
use anyhow::{anyhow, bail, Error, Result};
|
||||
use config::{open::Opener, BOOT, OPEN};
|
||||
|
|
@ -231,9 +231,17 @@ impl Manager {
|
|||
};
|
||||
|
||||
{
|
||||
let b = old.iter().map(|o| o.as_os_str()).collect::<Vec<_>>().join(OsStr::new("\n"));
|
||||
let s = old.iter().map(|o| o.as_os_str()).collect::<Vec<_>>().join(OsStr::new("\n"));
|
||||
let mut f = OpenOptions::new().write(true).create_new(true).open(&tmp).await?;
|
||||
f.write_all(b.as_bytes()).await?;
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
f.write_all(s.to_string_lossy().as_bytes()).await?;
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
f.write_all(s.as_bytes()).await?;
|
||||
}
|
||||
}
|
||||
|
||||
let _guard = BLOCKER.acquire().await.unwrap();
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ use std::{io::BufRead, mem, path::{Path, PathBuf}, sync::{atomic::{AtomicUsize,
|
|||
use adaptor::Adaptor;
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use config::{BOOT, PREVIEW};
|
||||
use crossterm::terminal::WindowSize;
|
||||
use ratatui::prelude::Rect;
|
||||
use shared::{tty_size, MimeKind};
|
||||
use shared::{MimeKind, Term};
|
||||
use syntect::{easy::HighlightFile, util::as_24_bit_terminal_escaped};
|
||||
use tokio::{fs, task::JoinHandle};
|
||||
|
||||
|
|
@ -31,16 +32,16 @@ pub enum PreviewData {
|
|||
|
||||
impl Preview {
|
||||
fn rect() -> Rect {
|
||||
let s = tty_size();
|
||||
let WindowSize { columns, rows, .. } = Term::size();
|
||||
|
||||
let x = (s.ws_col as u32 * (PARENT_RATIO + CURRENT_RATIO) / ALL_RATIO) as u16;
|
||||
let width = (s.ws_col as u32 * PREVIEW_RATIO / ALL_RATIO) as u16;
|
||||
let x = (columns as u32 * (PARENT_RATIO + CURRENT_RATIO) / ALL_RATIO) as u16;
|
||||
let width = (columns as u32 * PREVIEW_RATIO / ALL_RATIO) as u16;
|
||||
|
||||
Rect {
|
||||
x: x.saturating_add(PREVIEW_BORDER / 2),
|
||||
y: PREVIEW_MARGIN / 2,
|
||||
width: width.saturating_sub(PREVIEW_BORDER),
|
||||
height: s.ws_row.saturating_sub(PREVIEW_MARGIN),
|
||||
height: rows.saturating_sub(PREVIEW_MARGIN),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::{collections::{BTreeMap, HashMap, HashSet}, ffi::OsStr, io::{stdout, Wr
|
|||
|
||||
use config::{manager::SortBy, open::Opener, OPEN};
|
||||
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
|
||||
use shared::{tty_size, Defer, MimeKind, Term};
|
||||
use shared::{Defer, MimeKind, Term};
|
||||
use tokio::{io::{stdin, AsyncReadExt}, select, sync::mpsc, time};
|
||||
use tracing::trace;
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ impl Tasks {
|
|||
|
||||
#[inline]
|
||||
pub fn limit() -> usize {
|
||||
(tty_size().ws_row * TASKS_PERCENT / 100).saturating_sub(TASKS_PADDING) as usize
|
||||
(Term::size().rows * TASKS_PERCENT / 100).saturating_sub(TASKS_PADDING) as usize
|
||||
}
|
||||
|
||||
pub fn toggle(&mut self) -> bool {
|
||||
|
|
|
|||
|
|
@ -125,7 +125,16 @@ impl File {
|
|||
|
||||
match fs::remove_file(&task.to).await {
|
||||
Err(e) if e.kind() != NotFound => Err(e)?,
|
||||
_ => fs::symlink(src, &task.to).await?,
|
||||
_ => {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
fs::symlink_file(src, &task.to).await?
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
fs::symlink(src, &task.to).await?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if task.cut {
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ pub fn copy_with_progress(from: &Path, to: &Path) -> mpsc::Receiver<Result<u64,
|
|||
}
|
||||
|
||||
// Convert a file mode to a string representation
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[allow(clippy::collapsible_else_if)]
|
||||
pub fn file_mode(mode: u32) -> String {
|
||||
use libc::{S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFSOCK, S_IRGRP, S_IROTH, S_IRUSR, S_ISGID, S_ISUID, S_ISVTX, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ mod mime;
|
|||
mod ro_cell;
|
||||
mod term;
|
||||
mod throttle;
|
||||
mod tty;
|
||||
|
||||
pub use buffer::*;
|
||||
pub use chars::*;
|
||||
|
|
@ -18,4 +17,3 @@ pub use mime::*;
|
|||
pub use ro_cell::*;
|
||||
pub use term::*;
|
||||
pub use throttle::*;
|
||||
pub use tty::*;
|
||||
|
|
|
|||
49
shared/src/term/cursor.rs
Normal file
49
shared/src/term/cursor.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
use std::io::{stdout, Write};
|
||||
|
||||
use anyhow::Result;
|
||||
use crossterm::{cursor::{MoveTo, RestorePosition, SavePosition, SetCursorStyle}, execute, queue, terminal::{Clear, ClearType}};
|
||||
|
||||
use crate::Term;
|
||||
|
||||
impl Term {
|
||||
#[inline]
|
||||
pub fn kill_to_end(stdout: &mut impl Write) -> Result<()> {
|
||||
Ok(queue!(stdout, Clear(ClearType::UntilNewLine))?)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn move_to(stdout: &mut impl Write, x: u16, y: u16) -> Result<()> {
|
||||
Ok(queue!(stdout, MoveTo(x, y))?)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn move_lock<W, F>(mut stdout: W, (x, y): (u16, u16), cb: F) -> Result<()>
|
||||
where
|
||||
W: Write,
|
||||
F: FnOnce(&mut W) -> Result<()>,
|
||||
{
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
use crossterm::cursor::{Hide, Show};
|
||||
queue!(&mut stdout, SavePosition, MoveTo(x, y), Show)?;
|
||||
let result = cb(&mut stdout);
|
||||
queue!(&mut stdout, Hide, RestorePosition)?;
|
||||
stdout.flush()?;
|
||||
result
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
queue!(&mut stdout, SavePosition, MoveTo(x, y))?;
|
||||
let result = cb(&mut stdout);
|
||||
queue!(&mut stdout, RestorePosition)?;
|
||||
stdout.flush()?;
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_block() -> Result<()> { Ok(execute!(stdout(), SetCursorStyle::BlinkingBlock)?) }
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_bar() -> Result<()> { Ok(execute!(stdout(), SetCursorStyle::BlinkingBar)?) }
|
||||
}
|
||||
5
shared/src/term/mod.rs
Normal file
5
shared/src/term/mod.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
mod cursor;
|
||||
mod term;
|
||||
|
||||
pub use cursor::*;
|
||||
pub use term::*;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
use std::{io::{stdout, Stdout, Write}, ops::{Deref, DerefMut}};
|
||||
use std::{io::{stdout, Stdout, Write}, mem, ops::{Deref, DerefMut}};
|
||||
|
||||
use anyhow::Result;
|
||||
use crossterm::{cursor::{MoveTo, SetCursorStyle}, event::{DisableBracketedPaste, DisableFocusChange, EnableBracketedPaste, EnableFocusChange, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, execute, queue, terminal::{disable_raw_mode, enable_raw_mode, supports_keyboard_enhancement, Clear, ClearType, EnterAlternateScreen, LeaveAlternateScreen}};
|
||||
use crossterm::{event::{DisableBracketedPaste, DisableFocusChange, EnableBracketedPaste, EnableFocusChange, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, execute, queue, terminal::{disable_raw_mode, enable_raw_mode, supports_keyboard_enhancement, Clear, ClearType, EnterAlternateScreen, LeaveAlternateScreen, WindowSize}};
|
||||
use ratatui::{backend::CrosstermBackend, Terminal};
|
||||
|
||||
pub struct Term {
|
||||
|
|
@ -32,23 +32,40 @@ impl Term {
|
|||
Ok(term)
|
||||
}
|
||||
|
||||
pub fn size() -> WindowSize {
|
||||
let mut size = WindowSize { rows: 0, columns: 0, width: 0, height: 0 };
|
||||
if let Ok(s) = crossterm::terminal::window_size() {
|
||||
let _ = mem::replace(&mut size, s);
|
||||
}
|
||||
|
||||
if size.rows == 0 || size.columns == 0 {
|
||||
if let Ok(s) = crossterm::terminal::size() {
|
||||
size.columns = s.0;
|
||||
size.rows = s.1;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Use `CSI 14 t` to get the actual size of the terminal
|
||||
// if size.width == 0 || size.height == 0 {}
|
||||
|
||||
size
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn ratio() -> Option<(f64, f64)> {
|
||||
let s = Self::size();
|
||||
if s.width == 0 || s.height == 0 {
|
||||
return None;
|
||||
}
|
||||
Some((f64::from(s.width) / f64::from(s.columns), f64::from(s.height) / f64::from(s.rows)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn clear(stdout: &mut impl Write) -> Result<()> {
|
||||
execute!(stdout, Clear(ClearType::All))?;
|
||||
queue!(stdout, Clear(ClearType::All))?;
|
||||
writeln!(stdout)?;
|
||||
Ok(stdout.flush()?)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn move_to(stdout: &mut impl Write, x: u16, y: u16) -> Result<()> {
|
||||
Ok(execute!(stdout, MoveTo(x, y))?)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_block() -> Result<()> { Ok(execute!(stdout(), SetCursorStyle::BlinkingBlock)?) }
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_bar() -> Result<()> { Ok(execute!(stdout(), SetCursorStyle::BlinkingBar)?) }
|
||||
}
|
||||
|
||||
impl Drop for Term {
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
use libc::{ioctl, winsize, STDOUT_FILENO, TIOCGWINSZ};
|
||||
|
||||
#[inline]
|
||||
pub fn tty_size() -> winsize {
|
||||
unsafe {
|
||||
let s: winsize = std::mem::zeroed();
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &s);
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn tty_ratio() -> (f64, f64) {
|
||||
let s = tty_size();
|
||||
(f64::from(s.ws_xpixel) / f64::from(s.ws_col), f64::from(s.ws_ypixel) / f64::from(s.ws_row))
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue