diff --git a/Cargo.lock b/Cargo.lock index 52ed38b..94b18ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + [[package]] name = "aho-corasick" version = "1.1.4" @@ -11,6 +17,24 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee4508988c62edf04abd8d92897fca0c2995d907ce1dfeaf369dac3716a40685" +dependencies = [ + "as-slice", +] + +[[package]] +name = "aligned-vec" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b" +dependencies = [ + "equator", +] + [[package]] name = "allocator-api2" version = "0.2.21" @@ -53,7 +77,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -64,7 +88,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -73,12 +97,112 @@ version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "arrayvec" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +[[package]] +name = "as-slice" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "av-scenechange" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f321d77c20e19b92c39e7471cf986812cbb46659d2af674adc4331ef3f18394" +dependencies = [ + "aligned", + "anyhow", + "arg_enum_proc_macro", + "arrayvec", + "log", + "num-rational", + "num-traits", + "pastey", + "rayon", + "thiserror 2.0.18", + "v_frame", + "y4m", +] + +[[package]] +name = "av1-grain" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cfddb07216410377231960af4fcab838eaa12e013417781b78bd95ee22077f8" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7178fe5f7d460b13895ebb9dcb28a3a6216d2df2574a0806cb51b555d297f38" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "base64-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" +dependencies = [ + "outref", + "vsimd", +] + +[[package]] +name = "bit_field" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -87,9 +211,30 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" + +[[package]] +name = "bitstream-io" +version = "4.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eff00be299a18769011411c9def0d827e8f2d7bf0c3dbf53633147a8867fd1f" +dependencies = [ + "no_std_io2", +] + +[[package]] +name = "bitvec" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] [[package]] name = "block2" @@ -100,6 +245,50 @@ dependencies = [ "objc2", ] +[[package]] +name = "built" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c0e531d93d39c34eef561e929e8a7f86d77a5af08aac4f6d6e39976c51858e9" + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "by_address" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" + +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "castaway" version = "0.2.4" @@ -111,11 +300,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.62" +version = "1.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -177,6 +368,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "colorchoice" version = "1.0.5" @@ -185,9 +382,9 @@ checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "compact_str" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a" +checksum = "9dfdd1c2274d9aa354115b09dc9a901d6c5576818cdf70d14cae2bdb47df00ab" dependencies = [ "castaway", "cfg-if", @@ -206,19 +403,53 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + [[package]] name = "crossterm" version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "crossterm_winapi", "derive_more", "document-features", "mio", "parking_lot", - "rustix", + "rustix 1.1.4", "signal-hook", "signal-hook-mio", "winapi", @@ -233,6 +464,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + [[package]] name = "ctrlc" version = "3.5.2" @@ -241,7 +478,7 @@ checksum = "e0b1fab2ae45819af2d0731d60f2afe17227ebb1a1538a236da84c93e9a60162" dependencies = [ "dispatch2", "nix 0.31.3", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -315,7 +552,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "block2", "libc", "objc2", @@ -348,6 +585,26 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" +[[package]] +name = "equator" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc" +dependencies = [ + "equator-macro", +] + +[[package]] +name = "equator-macro" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -361,7 +618,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "exr" +version = "1.74.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4300e043a56aa2cb633c01af81ca8f699a321879a7854d3896a0ba89056363be" +dependencies = [ + "bit_field", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + +[[package]] +name = "fast-srgb8" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" + +[[package]] +name = "fax" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caf1079563223d5d59d83c85886a56e586cfd5c1a26292e971a0fa266531ac5a" + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", ] [[package]] @@ -381,12 +674,72 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "foldhash" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "gif" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee8cfcc411d9adbbaba82fb72661cc1bcca13e8bba98b364e62b2dba8f960159" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + [[package]] name = "hashbrown" version = "0.16.1" @@ -403,6 +756,11 @@ name = "hashbrown" version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] [[package]] name = "heck" @@ -410,12 +768,62 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "icy_sixel" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85518b9086bf01117761b90e7691c0ef3236fa8adfb1fb44dd248fe5f87215d5" +dependencies = [ + "quantette", + "thiserror 2.0.18", +] + [[package]] name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "image" +version = "0.25.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104" +dependencies = [ + "bytemuck", + "byteorder-lite", + "color_quant", + "exr", + "gif", + "image-webp", + "moxcms", + "num-traits", + "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3" +dependencies = [ + "byteorder-lite", + "quick-error", +] + +[[package]] +name = "imgref" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89194689a993ab15268672e99e7b0e19da2da3268ac682e8f02d29d4d1434cd7" + [[package]] name = "include_dir" version = "0.7.4" @@ -467,6 +875,17 @@ dependencies = [ "syn", ] +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -488,6 +907,16 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + [[package]] name = "kasuari" version = "0.4.12" @@ -505,6 +934,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "lebe" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" + [[package]] name = "libc" version = "0.2.186" @@ -512,14 +947,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] -name = "line-clipping" -version = "0.3.7" +name = "libfuzzer-sys" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f50e8f47623268b5407192d26876c4d7f89d686ca130fdc53bced4814cd29f8" +checksum = "a9fd2f41a1cba099f79a0b6b6c35656cf7c03351a7bae8ff0f28f25270f929d2" dependencies = [ - "bitflags 2.11.1", + "arbitrary", + "cc", +] + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "line-clipping" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f50e8f47623268b5407192d26876c4d7f89d686ca130fdc53bced4814cd29f8" +dependencies = [ + "bitflags 2.13.0", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + [[package]] name = "linux-raw-sys" version = "0.12.1" @@ -543,44 +1000,89 @@ dependencies = [ [[package]] name = "log" -version = "0.4.30" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" +checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" + +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] [[package]] name = "lru" -version = "0.16.4" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" +checksum = "8a860605968fce16869fd239cf4237a82f3ac470723415db603b0e8b6c8d4fb9" dependencies = [ - "hashbrown 0.16.1", + "hashbrown 0.17.1", +] + +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", ] [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] [[package]] name = "mio" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.61.2", ] +[[package]] +name = "moxcms" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b" +dependencies = [ + "num-traits", + "pxfm", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + [[package]] name = "nix" version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "cfg-if", "cfg_aliases 0.1.1", "libc", @@ -592,18 +1094,93 @@ version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "cfg-if", "cfg_aliases 0.2.1", "libc", ] +[[package]] +name = "no_std_io2" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418abd1b6d34fbf6cae440dc874771b0525a604428704c76e48b29a5e67b8003" +dependencies = [ + "memchr", +] + +[[package]] +name = "nom" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" +dependencies = [ + "memchr", +] + +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-conv" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + [[package]] name = "num_threads" version = "0.1.7" @@ -628,6 +1205,12 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + [[package]] name = "once_cell_polyfill" version = "1.70.2" @@ -640,9 +1223,18 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe21416a02c693fb9f980befcb230ecc70b0b3d1cc4abf88b9675c4c1457f0c" +[[package]] +name = "ordered-float" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7d950ca161dc355eaf28f82b11345ed76c6e1f6eb1f4f4479e0323b9e2fbd0e" +dependencies = [ + "num-traits", +] + [[package]] name = "osutil_core" -version = "2.1.3" +version = "2.2.0" dependencies = [ "ego-tree", "include_dir", @@ -654,16 +1246,18 @@ dependencies = [ [[package]] name = "osutil_tui" -version = "2.1.3" +version = "2.2.0" dependencies = [ "anyhow", "clap", "ctrlc", + "image", "nix 0.31.3", "oneshot", "osutil_core", "portable-pty", "ratatui", + "ratatui-image", "time", "tree-sitter-bash", "tree-sitter-highlight", @@ -673,6 +1267,37 @@ dependencies = [ "which", ] +[[package]] +name = "outref" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" + +[[package]] +name = "palette" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbf71184cc5ecc2e4e1baccdb21026c20e5fc3dcf63028a086131b3ab00b6e6" +dependencies = [ + "approx", + "bytemuck", + "fast-srgb8", + "libm", + "palette_derive", +] + +[[package]] +name = "palette_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5030daf005bface118c096f510ffb781fc28f9ab6a32ab224d8631be6851d30" +dependencies = [ + "by_address", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "parking_lot" version = "0.12.5" @@ -696,6 +1321,31 @@ dependencies = [ "windows-link", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pastey" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" + +[[package]] +name = "png" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" +dependencies = [ + "bitflags 2.13.0", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + [[package]] name = "portable-atomic" version = "1.13.1" @@ -729,6 +1379,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + [[package]] name = "proc-macro2" version = "1.0.106" @@ -739,84 +1398,335 @@ dependencies = [ ] [[package]] -name = "quote" -version = "1.0.45" +name = "profiling" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4488a4a36b9a4ba6b9334a32a39971f77c1436ec82c38707bce707699cc3bbcb" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "pxfm" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0c5ccf5294c6ccd63a74f1565028353830a9c2f5eb0c682c355c471726a6e3f" + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quantette" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c98fecda8b16396ff9adac67644a523dd1778c42b58606a29df5c31ca925d174" +dependencies = [ + "bitvec", + "bytemuck", + "image", + "libm", + "num-traits", + "ordered-float", + "palette", + "rand 0.9.4", + "rand_xoshiro", + "rayon", + "ref-cast", + "wide", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rand_xoshiro" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" +dependencies = [ + "rand_core 0.9.5", +] + +[[package]] +name = "ratatui" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1695748e3a735b34968c887ceea5a380b43545903868ae8f5b666593100f6b68" +dependencies = [ + "instability", + "ratatui-core", + "ratatui-crossterm", + "ratatui-widgets", + "serde", +] + +[[package]] +name = "ratatui-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3603f354bba8c595fa47860e60142d7372b7210c27044c6a7d0e1a4336b44" +dependencies = [ + "bitflags 2.13.0", + "compact_str", + "hashbrown 0.17.1", + "indoc", + "itertools", + "kasuari", + "lru", + "palette", + "serde", + "strum", + "thiserror 2.0.18", + "unicode-segmentation", + "unicode-truncate", + "unicode-width", +] + +[[package]] +name = "ratatui-crossterm" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2867bedcbd6a690ca4f8672a687b730ec07660c79844517b084311b529980c" +dependencies = [ + "cfg-if", + "crossterm", + "instability", + "ratatui-core", +] + +[[package]] +name = "ratatui-image" +version = "11.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f522f51185b7f2a2a76658dfb3f3995d35a85908afa559595c468b48f30ed6de" +dependencies = [ + "base64-simd", + "icy_sixel", + "image", + "rand 0.8.6", + "ratatui", + "rustix 0.38.44", + "self_cell", + "thiserror 1.0.69", + "windows", +] + +[[package]] +name = "ratatui-widgets" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef4f17dd7ac3abf5adc2b920a03c61eee4bfe6a88fa5191936895525371d79c" +dependencies = [ + "bitflags 2.13.0", + "hashbrown 0.17.1", + "indoc", + "instability", + "itertools", + "line-clipping", + "ratatui-core", + "serde", + "strum", + "time", + "unicode-segmentation", + "unicode-width", +] + +[[package]] +name = "rav1e" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b6dd56e85d9483277cde964fd1bdb0428de4fec5ebba7540995639a21cb32b" +dependencies = [ + "aligned-vec", + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av-scenechange", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "paste", + "profiling", + "rand 0.9.4", + "rand_chacha 0.9.0", + "simd_helpers", + "thiserror 2.0.18", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "e52310197d971b0f5be7fe6b57530dcd27beb35c1b013f29d66c1ad73fbbcc45" dependencies = [ - "proc-macro2", + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", ] [[package]] -name = "ratatui" -version = "0.30.0" +name = "rayon" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1ce67fb8ba4446454d1c8dbaeda0557ff5e94d39d5e5ed7f10a65eb4c8266bc" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" dependencies = [ - "instability", - "ratatui-core", - "ratatui-crossterm", - "ratatui-widgets", + "either", + "rayon-core", ] [[package]] -name = "ratatui-core" -version = "0.1.0" +name = "rayon-core" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef8dea09a92caaf73bff7adb70b76162e5937524058a7e5bff37869cbbec293" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ - "bitflags 2.11.1", - "compact_str", - "hashbrown 0.16.1", - "indoc", - "itertools", - "kasuari", - "lru", - "strum", - "thiserror 2.0.18", - "unicode-segmentation", - "unicode-truncate", - "unicode-width", + "crossbeam-deque", + "crossbeam-utils", ] [[package]] -name = "ratatui-crossterm" -version = "0.1.0" +name = "redox_syscall" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "577c9b9f652b4c121fb25c6a391dd06406d3b092ba68827e6d2f09550edc54b3" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "cfg-if", - "crossterm", - "instability", - "ratatui-core", + "bitflags 2.13.0", ] [[package]] -name = "ratatui-widgets" -version = "0.3.0" +name = "ref-cast" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7dbfa023cd4e604c2553483820c5fe8aa9d71a42eea5aa77c6e7f35756612db" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" dependencies = [ - "bitflags 2.11.1", - "hashbrown 0.16.1", - "indoc", - "instability", - "itertools", - "line-clipping", - "ratatui-core", - "strum", - "time", - "unicode-segmentation", - "unicode-width", + "ref-cast-impl", ] [[package]] -name = "redox_syscall" -version = "0.5.18" +name = "ref-cast-impl" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ - "bitflags 2.11.1", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -848,6 +1758,12 @@ version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +[[package]] +name = "rgb" +version = "0.8.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4" + [[package]] name = "rustc_version" version = "0.4.1" @@ -857,17 +1773,30 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.13.0", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + [[package]] name = "rustix" version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "errno", "libc", - "linux-raw-sys", - "windows-sys", + "linux-raw-sys 0.12.1", + "windows-sys 0.61.2", ] [[package]] @@ -882,12 +1811,27 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +[[package]] +name = "safe_arch" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "629516c85c29fe757770fa03f2074cf1eac43d44c02a3de9fc2ef7b0e207dfdd" +dependencies = [ + "bytemuck", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "self_cell" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b12e76d157a900eb52e81bc6e9f3069344290341720e9178cde2407113ac8d89" + [[package]] name = "semver" version = "1.0.28" @@ -955,7 +1899,7 @@ checksum = "9eb6ea5562eeaed6936b8b54e086aa0f88b9e5b1bef45beb038e2519fa1185b1" dependencies = [ "cfg-if", "libc", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -976,9 +1920,9 @@ checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signal-hook" @@ -1011,12 +1955,33 @@ dependencies = [ "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" + +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + [[package]] name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + [[package]] name = "static_assertions" version = "1.1.0" @@ -1037,18 +2002,18 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.27.2" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.27.2" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" dependencies = [ "heck", "proc-macro2", @@ -1067,6 +2032,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "temp-dir" version = "0.2.0" @@ -1113,6 +2084,20 @@ dependencies = [ "syn", ] +[[package]] +name = "tiff" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63feaf3343d35b6ca4d50483f94843803b0f51634937cc2ec519fc32232bc52" +dependencies = [ + "fax", + "flate2", + "half", + "quick-error", + "weezl", + "zune-jpeg", +] + [[package]] name = "time" version = "0.3.47" @@ -1238,9 +2223,9 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-segmentation" -version = "1.13.2" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-truncate" @@ -1265,6 +2250,23 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "v_frame" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "666b7727c8875d6ab5db9533418d7c764233ac9c0cff1d469aec8fa127597be2" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + [[package]] name = "vt100" version = "0.16.2" @@ -1292,15 +2294,85 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" +[[package]] +name = "wasip2" +version = "1.0.3+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "weezl" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" + [[package]] name = "which" -version = "8.0.2" +version = "8.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81995fafaaaf6ae47a7d0cc83c67caf92aeb7e5331650ae6ff856f7c0c60c459" +checksum = "c789537cf2f7f55be8e6192f92e464174ee55f91af622777f7f1ceb0dbccd03e" dependencies = [ "libc", ] +[[package]] +name = "wide" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13ca908d26e4786149c48efcf6c0ea09ab0e06d1fe3c17dc1b4b0f1ca4a7e788" +dependencies = [ + "bytemuck", + "safe_arch", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1323,12 +2395,85 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core", + "windows-targets", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.61.2" @@ -1338,6 +2483,70 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[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.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[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.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[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.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "winnow" version = "1.0.3" @@ -1353,8 +2562,73 @@ dependencies = [ "winapi", ] +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "y4m" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5a4b21e1a62b67a2970e6831bc091d7b87e119e7f9791aef9702e3bef04448" + +[[package]] +name = "zerocopy" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zmij" version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + +[[package]] +name = "zune-core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296" +dependencies = [ + "zune-core", +] diff --git a/Cargo.toml b/Cargo.toml index 7fda4ed..2b5b5e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace.package] license = "MIT" -version = "2.1.3" +version = "2.2.0" edition = "2024" [workspace] diff --git a/core/tabs/linux/applications-setup/yazi.sh b/core/tabs/linux/applications-setup/yazi.sh index 4a3b445..7e75530 100644 --- a/core/tabs/linux/applications-setup/yazi.sh +++ b/core/tabs/linux/applications-setup/yazi.sh @@ -50,7 +50,7 @@ installYazi() { "$ESCALATION_TOOL" "$PACKAGER" install -y yazi ffmpeg p7zip jq poppler-utils fd-find ripgrep fzf zoxide ImageMagick ;; eopkg) - "$ESCALATION_TOOL" "$PACKAGER" install -y yazi ffmpeg p7zip jq poppler-utils fd ripgrep fzf zoxide resvg imagemagick + "$ESCALATION_TOOL" "$PACKAGER" install -y yazi ffmpeg 7zip jq poppler-utils fd ripgrep fzf zoxide resvg imagemagick ;; xbps-install) "$ESCALATION_TOOL" "$PACKAGER" -Sy yazi ffmpeg p7zip jq poppler-utils fd ripgrep fzf zoxide resvg ImageMagick diff --git a/core/tabs/macos/applications-setup/alacritty.sh b/core/tabs/macos/applications-setup/alacritty.sh deleted file mode 100644 index 46f02e0..0000000 --- a/core/tabs/macos/applications-setup/alacritty.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh -e - -. ../common-script.sh - -installAlacritty() { - if ! brewprogram_exists alacritty; then - printf "%b\n" "${YELLOW}Installing Alacritty...${RC}" - if ! brew install --cask alacritty; then - printf "%b\n" "${RED}Failed to install Alacritty. Please check your Homebrew installation or try again later.${RC}" - exit 1 - fi - else - printf "%b\n" "${GREEN}Alacritty is already installed.${RC}" - fi -} - -setupAlacrittyConfig() { - printf "%b\n" "${YELLOW}Copying alacritty config files...${RC}" - if [ -d "${HOME}/.config/alacritty" ] && [ ! -d "${HOME}/.config/alacritty-bak" ]; then - cp -r "${HOME}/.config/alacritty" "${HOME}/.config/alacritty-bak" - fi - mkdir -p "${HOME}/.config/alacritty/" - curl -fsSLo "${HOME}/.config/alacritty/alacritty.toml" "https://github.com/ChrisTitusTech/dwm-titus/raw/main/config/alacritty/alacritty.toml" - curl -fsSLo "${HOME}/.config/alacritty/keybinds.toml" "https://github.com/ChrisTitusTech/dwm-titus/raw/main/config/alacritty/keybinds.toml" - curl -fsSLo "${HOME}/.config/alacritty/nordic.toml" "https://github.com/ChrisTitusTech/dwm-titus/raw/main/config/alacritty/nordic.toml" - printf "%b\n" "${GREEN}Alacritty configuration files copied.${RC}" -} - -checkEnv -installAlacritty -setupAlacrittyConfig \ No newline at end of file diff --git a/core/tabs/macos/applications-setup/kitty.sh b/core/tabs/macos/applications-setup/kitty.sh deleted file mode 100644 index 6137553..0000000 --- a/core/tabs/macos/applications-setup/kitty.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh -e - -. ../common-script.sh - -installKitty() { - if ! brewprogram_exists kitty; then - if ! brew install --cask kitty; then - printf "%b\n" "${RED}Failed to install Kitty. Please check your Homebrew installation or try again later.${RC}" - exit 1 - fi - printf "%b\n" "${GREEN}Kitty installed successfully!${RC}" - else - printf "%b\n" "${GREEN}Kitty is already installed.${RC}" - fi -} - -setupKittyConfig() { - printf "%b\n" "${YELLOW}Copying Kitty configuration files...${RC}" - if [ -d "${HOME}/.config/kitty" ] && [ ! -d "${HOME}/.config/kitty-bak" ]; then - cp -r "${HOME}/.config/kitty" "${HOME}/.config/kitty-bak" - fi - mkdir -p "${HOME}/.config/kitty/" - curl -fsSLo "${HOME}/.config/kitty/kitty.conf" https://github.com/ChrisTitusTech/dwm-titus/raw/main/config/kitty/kitty.conf - curl -fsSLo "${HOME}/.config/kitty/nord.conf" https://github.com/ChrisTitusTech/dwm-titus/raw/main/config/kitty/nord.conf -} - -checkEnv -installKitty -setupKittyConfig \ No newline at end of file diff --git a/core/tabs/macos/applications-setup/tab_data.toml b/core/tabs/macos/applications-setup/tab_data.toml index 9228ab1..e9c6696 100644 --- a/core/tabs/macos/applications-setup/tab_data.toml +++ b/core/tabs/macos/applications-setup/tab_data.toml @@ -108,6 +108,63 @@ description = "Zellij is a terminal workspace with batteries included, featuring script = "developer-tools/zellij.sh" task_list = "I" +[[data]] +name = "Terminal Emulators" + +[[data.entries]] +name = "Alacritty" +description = "Alacritty is a modern terminal emulator that comes with sensible defaults, but allows for extensive configuration. By integrating with other applications, rather than reimplementing their functionality, it manages to provide a flexible set of features with high performance. The supported platforms currently consist of BSD, Linux, macOS and Windows. This command installs and configures alacritty terminal emulator." +script = "terminal-emulators/alacritty.sh" +task_list = "I FM" + +[[data.entries]] +name = "Ghostty" +description = "Ghostty is a fast, feature-rich, and cross-platform terminal emulator that uses platform-native UI and GPU acceleration." +script = "terminal-emulators/ghostty.sh" +task_list = "I" + +[[data.entries]] +name = "iTerm2" +description = "iTerm2 is a popular macOS terminal emulator with split panes, search, autocomplete, and extensive customization." +script = "terminal-emulators/iterm2.sh" +task_list = "I" + +[[data.entries]] +name = "Kitty" +description = "kitty is a free and open-source GPU-accelerated terminal emulator for Linux, macOS, and some BSD distributions, focused on performance and features. kitty is written in a mix of C and Python programming languages. This command installs and configures kitty." +script = "terminal-emulators/kitty.sh" +task_list = "I FM" + +[[data.entries]] +name = "Rio" +description = "Rio is a hardware-accelerated GPU terminal emulator built for speed and a native macOS experience." +script = "terminal-emulators/rio.sh" +task_list = "I" + +[[data.entries]] +name = "Tabby" +description = "Tabby is a modern terminal emulator with SSH, serial, and Telnet clients, themes, and split panes." +script = "terminal-emulators/tabby.sh" +task_list = "I" + +[[data.entries]] +name = "Termius" +description = "Termius is an SSH client and terminal how it should be. Connect with one tap from any mobile and desktop device—no re-entering IP addresses, ports, and passwords." +script = "terminal-emulators/termius.sh" +task_list = "I" + +[[data.entries]] +name = "Warp" +description = "Warp is the intelligent terminal with AI and your dev team's knowledge built-in." +script = "terminal-emulators/warp.sh" +task_list = "I" + +[[data.entries]] +name = "WezTerm" +description = "WezTerm is a GPU-accelerated cross-platform terminal emulator and multiplexer with ligatures, tabs, and panes." +script = "terminal-emulators/wezterm.sh" +task_list = "I" + [[data]] name = "Multimedia" @@ -198,12 +255,6 @@ description = "Helium is a modern web browser designed for a fast and efficient script = "browsers/helium.sh" task_list = "I" -[[data]] -name = "Alacritty" -description = "Alacritty is a modern terminal emulator that comes with sensible defaults, but allows for extensive configuration. By integrating with other applications, rather than reimplementing their functionality, it manages to provide a flexible set of features with high performance. The supported platforms currently consist of BSD, Linux, macOS and Windows. This command installs and configures alacritty terminal emulator." -script = "alacritty.sh" -task_list = "I FM" - [[data]] name = "Applite" description = "Gui to install Mac applications through homebrew" @@ -222,24 +273,12 @@ description = "Fastfetch is a neofetch-like tool for fetching system information script = "fastfetch.sh" task_list = "I FM" -[[data]] -name = "Ghostty" -description = "Ghostty is a fast, feature-rich, and cross-platform terminal emulator that uses platform-native UI and GPU acceleration." -script = "ghostty.sh" -task_list = "I" - [[data]] name = "GrandPerspective" description = "Graphically shows disk usage within a file system" script = "grandperspective.sh" task_list = "I" -[[data]] -name = "Kitty" -description = "kitty is a free and open-source GPU-accelerated terminal emulator for Linux, macOS, and some BSD distributions, focused on performance and features. kitty is written in a mix of C and Python programming languages. This command installs and configures kitty." -script = "kitty.sh" -task_list = "I FM" - [[data]] name = "OnyX" description = "Verify system files structure, run miscellaneous maintenance and more" diff --git a/core/tabs/macos/applications-setup/terminal-emulators/alacritty.sh b/core/tabs/macos/applications-setup/terminal-emulators/alacritty.sh new file mode 100755 index 0000000..d077b45 --- /dev/null +++ b/core/tabs/macos/applications-setup/terminal-emulators/alacritty.sh @@ -0,0 +1,19 @@ +#!/bin/sh -e + +. ../../common-script.sh + +installAlacritty() { + if ! brewprogram_exists alacritty; then + printf "%b\n" "${YELLOW}Installing Alacritty...${RC}" + if ! brew install --cask alacritty; then + printf "%b\n" "${RED}Failed to install Alacritty. Please check your Homebrew installation or try again later.${RC}" + exit 1 + fi + printf "%b\n" "${GREEN}Alacritty installed successfully!${RC}" + else + printf "%b\n" "${GREEN}Alacritty is already installed.${RC}" + fi +} + +checkEnv +installAlacritty diff --git a/core/tabs/macos/applications-setup/ghostty.sh b/core/tabs/macos/applications-setup/terminal-emulators/ghostty.sh old mode 100644 new mode 100755 similarity index 81% rename from core/tabs/macos/applications-setup/ghostty.sh rename to core/tabs/macos/applications-setup/terminal-emulators/ghostty.sh index 95604af..2726131 --- a/core/tabs/macos/applications-setup/ghostty.sh +++ b/core/tabs/macos/applications-setup/terminal-emulators/ghostty.sh @@ -1,9 +1,10 @@ #!/bin/sh -e -. ../common-script.sh +. ../../common-script.sh installGhostty() { if ! brewprogram_exists ghostty; then + printf "%b\n" "${YELLOW}Installing Ghostty...${RC}" if ! brew install --cask ghostty; then printf "%b\n" "${RED}Failed to install Ghostty. Please check your Homebrew installation or try again later.${RC}" exit 1 @@ -15,4 +16,4 @@ installGhostty() { } checkEnv -installGhostty \ No newline at end of file +installGhostty diff --git a/core/tabs/macos/applications-setup/terminal-emulators/iterm2.sh b/core/tabs/macos/applications-setup/terminal-emulators/iterm2.sh new file mode 100755 index 0000000..c49df57 --- /dev/null +++ b/core/tabs/macos/applications-setup/terminal-emulators/iterm2.sh @@ -0,0 +1,19 @@ +#!/bin/sh -e + +. ../../common-script.sh + +installITerm2() { + if ! brewprogram_exists iterm2; then + printf "%b\n" "${YELLOW}Installing iTerm2...${RC}" + if ! brew install --cask iterm2; then + printf "%b\n" "${RED}Failed to install iTerm2. Please check your Homebrew installation or try again later.${RC}" + exit 1 + fi + printf "%b\n" "${GREEN}iTerm2 installed successfully!${RC}" + else + printf "%b\n" "${GREEN}iTerm2 is already installed.${RC}" + fi +} + +checkEnv +installITerm2 diff --git a/core/tabs/macos/applications-setup/terminal-emulators/kitty.sh b/core/tabs/macos/applications-setup/terminal-emulators/kitty.sh new file mode 100755 index 0000000..41b7ec4 --- /dev/null +++ b/core/tabs/macos/applications-setup/terminal-emulators/kitty.sh @@ -0,0 +1,19 @@ +#!/bin/sh -e + +. ../../common-script.sh + +installKitty() { + if ! brewprogram_exists kitty; then + printf "%b\n" "${YELLOW}Installing Kitty...${RC}" + if ! brew install --cask kitty; then + printf "%b\n" "${RED}Failed to install Kitty. Please check your Homebrew installation or try again later.${RC}" + exit 1 + fi + printf "%b\n" "${GREEN}Kitty installed successfully!${RC}" + else + printf "%b\n" "${GREEN}Kitty is already installed.${RC}" + fi +} + +checkEnv +installKitty diff --git a/core/tabs/macos/applications-setup/terminal-emulators/rio.sh b/core/tabs/macos/applications-setup/terminal-emulators/rio.sh new file mode 100755 index 0000000..6e2cb63 --- /dev/null +++ b/core/tabs/macos/applications-setup/terminal-emulators/rio.sh @@ -0,0 +1,19 @@ +#!/bin/sh -e + +. ../../common-script.sh + +installRio() { + if ! brewprogram_exists rio; then + printf "%b\n" "${YELLOW}Installing Rio...${RC}" + if ! brew install --cask rio; then + printf "%b\n" "${RED}Failed to install Rio. Please check your Homebrew installation or try again later.${RC}" + exit 1 + fi + printf "%b\n" "${GREEN}Rio installed successfully!${RC}" + else + printf "%b\n" "${GREEN}Rio is already installed.${RC}" + fi +} + +checkEnv +installRio diff --git a/core/tabs/macos/applications-setup/terminal-emulators/tabby.sh b/core/tabs/macos/applications-setup/terminal-emulators/tabby.sh new file mode 100755 index 0000000..7cd01cf --- /dev/null +++ b/core/tabs/macos/applications-setup/terminal-emulators/tabby.sh @@ -0,0 +1,19 @@ +#!/bin/sh -e + +. ../../common-script.sh + +installTabby() { + if ! brewprogram_exists tabby; then + printf "%b\n" "${YELLOW}Installing Tabby...${RC}" + if ! brew install --cask tabby; then + printf "%b\n" "${RED}Failed to install Tabby. Please check your Homebrew installation or try again later.${RC}" + exit 1 + fi + printf "%b\n" "${GREEN}Tabby installed successfully!${RC}" + else + printf "%b\n" "${GREEN}Tabby is already installed.${RC}" + fi +} + +checkEnv +installTabby diff --git a/core/tabs/macos/applications-setup/terminal-emulators/termius.sh b/core/tabs/macos/applications-setup/terminal-emulators/termius.sh new file mode 100755 index 0000000..6a9a578 --- /dev/null +++ b/core/tabs/macos/applications-setup/terminal-emulators/termius.sh @@ -0,0 +1,19 @@ +#!/bin/sh -e + +. ../../common-script.sh + +installTermius() { + if ! brewprogram_exists termius; then + printf "%b\n" "${YELLOW}Installing Termius...${RC}" + if ! brew install --cask termius; then + printf "%b\n" "${RED}Failed to install Termius. Please check your Homebrew installation or try again later.${RC}" + exit 1 + fi + printf "%b\n" "${GREEN}Termius installed successfully!${RC}" + else + printf "%b\n" "${GREEN}Termius is already installed.${RC}" + fi +} + +checkEnv +installTermius diff --git a/core/tabs/macos/applications-setup/terminal-emulators/warp.sh b/core/tabs/macos/applications-setup/terminal-emulators/warp.sh new file mode 100755 index 0000000..a108cf3 --- /dev/null +++ b/core/tabs/macos/applications-setup/terminal-emulators/warp.sh @@ -0,0 +1,19 @@ +#!/bin/sh -e + +. ../../common-script.sh + +installWarp() { + if ! brewprogram_exists warp; then + printf "%b\n" "${YELLOW}Installing Warp...${RC}" + if ! brew install --cask warp; then + printf "%b\n" "${RED}Failed to install Warp. Please check your Homebrew installation or try again later.${RC}" + exit 1 + fi + printf "%b\n" "${GREEN}Warp installed successfully!${RC}" + else + printf "%b\n" "${GREEN}Warp is already installed.${RC}" + fi +} + +checkEnv +installWarp diff --git a/core/tabs/macos/applications-setup/terminal-emulators/wezterm.sh b/core/tabs/macos/applications-setup/terminal-emulators/wezterm.sh new file mode 100755 index 0000000..8b02220 --- /dev/null +++ b/core/tabs/macos/applications-setup/terminal-emulators/wezterm.sh @@ -0,0 +1,19 @@ +#!/bin/sh -e + +. ../../common-script.sh + +installWezTerm() { + if ! brewprogram_exists wezterm; then + printf "%b\n" "${YELLOW}Installing WezTerm...${RC}" + if ! brew install --cask wezterm; then + printf "%b\n" "${RED}Failed to install WezTerm. Please check your Homebrew installation or try again later.${RC}" + exit 1 + fi + printf "%b\n" "${GREEN}WezTerm installed successfully!${RC}" + else + printf "%b\n" "${GREEN}WezTerm is already installed.${RC}" + fi +} + +checkEnv +installWezTerm diff --git a/tui/Cargo.toml b/tui/Cargo.toml index c1884f0..80e1ff8 100644 --- a/tui/Cargo.toml +++ b/tui/Cargo.toml @@ -7,7 +7,7 @@ edition = "2024" license.workspace = true repository = "https://github.com/Jaredy899/osutil" version.workspace = true -include = ["src/*.rs", "Cargo.toml", "../man/osutil.1"] +include = ["src/*.rs", "Cargo.toml", "assets/jc_logo.png", "../man/osutil.1"] [features] default = [] @@ -15,6 +15,8 @@ syntax-highlighting = ["tree-sitter-highlight", "tree-sitter-bash"] [dependencies] clap = { version = "4.6.1", features = ["derive"] } +image = { version = "0.25.10", default-features = false, features = ["png"] } +ratatui-image = { version = "11.0.2", default-features = false, features = ["crossterm", "image-defaults"] } oneshot = { version = "0.2.1", features = ["std"], default-features = false } portable-pty = "0.9.0" ratatui = { version = "0.30.0", features = ["crossterm"], default-features = false } diff --git a/tui/assets/jc_logo.png b/tui/assets/jc_logo.png new file mode 100644 index 0000000..669f52d Binary files /dev/null and b/tui/assets/jc_logo.png differ diff --git a/tui/src/logo.rs b/tui/src/logo.rs new file mode 100644 index 0000000..c01f0b5 --- /dev/null +++ b/tui/src/logo.rs @@ -0,0 +1,259 @@ +use crate::theme::Theme; +use image::{RgbaImage, imageops::FilterType}; +use ratatui::{prelude::*, widgets::Paragraph}; +use ratatui_image::{ + Resize, StatefulImage, + picker::{Picker, ProtocolType}, + protocol::StatefulProtocol, +}; + +const LOGO_TEXT_GAP: u16 = 0; +const LOGO_ALPHA_CUTOFF: u8 = 10; +const LOGO_SCALE_NUM: u32 = 70; +const LOGO_SCALE_DEN: u32 = 100; + +enum Renderer { + Protocol { + protocol: Box, + resize: Resize, + }, + Blocks, +} + +pub struct Logo { + renderer: Renderer, + rgba: RgbaImage, + font_size: (u16, u16), + image_size: (u32, u32), + cached_size: (u16, u16), + cached_lines: Vec>, + last_area_size: (u16, u16), +} + +impl Logo { + pub fn load() -> Option { + let dyn_image = image::load_from_memory(include_bytes!("../assets/jc_logo.png")).ok()?; + let rgba = dyn_image.to_rgba8(); + let image_size = rgba.dimensions(); + + let mut picker = Picker::from_query_stdio().unwrap_or_else(|_| Picker::halfblocks()); + picker.set_background_color(Some([0, 0, 0, 0])); + let font_size = picker.font_size(); + let font_size = (font_size.width, font_size.height); + let renderer = if picker.protocol_type() == ProtocolType::Halfblocks { + Renderer::Blocks + } else { + let protocol = + Box::new(picker.new_resize_protocol(image::DynamicImage::ImageRgba8(rgba.clone()))); + Renderer::Protocol { + protocol, + resize: Resize::Scale(Some(FilterType::Triangle)), + } + }; + + Some(Self { + renderer, + rgba, + font_size, + image_size, + cached_size: (0, 0), + cached_lines: Vec::new(), + last_area_size: (0, 0), + }) + } + + pub fn area_height_for_width(&self, width: u16, max_height: u16) -> u16 { + if width == 0 || max_height == 0 { + return 0; + } + + let scaled_width = self.scaled_width(width); + let max_image_height = max_height.saturating_sub(LOGO_TEXT_GAP + 1); + if max_image_height == 0 { + return max_height.min(1); + } + + let mut image_height = self.rows_for_width(scaled_width); + if image_height > max_image_height { + image_height = max_image_height; + } + + image_height + LOGO_TEXT_GAP + 1 + } + + pub fn draw(&mut self, frame: &mut Frame, area: Rect, theme: &Theme) { + if area.height == 0 || area.width == 0 { + return; + } + + self.refresh_protocol_if_needed(area); + + let max_image_height = area.height.saturating_sub(LOGO_TEXT_GAP + 1); + let (draw_width, draw_height) = self.draw_size(area.width, max_image_height); + + if draw_width > 0 && draw_height > 0 { + let centered_x = area.x + area.width.saturating_sub(draw_width) / 2; + let max_x = area.x + area.width.saturating_sub(draw_width); + let image_x = centered_x.min(max_x); + let image_area = Rect::new(image_x, area.y, draw_width, draw_height); + let mut use_blocks = matches!(self.renderer, Renderer::Blocks); + + if !use_blocks && let Renderer::Protocol { protocol, resize } = &mut self.renderer { + let widget = StatefulImage::::default().resize(resize.clone()); + frame.render_stateful_widget(widget, image_area, protocol.as_mut()); + if let Some(result) = protocol.last_encoding_result() + && result.is_err() + { + use_blocks = true; + } + } + + if use_blocks { + self.renderer = Renderer::Blocks; + self.render_blocks(frame, image_area); + } + } + + let text_y = if draw_height > 0 { + area.y + draw_height + LOGO_TEXT_GAP + } else { + area.y + }; + if text_y < area.y + area.height { + let text_area = Rect::new(area.x, text_y, area.width, 1); + let label = Line::styled( + format!("OSutil v{}", env!("CARGO_PKG_VERSION")), + Style::default().fg(theme.tab_color()).bold(), + ); + let text = Paragraph::new(label).alignment(Alignment::Center); + frame.render_widget(text, text_area); + } + } + + fn draw_size(&self, width: u16, max_height: u16) -> (u16, u16) { + if width == 0 || max_height == 0 { + return (0, 0); + } + + let scaled_width = self.scaled_width(width); + let mut draw_width = scaled_width; + let mut draw_height = self.rows_for_width(draw_width); + if draw_height > max_height { + draw_height = max_height; + draw_width = self.width_for_height(draw_height).min(scaled_width); + } + + (draw_width, draw_height) + } + + fn rows_for_width(&self, width: u16) -> u16 { + if width == 0 || self.image_size.0 == 0 || self.font_size.0 == 0 || self.font_size.1 == 0 { + return 0; + } + + let pixel_width = u64::from(width) * u64::from(self.font_size.0); + let scaled_pixel_height = + u64::from(self.image_size.1) * pixel_width / u64::from(self.image_size.0); + let row_height = u64::from(self.font_size.1); + let rows = scaled_pixel_height.div_ceil(row_height); + + rows.min(u64::from(u16::MAX)) as u16 + } + + fn width_for_height(&self, height: u16) -> u16 { + if height == 0 || self.image_size.1 == 0 || self.font_size.0 == 0 || self.font_size.1 == 0 { + return 0; + } + + let pixel_height = u64::from(height) * u64::from(self.font_size.1); + let scaled_pixel_width = + u64::from(self.image_size.0) * pixel_height / u64::from(self.image_size.1); + let col_width = u64::from(self.font_size.0); + let cols = scaled_pixel_width.div_ceil(col_width); + + cols.min(u64::from(u16::MAX)) as u16 + } + + fn render_blocks(&mut self, frame: &mut Frame, area: Rect) { + if area.width == 0 || area.height == 0 { + return; + } + + let size = (area.width, area.height); + if self.cached_size != size { + self.cached_size = size; + self.cached_lines.clear(); + + let resized = image::imageops::resize( + &self.rgba, + area.width as u32, + area.height as u32, + FilterType::Triangle, + ); + + for y in 0..area.height { + let mut spans = Vec::with_capacity(area.width as usize); + for x in 0..area.width { + let pixel = resized.get_pixel(x as u32, y as u32).0; + if pixel[3] < LOGO_ALPHA_CUTOFF { + spans.push(Span::raw(" ")); + } else { + spans.push(Span::styled( + "#", + Style::default().fg(Color::Rgb(pixel[0], pixel[1], pixel[2])), + )); + } + } + self.cached_lines.push(Line::from(spans)); + } + } + + frame.render_widget(Paragraph::new(Text::from(self.cached_lines.clone())), area); + } + + fn refresh_protocol_if_needed(&mut self, area: Rect) { + let area_size = (area.width, area.height); + if self.last_area_size == area_size { + return; + } + self.last_area_size = area_size; + + if !matches!(self.renderer, Renderer::Protocol { .. }) { + return; + } + + let mut picker = match Picker::from_query_stdio() { + Ok(picker) => picker, + Err(_) => return, + }; + picker.set_background_color(Some([0, 0, 0, 0])); + let new_font_size = picker.font_size(); + let new_font_size = (new_font_size.width, new_font_size.height); + let protocol_type = picker.protocol_type(); + + if protocol_type == ProtocolType::Halfblocks { + self.renderer = Renderer::Blocks; + self.font_size = new_font_size; + self.cached_size = (0, 0); + return; + } + + if self.font_size != new_font_size { + self.font_size = new_font_size; + self.renderer = Renderer::Protocol { + protocol: Box::new( + picker.new_resize_protocol(image::DynamicImage::ImageRgba8(self.rgba.clone())), + ), + resize: Resize::Scale(Some(FilterType::Triangle)), + }; + } + } + + fn scaled_width(&self, width: u16) -> u16 { + if width == 0 { + return 0; + } + let scaled = (u32::from(width) * LOGO_SCALE_NUM + (LOGO_SCALE_DEN / 2)) / LOGO_SCALE_DEN; + scaled.clamp(1, u16::MAX as u32) as u16 + } +} diff --git a/tui/src/main.rs b/tui/src/main.rs index eaffa35..b56f15b 100644 --- a/tui/src/main.rs +++ b/tui/src/main.rs @@ -4,9 +4,11 @@ mod filter; mod float; mod floating_text; mod hint; +mod logo; mod root; mod running_command; mod state; +mod system_info; mod theme; use crate::cli::Args; diff --git a/tui/src/state.rs b/tui/src/state.rs index bf7bf22..95eed13 100644 --- a/tui/src/state.rs +++ b/tui/src/state.rs @@ -5,9 +5,11 @@ use crate::{ float::{Float, FloatContent}, floating_text::FloatingText, hint::{Shortcut, create_shortcut_list}, + logo::Logo, root::check_root_status, running_command::RunningCommand, shortcuts, + system_info::SystemInfo, theme::Theme, }; #[allow(unused_imports)] @@ -17,7 +19,7 @@ use ratatui::{ layout::Flex, prelude::*, symbols::border, - widgets::{Block, List, ListState, Paragraph}, + widgets::{Block, List, ListState, Padding, Paragraph}, }; use std::rc::Rc; @@ -25,7 +27,9 @@ const MIN_WIDTH: u16 = 99; const MIN_HEIGHT: u16 = 25; const FLOAT_SIZE: u16 = 95; const CONFIRM_PROMPT_FLOAT_SIZE: u16 = 40; -const TITLE: &str = concat!(" Linux Toolbox - ", env!("CARGO_PKG_VERSION"), " "); +const LEFT_EXTRA_WIDTH: u16 = 4; +const TITLE: &str = " OSUTIL "; +const LIST_HIGHLIGHT_SYMBOL: &str = "> "; const ACTIONS_GUIDE: &str = "List of important tasks performed by commands' names: D - disk modifications (ex. partitioning) (privileged) @@ -67,6 +71,8 @@ pub struct AppState { size_bypass: bool, skip_confirmation: bool, mouse_enabled: bool, + system_info: Option, + logo: Option, } pub enum Focus { @@ -129,6 +135,8 @@ impl AppState { size_bypass: args.size_bypass, skip_confirmation: args.skip_confirmation, mouse_enabled: args.mouse, + system_info: SystemInfo::gather(), + logo: Logo::load(), }; if let Some(root_warning) = root_warning { @@ -288,29 +296,14 @@ impl AppState { return frame.render_widget(warning, centered_layout[1]); } - let label_block = Block::bordered().border_set(border::Set { - top_left: " ", - top_right: " ", - bottom_left: " ", - bottom_right: " ", - vertical_left: " ", - vertical_right: " ", - horizontal_top: "*", - horizontal_bottom: "*", - }); - - let label = Paragraph::new(Line::from(vec![ - Span::styled("OSutil ", Style::default().bold()), - // Span::styled("by Chris Titus", Style::default().italic()), - ])) - .block(label_block) - .centered(); - let (keybind_scope, shortcuts) = self.get_keybinds(); let keybinds_block = Block::bordered() .title(format!(" {keybind_scope} ")) - .border_set(border::ROUNDED); + .border_set(border::PLAIN) + .border_style(Style::default().fg(self.theme.unfocused_color())) + .title_style(Style::default().fg(self.theme.tab_color()).bold()) + .padding(Padding::horizontal(1)); let keybind_render_width = keybinds_block.inner(area).width; let keybinds = create_shortcut_list(shortcuts, keybind_render_width); @@ -323,14 +316,49 @@ impl AppState { .split(area); let horizontal = Layout::horizontal([ - Constraint::Min(self.longest_tab_display_len + 5), + Constraint::Min(self.longest_tab_display_len + 7 + LEFT_EXTRA_WIDTH), Constraint::Percentage(100), ]) .split(vertical[0]); - let left_chunks = - Layout::vertical([Constraint::Length(3), Constraint::Min(1)]).split(horizontal[0]); - frame.render_widget(label, left_chunks[0]); + let info_height = self + .system_info + .as_ref() + .map(|info| info.entries_len() as u16) + .unwrap_or(0); + let show_info = info_height > 0 && horizontal[0].height > info_height.saturating_add(3); + + let reserved_info_height = if show_info { info_height } else { 0 }; + let max_logo_area_height = horizontal[0] + .height + .saturating_sub(reserved_info_height) + .saturating_sub(1); + let logo_height = if let Some(logo) = &self.logo { + logo.area_height_for_width(horizontal[0].width, max_logo_area_height) + } else { + max_logo_area_height.min(1) + }; + let left_chunks = if show_info { + Layout::vertical([ + Constraint::Length(logo_height), + Constraint::Min(1), + Constraint::Length(info_height), + ]) + .split(horizontal[0]) + } else { + Layout::vertical([Constraint::Length(logo_height), Constraint::Min(1)]) + .split(horizontal[0]) + }; + if let Some(logo) = &mut self.logo { + logo.draw(frame, left_chunks[0], &self.theme); + } else { + let label = Paragraph::new(Line::styled( + format!("OSutil v{}", env!("CARGO_PKG_VERSION")), + Style::default().fg(self.theme.tab_color()).bold(), + )) + .alignment(Alignment::Center); + frame.render_widget(label, left_chunks[0]); + } self.areas = Some(Areas { tab_list: left_chunks[1], @@ -343,36 +371,77 @@ impl AppState { .map(|tab| tab.name.as_str()) .collect::>(); - let (tab_hl_style, highlight_symbol) = if let Focus::TabList = self.focus { - ( - Style::default().reversed().fg(self.theme.tab_color()), - self.theme.tab_icon(), - ) - } else if let Focus::Search = self.focus { - (Style::reset(), " ") + let tab_focus = matches!(self.focus, Focus::TabList); + let tab_hl_style = if tab_focus { + Style::default() + .bg(self.theme.focused_color()) + .fg(Color::Black) + .bold() } else { - ( - Style::new().fg(self.theme.tab_color()), - self.theme.tab_icon(), - ) + Style::default().fg(self.theme.unfocused_color()) + }; + let tab_border_style = if tab_focus { + Style::default().fg(self.theme.focused_color()) + } else { + Style::default().fg(self.theme.unfocused_color()) }; let tab_list = List::new(tabs) - .block(Block::bordered().border_set(border::ROUNDED)) + .block( + Block::bordered() + .border_set(border::PLAIN) + .border_style(tab_border_style) + .padding(Padding::horizontal(1)), + ) + .style(Style::default().fg(self.theme.tab_color())) .highlight_style(tab_hl_style) - .highlight_symbol(highlight_symbol); + .highlight_symbol(self.theme.tab_icon()); frame.render_stateful_widget(tab_list, left_chunks[1], &mut self.current_tab); + if show_info && left_chunks.len() > 2 { + self.draw_system_info(frame, left_chunks[2]); + } let chunks = Layout::vertical([Constraint::Length(3), Constraint::Min(1)]).split(horizontal[1]); self.filter.draw_searchbar(frame, chunks[0], &self.theme); + let title = if self.multi_select { + &format!("{TITLE}[Multi-Select] ") + } else { + TITLE + }; + let bottom_title = ""; + + let list_focus = matches!(self.focus, Focus::List); + let list_dim_style = if list_focus { + Style::default() + } else { + Style::default().dim() + }; + let list_border_style = if list_focus { + Style::default().fg(self.theme.focused_color()) + } else { + Style::default().fg(self.theme.unfocused_color()) + }; + let task_list_title = Line::from(" FLAGS ").right_aligned(); + let list_block = Block::bordered() + .border_set(border::PLAIN) + .border_style(list_border_style) + .title(title) + .title(task_list_title) + .title_bottom(bottom_title) + .padding(Padding::horizontal(1)); + let list_inner_width = list_block.inner(chunks[1]).width as usize; + let list_content_width = list_inner_width.saturating_sub(LIST_HIGHLIGHT_SYMBOL.len()); + let mut items: Vec = Vec::with_capacity(self.filter.item_list().len()); if !self.at_root() { items.push( - Line::from(format!("{} ..", self.theme.dir_icon())).style(self.theme.dir_color()), + Line::from(format!("{} ..", self.theme.dir_icon())) + .style(self.theme.dir_color()) + .patch_style(list_dim_style), ); } @@ -397,48 +466,43 @@ impl AppState { self.theme.dir_color(), ) .patch_style(style) + .patch_style(list_dim_style) } else { let left_content = format!("{} {} {}", self.theme.cmd_icon(), node.name, indicator); let right_content = format!("{} ", node.task_list); - let center_space = " ".repeat( - chunks[1].width as usize - left_content.len() - right_content.len(), - ); + let center_space_width = + list_content_width.saturating_sub(left_content.len() + right_content.len()); + let center_space = " ".repeat(center_space_width); Line::styled( format!("{left_content}{center_space}{right_content}"), self.theme.cmd_color(), ) .patch_style(style) + .patch_style(list_dim_style) } }, )); - let style = if let Focus::List = self.focus { - Style::default().reversed() + let list_highlight_style = if list_focus { + Style::default() + .bg(self.theme.focused_color()) + .fg(Color::Black) + .bold() } else { - Style::new() + list_dim_style }; - - let title = if self.multi_select { - &format!("{TITLE}[Multi-Select] ") + let list_highlight_symbol = if list_focus { + LIST_HIGHLIGHT_SYMBOL } else { - TITLE + " " }; - let bottom_title = ""; - - let task_list_title = Line::from(" Important Actions ").right_aligned(); - // Create the list widget with items let list = List::new(items) - .highlight_style(style) - .block( - Block::bordered() - .border_set(border::ROUNDED) - .title(title) - .title(task_list_title) - .title_bottom(bottom_title), - ) + .highlight_style(list_highlight_style) + .highlight_symbol(list_highlight_symbol) + .block(list_block) .scroll_padding(1); frame.render_stateful_widget(list, chunks[1], &mut self.selection); @@ -451,6 +515,17 @@ impl AppState { frame.render_widget(keybind_para, vertical[1]); } + fn draw_system_info(&self, frame: &mut Frame, area: Rect) { + let max_width = area.width as usize; + let lines = self + .system_info + .as_ref() + .map(|info| info.render_lines(&self.theme, max_width)) + .unwrap_or_default(); + + frame.render_widget(Paragraph::new(Text::from(lines)), area); + } + pub fn handle_mouse(&mut self, event: &MouseEvent) -> bool { if !self.mouse_enabled { return true; diff --git a/tui/src/system_info.rs b/tui/src/system_info.rs new file mode 100644 index 0000000..0c52549 --- /dev/null +++ b/tui/src/system_info.rs @@ -0,0 +1,253 @@ +use crate::theme::Theme; +use ratatui::{ + style::Style, + text::{Line, Span}, +}; +#[cfg(target_os = "linux")] +use std::fs; +use std::process::Command; + +#[derive(Clone, Debug)] +pub struct SystemInfo { + entries: Vec, +} + +#[derive(Clone, Debug)] +struct InfoEntry { + label: &'static str, + value: String, +} + +impl SystemInfo { + pub fn gather() -> Option { + let entries = vec![ + InfoEntry { + label: " OS", + value: detect_os(), + }, + InfoEntry { + label: "CPU", + value: detect_cpu().unwrap_or_else(|| "n/a".to_string()), + }, + InfoEntry { + label: "RAM", + value: detect_memory().unwrap_or_else(|| "n/a".to_string()), + }, + InfoEntry { + label: "DISK", + value: detect_disk().unwrap_or_else(|| "n/a".to_string()), + }, + ]; + + Some(Self { entries }) + } + + pub fn entries_len(&self) -> usize { + self.entries.len() + } + + pub fn render_lines(&self, theme: &Theme, max_width: usize) -> Vec> { + self.entries + .iter() + .map(|entry| { + let prefix = format!("{:>4}: ", entry.label); + let value_width = max_width.saturating_sub(prefix.len()); + let value = truncate(&entry.value, value_width); + + Line::from(vec![ + Span::styled( + format!("{:>4}", entry.label), + Style::default().fg(theme.tab_color()).bold(), + ), + Span::styled(": ", Style::default().fg(theme.unfocused_color())), + Span::styled(value, Style::default().fg(theme.cmd_color())), + ]) + }) + .collect() + } +} + +fn truncate(value: &str, max_width: usize) -> String { + if max_width == 0 { + return String::new(); + } + + let chars: Vec = value.chars().collect(); + if chars.len() <= max_width { + return value.to_string(); + } + + if max_width <= 3 { + return chars.iter().take(max_width).collect(); + } + + let slice: String = chars.iter().take(max_width - 3).collect(); + format!("{slice}...") +} + +fn command_output(program: &str, args: &[&str]) -> Option { + let output = Command::new(program).args(args).output().ok()?; + + if !output.status.success() { + return None; + } + + let value = String::from_utf8_lossy(&output.stdout).trim().to_string(); + (!value.is_empty()).then_some(value) +} + +fn strip_device_details(value: &str) -> String { + let mut trimmed = value.trim().to_string(); + for pattern in [" @", " (", " ["] { + if let Some(idx) = trimmed.find(pattern) { + trimmed.truncate(idx); + trimmed = trimmed.trim().to_string(); + } + } + trimmed +} + +#[cfg(target_os = "linux")] +fn shorten_os(value: &str) -> String { + let mut name = value.trim().to_string(); + if let Some(idx) = name.find(" GNU/Linux") { + name.truncate(idx); + } + if name.ends_with(" Linux") { + name.truncate(name.len() - " Linux".len()); + } + name.trim().to_string() +} + +#[cfg(target_os = "linux")] +fn detect_os() -> String { + fs::read_to_string("/etc/os-release") + .ok() + .and_then(|data| parse_os_release(&data)) + .map(|name| shorten_os(&name)) + .unwrap_or_else(|| "Linux".to_string()) +} + +#[cfg(target_os = "macos")] +fn detect_os() -> String { + match ( + command_output("sw_vers", &["-productName"]), + command_output("sw_vers", &["-productVersion"]), + ) { + (Some(name), Some(version)) => format!("{name} {version}"), + (Some(name), None) => name, + _ => "macOS".to_string(), + } +} + +#[cfg(not(any(target_os = "linux", target_os = "macos")))] +fn detect_os() -> String { + std::env::consts::OS.to_string() +} + +#[cfg(target_os = "linux")] +fn detect_cpu() -> Option { + fs::read_to_string("/proc/cpuinfo") + .ok() + .and_then(|data| { + data.lines().find_map(|line| { + line.strip_prefix("model name") + .and_then(|line| line.split_once(':')) + .map(|(_, value)| strip_device_details(value)) + }) + }) + .or_else(|| command_output("uname", &["-m"]).map(|value| strip_device_details(&value))) +} + +#[cfg(target_os = "macos")] +fn detect_cpu() -> Option { + command_output("sysctl", &["-n", "machdep.cpu.brand_string"]) + .map(|value| strip_device_details(&value)) +} + +#[cfg(not(any(target_os = "linux", target_os = "macos")))] +fn detect_cpu() -> Option { + None +} + +#[cfg(target_os = "linux")] +fn detect_memory() -> Option { + let data = fs::read_to_string("/proc/meminfo").ok()?; + let total_kib = meminfo_value(&data, "MemTotal")?; + Some(format!("{:.1} GiB", kib_to_gib(total_kib))) +} + +#[cfg(target_os = "macos")] +fn detect_memory() -> Option { + let bytes = command_output("sysctl", &["-n", "hw.memsize"])? + .parse::() + .ok()?; + Some(format!("{:.1} GiB", bytes as f64 / 1024_f64.powi(3))) +} + +#[cfg(not(any(target_os = "linux", target_os = "macos")))] +fn detect_memory() -> Option { + None +} + +fn detect_disk() -> Option { + let output = command_output("df", &["-h", "/"])?; + let line = output.lines().nth(1)?; + let columns = line.split_whitespace().collect::>(); + let size = columns.get(1)?; + Some(size.to_string()) +} + +#[cfg(target_os = "linux")] +fn meminfo_value(data: &str, key: &str) -> Option { + data.lines().find_map(|line| { + line.strip_prefix(key) + .and_then(|line| line.split_once(':')) + .and_then(|(_, value)| value.split_whitespace().next()) + .and_then(|value| value.parse().ok()) + }) +} + +#[cfg(target_os = "linux")] +fn kib_to_gib(kib: u64) -> f64 { + kib as f64 / 1024.0 / 1024.0 +} + +#[cfg(target_os = "linux")] +fn parse_os_release(data: &str) -> Option { + let mut name = None; + let mut version = None; + let mut pretty_name = None; + + for line in data.lines() { + let Some((key, value)) = line.split_once('=') else { + continue; + }; + + let value = clean_os_release_value(value); + + match key { + "PRETTY_NAME" => pretty_name = Some(value), + "NAME" => name = Some(value), + "VERSION_ID" => version = Some(value), + _ => {} + } + } + + match (name, version, pretty_name) { + (_, _, Some(pretty)) if pretty.chars().count() <= 24 => Some(pretty), + (Some(name), Some(version), _) => Some(format!("{name} {version}")), + (Some(_name), None, Some(pretty)) => Some(pretty), + (Some(name), None, None) => Some(name), + _ => None, + } +} + +#[cfg(target_os = "linux")] +fn clean_os_release_value(value: &str) -> String { + value + .trim() + .trim_matches('"') + .replace("\\\"", "\"") + .replace("\\\\", "\\") +} diff --git a/tui/src/theme.rs b/tui/src/theme.rs index f09c6b5..38a55c0 100644 --- a/tui/src/theme.rs +++ b/tui/src/theme.rs @@ -37,8 +37,8 @@ impl Theme { pub const fn tab_color(&self) -> Color { match self { - Theme::Default => Color::Rgb(255, 255, 85), - Theme::Compatible => Color::Yellow, + Theme::Default => Color::White, + Theme::Compatible => Color::White, } }