diff --git a/app-misc/joshuto/Manifest b/app-misc/joshuto/Manifest index 02fb4e8..55760a0 100644 --- a/app-misc/joshuto/Manifest +++ b/app-misc/joshuto/Manifest @@ -1,4 +1,4 @@ -AUX 72aaf0c5d10db0004d48e27c58d18d8f2c568f8f.patch 163466 BLAKE2B 5b84539c7e27ae0e3fad0dd3e627f5720fbd013d2a1c9dc6c348f98a0b06b435b8f136ee534a56088b43e608da3b4b6214e756ec68155b4de2434c39d26df679 SHA512 b43cf2a0e796d5cae9ea00b23f3d1d3ef7efbfaff66aa400d24f232df9b277e0446f0a4f3c148f0a2d8f6d3d584f71dfc4b7fb8cbd2c1101af39b071a9b4d309 +AUX 0001-add-additional-configuration-directories.patch 2577 BLAKE2B 2b5eddb0f151cc0f59769776a11a7b1d42f9c6c49712f113ec4c6807c7e82ce04c8183e1dfbce26502c9e4884290565ceadf99cf92493f45856676d057d37266 SHA512 77e0a67061f26fe820ebe46c2918b6d1d53f802850d8b80f29733c54169de1b14b45b84319ed6bb6cda92510d6d9bd5c9b4fec0d5d69c059ca013cbb1ccfcba3 AUX 99joshuto 33 BLAKE2B 1e032f3bbfd3deb86e4dc380e84162eabaa00060f43184efca9d54cb948267e42d7a2d065827c459cb9a97d87d938c7ab2c4a0f22ca9c6bba01b4c46ef454633 SHA512 cd678cb36bf660ef3d60497f785cf4f991528c3baeb801f14027ddaca4ef96799ee7822725524283ed5e3d39f330c6e1670f3da9b5c90a449e971fb67f6c219f DIST aho-corasick-0.7.18.crate 112923 BLAKE2B 4f6947d1aacf89ccfab0592cdc55fa61ef09cea38231d3f758765dbce328a810c0b588be4ba96e81d64955379ee005722d22a7aec39caea6e72342245d7ca34f SHA512 7a23b16231a90d23ee60ad4c81bc225410599a4560d33d3a203138fc540c39cf1000100fed3aed40dcc371c3635656a3792545dca5dd1aefbde00d8774eebd00 DIST alphanumeric-sort-1.4.3.crate 5796 BLAKE2B 38383f7816ba73baf3ada54059daa808909d6560f904244ed7b6804ededcd13ce4b30aa04a79ac8bb3b226e905561037ecc827f9eb7ae255bf0237598d596e5e SHA512 9b4f0edb16ebf43b8411fcfb6f78c0934155ba7f68817f30ec0d1fde730b812af550f5e1a11411230b4f9074934971734724c39fe3779e1dc0aa9e61aa11292e @@ -7,70 +7,37 @@ DIST arrayref-0.3.6.crate 10035 BLAKE2B 88292fa4b3ad4fccd03772c2f0eca04cc13373fe DIST arrayvec-0.5.2.crate 27838 BLAKE2B 51e2eacae0ef148f3f52d21ae00794e540e7ce4c013fb496dd1347ad91ffbbca199381fffbb064225f829216f6c5e915edfa64833f91fabdd13c3f011d86491f SHA512 1896b5f64b4dbdcff8ad234bda4ea8129bcacf87839347304717e94ee9f369cf5f4371755e453ff7d72817edb8f7fdbc726d77cc4f28ed05148dc89c7714b004 DIST atty-0.2.14.crate 5470 BLAKE2B 2db856a9e898a430258f059aeaf7c844a153293e8856d90ac81f7d91a888c89198768ad5cb09303c23241fe85c560a55148fa56a303651a82b0edb895616bfab SHA512 d7b6c4b9a0f898d91ddbc41a5ee45bbf45d1d269508c8cc87ee3e3990500e41e0ec387afb1f3bc7db55bedac396dd86c6509f4bf9e5148d809c3802edcc5e1d9 DIST autocfg-1.0.1.crate 12908 BLAKE2B 40c53cab298e4f26634c3acff3ece6a3371188d91dbf377ed664eabedcde20536edaa93daf406618f37edde019f049a6e7b9a47f627344587dbd126bee2b5e3a SHA512 630b348acb98b012e97804e6325d03c89abc22f2157762c59144c04e6c733daf550bdc7f0fe0b9f3b50e15dae8c1c3c4bdfce3d805b02f0fc987311f5332419b -DIST base-x-0.2.8.crate 10614 BLAKE2B de50c274295b12234d9c4b8a551058b3345f3f3801cda0141f18b6df9e0f92d2a1fe09dca185e475fb95a1b2bee7935549d1ca1bf882d77e64afad5bb0b55955 SHA512 ad140fc44bdf0342875b7087ee242e70ebedf591075cf80d2362f74e544882971bd9b1cc21dc5b4ac13e38710ec0e087474b54b238d6ea6748d3ca4755b25929 DIST base64-0.13.0.crate 62070 BLAKE2B b957f65cdb1e28baeca0cefc92fa98be797409b7dabd15e0e88db6cdfb89779b662cba9f2270fbf3b7b66948fdc46c118b8040a78ab72049c48a928fa802bee0 SHA512 991a72999839daa232f508c5b24e7d3225e8a26db8d1d0e747881b115af9e408b92374e163b31e0b0d324c1c2e57e8e38d66861b61eb0a1dba87bb5871940151 -DIST beef-0.5.0.crate 14870 BLAKE2B 486e92a57e6c9dd109256a80ebf0e2bfc9aec6ab0d6f4958f5ac0c4a2616b56d9d8947f5c9f2bcaaf313e14af0447b39bc1edfd2e77b21d0308c00398dead4b1 SHA512 f46643f7aecbe5784dbae3f4bd20dd186a752534a5fd2170d9277b813b5bd9e15498e4f1296643526b201992cd7fc044acef5bd9dbf55cab3437865ad71df12f DIST bitflags-1.2.1.crate 16745 BLAKE2B 0fa6d3ce44aad7616d5cd02aad8c1d0b0fed4022650eb43067c4a72e6fc88da05442674fa51826e4858a47c9de233e1ba2229820af094197cd11bb416ceffb2b SHA512 ad89b3798845e23737a620bba581c2ff1ff3e15bac12555c765e201d2c0b90ecea0cdbc5b5b1a3fa9858c385e8e041f8226f5acfae5bbbe9925643fff2bf3f0b DIST blake2b_simd-0.5.11.crate 34096 BLAKE2B 480fc200ce3fa3bb364ae05590fe26f59efb6f81fc2fcb7ae1593671677daa6f1b526d800099d002239e2ad435b919e9b32778021c0790954383079a49a90965 SHA512 4a7657db637869465637cb9a65cb82e7a119c554bd4d532aaf84f9cc77a494fda07d07db89c73e92e5bf4844bb1be53062fc61120e839e414e938e487e7f2257 DIST bstr-0.2.16.crate 330346 BLAKE2B 75a345f3a5d428ec7278cd10fa676f5bb72685c65c4fe68163943cf3142b43ac45d458bce9323447b201ffcc91aa82cd8c762cb1954c055e34b1a5cebc686ee8 SHA512 33e82e5637efdc2f404ab9405331ae135df12586785491c3e61e70ea8406c67e2109e550cc70a4ab8e95d054e8519c48257fd3b55ef0b67b2530914a9a0b0fac -DIST bumpalo-3.6.1.crate 133836 BLAKE2B d67f19bd68e87c1c1360c77df2cd9b11e66f4db3ed5468463d266d2ce187006f2b2117f647a9c331838b8ce6c50519db2f9645fbce190ade2c10a0284b29fa06 SHA512 0d923bda2c98bae60d8ca09d63dc12b67c8fb5addd4a675e27b619bb41b36d3dfc0742696fb53e5fa538790814cf2401d15b110216daf49e5a2ce046bd540866 DIST cassowary-0.3.0.crate 22876 BLAKE2B 7e74a08e02050548ade7dd1ebba7ce4e4360d258ea6acf126453889dbf16df433bed7b68789736881c957f4c09eead1f763a0c02f2474157b1650a1e77e6eca9 SHA512 0838c0b79ed31f0c514fe4ac82633976e34b0d6cb08616313cda0e00623514fc6498c6c308cfef54ea029f1fdbaafe2991ca8ac3c38437a113ac62e37f9397f8 DIST cc-1.0.67.crate 53486 BLAKE2B 42fd02a5886df50857075c909819c8afcf091cee6b7bc517848786f287f4559e70a07f0a0f42a742baa2665465dfdb2139ecac7e93f1a41b16eab30556eb0259 SHA512 f1ad4abdaad2667b190d1f8df8515f603107be1f69bdbdc02b5159764a6ed18b3f672d6b06af50c7f2fd3e6e3dad5df0fcd0dda762d909ba0922c769f1efbe05 DIST cfg-if-0.1.10.crate 7933 BLAKE2B 063a96ed176f34f788666b40adc483d147fc011dee941ab60569ddd0e57502b5dd06ed71090f4e14ce005d06e240500a286f74652615e9d068fba649610d8cf8 SHA512 9d22616bfb4a75770a828a0a3cddac6787297a5fdc53eb17e25811cc94de717f2de8bd66d53c5d65ba1c83d8892aefee5ae758cf56a1ef0a0c3120f70b244339 DIST cfg-if-1.0.0.crate 7934 BLAKE2B e99a5589c11d79d77a4537b34ce0a45d37b981c123b79b807cea836c89fc3926d693458893baca2882448d3d44e3f64e06141f6d916b748daa10b8cc1ae16d1b SHA512 0fb16a8882fd30e86b62c5143b1cb18ab564e84e75bd1f28fd12f24ffdc4a42e0d2e012a99abb606c12efe3c11061ff5bf8e24ab053e550ae083f7d90f6576ff DIST chrono-0.4.19.crate 155663 BLAKE2B c92c273fb6475bbb2546dfb75eaa23321bc8f9a5fa8a7c652f527649b96ff8718fa932f52b500b02a4acae7837df5bdb14f69cb821d4962be2790dbd1d023a54 SHA512 a119349bfc2243a249f1d18b1ae548a04b30fecb75913a56f26d1ff8c0eb53097a2674d9141e2094018191cbbc1620843fbddaf52999824e077c1157f0907980 DIST clap-2.33.3.crate 201925 BLAKE2B bec9c866481c5b3fddeb314f68af9bce38fc421e42816182de3209e8ea3447b72cf033e6251eea27fe974eff8085b7d98cdd2911b5cc0ec6b4bf4c750deb8a25 SHA512 3eb0fd648e2e3f9e5ff69a5e6cf0d867304fe18523accd036f28a86de368e4774088a6936c108ccc045092c539fe7f7494ea96420ebf6b4bec16880cea84bedf -DIST colors-transform-0.2.11.crate 10094 BLAKE2B e646e8b22aed7385d0edef41fa3173fc505dc13f02c31b3af4c24ce8309e0f669871d874bac130a9f54d9710326d98195902141dbfe94d974d30ea10a69a5202 SHA512 9135e971049124b9a399382cb4634fd0c98b07058fedb62c3249539f9a442ba85caa4fe4313d34c0303547ed7ff3ca6e07de855d467fd00459bba2c788550b48 -DIST const_fn-0.4.8.crate 12662 BLAKE2B ee8d12d8bd01e64c308b27fe4f55e665fe6ccbba6e911745061e816265b096d17c708fc4ff9d28ebe7101a6523edc65e8c54d189a4a9815b2d4341c69f20d741 SHA512 e7bd5c50a10f55bc9578e55f9bca80c8ca1cebcd49206ce1feeeeaaac3dfbefdaa89f3c197a992d8ef52efc8327b3b34935e253a41ae9ac20b0b08b73f19df8b DIST constant_time_eq-0.1.5.crate 4936 BLAKE2B 882dbf33f20954205fcc5b6e39863db8969d184b697fd51ef462f6890c1a754e3fae67bcc7db685d8cc26abe6e3871d3b80aa542489ba9551a0c95a49f7a6dc2 SHA512 a4e0155a7ad72babcfd418d832d362b3fca7333aaaf36c246b00e948983837c3c93378b86e37c5fa7626fe137e3b6d77276ccc61624a7f4ab914605905a88a01 -DIST crossbeam-0.8.0.crate 10993 BLAKE2B 9758a7ed1373f10da09c07875842a1fbb549dd20add43c50918276574fa57b5c5b51d15593e6611b34ff2472e51770fd965fc0810d0bf18f7740467d866c5669 SHA512 8846d29074f5e2a601e1bb741db9396b16270689f108e0b1621d29d15e774898e5f8d159e9af990fbba2cb414a13948a6236254353d4c594c38bf9cbfd2032d7 -DIST crossbeam-channel-0.4.4.crate 86868 BLAKE2B 88629c72c0be41bb3a0d7dc92f6908d46cb397223449da5b2c990b7660e09dfd3e3f3fb708d13586f5dbf199d62f781f1f7e0b73d279de0ef810f7bcf25b3f27 SHA512 2933721d6af3126f492f112f3d662fc40fb49139a84c72d33b6c2b0aa94fe964acb302fe726e999be4292a1410d3ee896169a0434dccfbf44d166008719846d3 -DIST crossbeam-channel-0.5.1.crate 86919 BLAKE2B b223d0dcacbb09850d457825cb2a018494d798d0000a20eed3f54b1152e41ebca4698e7d50e81f467b86543779155ad08566da9496eee36aa06644b69cf5d7eb SHA512 f15aff67e9105584f5fe41e1ee650ae4fdd0d0ca0fa9202ee83c6f6025398a300decaa50d1b4682e8afb9bd6e11e95b69bcf23f68ae117419aa84df14ee7747b -DIST crossbeam-deque-0.8.0.crate 20756 BLAKE2B 6bb602547cb0ca65552a9b981502221f1d3570422d22c867f654ba677e5c95aa5f81ed0022a498d3408c3f69291e1805b49fcfbfaff0d9a6075b75be3bf926ea SHA512 4efa73dcb9ef40b841039d24ffaf9bd7c63f8c0233bba1e0728fd5558702b4ef0af117543834c527335e99384d3c80d56293e891c9d94440f51f454b1b90c399 -DIST crossbeam-epoch-0.9.4.crate 42875 BLAKE2B 9c1f6faadddb5d01bdee18d09cd36016b1519830f4f2090b9ac6477b0d9ff4763ec473a40514dd2bf27c9f3ff06cbd98bd21084fe35fba7b2b515502b8baa794 SHA512 d5d2bf6a19986a8a7a6cccdefc46dde539e9772dd6d3ab9eb9275ec1006d0a517ada49e87c91d424b6ac63de82193d6dd95e733b65e097062567c91fa17befc2 -DIST crossbeam-queue-0.3.1.crate 14787 BLAKE2B 136cf26e3a932a4c8035c50b8d6f905f59d3116a8bfaaeb5511e48e7225d05857722240e169d8efe3aab07c370923a57178f058f05c83cee9c1992d03f907f1e SHA512 f666d14ffe4be603ada67ac1fd28526bd2517c32856dc077e5bfe512fa012c08f197e206afb2547b9b5a52ecfb1231a9bffb5b9d24cc4e58aee37ebb87b54d6f -DIST crossbeam-utils-0.7.2.crate 34338 BLAKE2B 3cb287c7741c4d5b0551331634a75b066f07fb4b55fa2b347370506467a05923254b1c4dca667de59ed91ff91f5496b37f40f13d3e9885a1b4f639f5b6748433 SHA512 e375f24c007bcf660d9e297527ed938f678a55696ca7b555b96fee7e0b94c31db2d3f4355675aa0baeadba68b9755ec92dc3a09a37b5db48e3723b926fd4a8f3 DIST crossbeam-utils-0.8.4.crate 37279 BLAKE2B 55372ee1bec00b4bb3ad8fdd1df3bae4b0c166aa08898c0400663b4ea8610c956fc5376fd1638492e0d887abe65491e380eaf73459545325a2ef1d23234eae6b SHA512 6147ee3048f2df2c311c6d9d683b239249e6f49f8b2b27eaeaea9361b32fccb1ba37fd8bd3fa147d70b7d7d8d3281d3018939c4a70a75e191da7d86128c4648c -DIST darling-0.10.2.crate 17620 BLAKE2B 33d1fc3dc10fc971ea304efe5bf8084843241ca9c2a89e54e7c5227e53b1ad86749bd8693989ced6bf17805001909033aff92d600e7169a02dccf009fe60a88a SHA512 b312a74e577cb2f889315ae42513c7f26597faff306a40281189be2101339661772016a5e197466bd85ef94c275e811adee1b7c0772458126677d1998ed6fb15 -DIST darling_core-0.10.2.crate 44339 BLAKE2B 3ab3762840aa869baccf1030617a2a534c5d63019deb7ec5848cf4f80aa6304307ae32c4425264f1fda220a502110549812112d08f0f60261b30731ee47335af SHA512 a0af8e8ebb8584973c20eac01fe9ae828744b5e86cbe268262f8710a2e0ad568bbc6cd051d5225cc536a0a1fcb1886233063c8c18ea16b45c47207ce64af89d9 -DIST darling_macro-0.10.2.crate 1919 BLAKE2B 6f07815ff5b333b6c34df08f3aec2e5af5385e60a94bf9d169701be19935d2a9292ec7396905d2caadddba38d3f70bc5e5c3f1167690f045b778b8fc8cb00985 SHA512 43a0e9091fe12ec986e229a73bc41e23b1815fecfe62df8eed74d2ef33f5c329c444f1568d3c966554ff0bb29220146ba8f30d1c2d77ed7dea9adea10dacd152 -DIST defer-drop-1.0.1.crate 9062 BLAKE2B 6b2e1d29d4e7141e70af1c11669e42c7b66dcbc999fd1e0c4de5786b307c773cc2581d8858ce3a405009285d70223d2e69404ac6cd583533a161fec03169f87a SHA512 317f6bbf340d6ff60c624d45b829563ea36d85b1de82cf3543227b11b0c95c1c23e44d02be7315f0c99db0af932d71aaec2f41c066b3abf28ebe3b86bbe95e01 -DIST derive_builder-0.9.0.crate 38161 BLAKE2B 08bcbf8851ba813627a56e3f93a95f08a938e0cdd4f2a7971961eb5ecbdd3c96f6143214b49d8ae6cf6be166a934208ff7d0f768a3408868cab093872860e7dc SHA512 e56a01ed13420ac024be394883e5cf148f83ea74d2488931216d84cd2e8f00953e2d61f9b81d34f18be40bda055c02614baeaa89d5fbb9d3defe9ed314f2ef95 -DIST derive_builder_core-0.9.0.crate 18328 BLAKE2B b7a70372bf9300a2957927dc6bf45d64ff923552d2aff463e9811cf295d8bf300f8e3a03c73d08e1f727e91bb0eca2d34e332bd65a1b43506b9d486e559c879a SHA512 432e17868ffbbf6e776ae885eac33617ce06e5f1cb9610e2ced4f17a0d2aa46d3576ec3249f92275379d875cd90dd86ba4de882089ad620fe6497fcd301e4fdf DIST dirs-1.0.5.crate 12908 BLAKE2B 0a5c1428087adeca310d7db53850ca0ee4b27df34a7629f13ca0f3c69c019c0ca2339949022317ec55ca0be35aa721e0a9040d9c9d011e1516d99772ccf8f730 SHA512 12ebc3e92511373b11c2b7913b7bf74f8022344758057a2c71e36ec262e7ea6ac386bc75c323317406f1b25e965e047ddb308ff5017a1e607b48b978414e7416 -DIST dirs-2.0.2.crate 11779 BLAKE2B d1a6152d05a98eacff15c6c7f1f550d475b5a1cf62e541a2fa8b9836b9a1ea6b98f9314341dda35929b968fcf8a47dac7679c5c0b0dd97f21564a8d469c2e254 SHA512 34d6e5956c9db1dae965d33f13c64dde59d3e0e18cbdc56c02f7f31cac8e0034a80fbb561e0a73b8dbd145f85b46fc4e8a147b4c946b5816d8dda6caef185396 DIST dirs-next-2.0.0.crate 11689 BLAKE2B f5022bc51dd50bad4ad0fd05b159a4117aca47afbea66dc42c8306ca58f3a550165afbcf9f5f721ef5ad8d357eaff305c6f6e42789354a910d5f1d05d3b7b7c6 SHA512 6ccb732da8ccf7bf35952c22a3b0caa8238319feb0a6cd3b0957e6be12548a2ce507c69cb6d3cbd2adfb37e13e6521c6229da5999edb0e47a292a41c3ea1a766 -DIST dirs-sys-0.3.6.crate 10626 BLAKE2B 6da8e4a1e51a4e06ab742ce5eb75155ff9b7cbe83f06947a0bfcda711ae1e0dbe51f9a1e1733ba771f2daddb2b8b14e343b9615608c1d9a8fb927b033c161b15 SHA512 79b6bfda14aafa3839365496e1b1926f763d3569e4e138a59f4acae15c38ec9a3bdcaa64293b03b536141c897c2bf68a67d7ae5670d86215080aa313e53d39e5 DIST dirs-sys-next-0.1.2.crate 10681 BLAKE2B 71431533dbfd6016cc309c14a842ac8d43577abe768e69bd2caaf7d19d743f3ca95b9b0be1747077282089c64485f3d4e24bec8e56d4d883f25e494d328fbf3a SHA512 b3c40a8e93d4f9f4a890718076e14779aedd67a79da61b466788268c1eaea19aa493f043a7e410f5023a23d5509e639a6fc6681fbee30e252a601091cfffa2d5 -DIST discard-1.0.4.crate 4700 BLAKE2B 423cb655d6d58b4ac68269a63332f4828a3f6a4823f6f98f83d748bd16afb7ae68d2bfe5852fbd86c10b79713576d6e16425bd2541451f715a7e9e3a9f2d2927 SHA512 51e0335509a16c73d2620ff83de4b73506a45b36e306dd0eedefcfe89c6054eb5abcfed0ff5b3868c3b17a1c6d82d958d7899f25aba50709c5dd486fdfd0dd6e DIST either-1.6.1.crate 13641 BLAKE2B e5f40c40a5edb6dcb07a10bf79183cbe42438f1f70f3932dce72f6f6e91f75f24d17d82bc447507def4dad4345ffc9dd9162dde778afb253bdb1218e91887949 SHA512 4bfe56920e30cbc8eb4f90162db618f7dca653b42db35ab6a7045d3fd9a24ceb1778b1f79613850bdb1a87ad3794fa0d73015e46c48d513f368d8c3776fc9ddf -DIST env_logger-0.8.3.crate 32543 BLAKE2B 513790f39c63eb096b0fb62687c74262b42b0edc3e6fc2e2f2fdd44463eb4cfbf67560136ec206e252afa1477fabf66917f4fc0e8192e040670f98f3d7c4bb51 SHA512 7f6c3c79b8f4efb8d1d4e4b879c1c78a427f15669244ce1eca869aea9bcad950ffa5b59f3f8e4513e085c2daf1f5857313b374e238fc78b731bba2646ec895ff -DIST filetime-0.2.14.crate 14358 BLAKE2B 7d50e71b5a556bc24a6bcf737ec07f185c6d6a2ba2717d91aaba71ec15d1981c47dd6010e5a4278f8996e05bd49d04f3481f0b9e3156a8ad1da1cf39a84796d6 SHA512 f2e6e41b8b705c510e1f1932451ab8a0acc6a4f84a7a21880c7e69639a6aace7c5ed4f694ebf47d04ae6ff227f8d6c6733f2c4bcb953088531dd91b37262e45b DIST fnv-1.0.7.crate 11266 BLAKE2B 81da85889c91b6567e0f555e37dd915f1bd919719d1ca10c31a6861d7aec29a49ae9c1e8bc500791bf9d6b8dbb318c096d04872c5872a4b1f7d45fbd8e12842d SHA512 2195a4b34a78e2dd9838caf0ee556bf87cbb4a8ef5505aac663b614eb59dcfc0c40f432463ede41ecca57bfe7711f72673d39a85fe03d426f1324097d5628334 -DIST fuzzy-matcher-0.3.7.crate 18047 BLAKE2B 934b90a74826393ceccc3e433df7cbc056a10744077e7a2178df9d9edc9db5d4cbc86d006c0ef1f7d82f4fb8ea0d52df71be1c7cc9ee39b433207d7f2126404e SHA512 ebcb6de06dd66da952183c75e4a44988bc60df17f035fe541c134f1c4e3c33d18a7385a9867fc23a99c07cef2b2737edd6128dea6546e243985da2f3a55dd8e3 DIST getrandom-0.1.16.crate 25077 BLAKE2B 0cbe96c27e78100c181a064e5fe524efa9a7a267fe60f8336d2ae0125883acd5d575ff17d1d56607255d9b2c30cb9d962026fdea1a5c3c29a5e0760d27c3136a SHA512 c5450c522c07c7a38b326f9a9062bac7d089630219d577ea4b55abad4e0c31d17b7cde385fc43912dfa100b42334e7a52422c55fda8b738caae428c6f9addb53 DIST getrandom-0.2.2.crate 26010 BLAKE2B f2df79db0fff4a4e57bb5c748932dd7a8d24f7072f9a81fa92159ea79de29a70e7b834af6ffc5178e898af456188f16476043e9be4dd25c6e7edde06d93cbb8a SHA512 f498fe00c9887748a0be88fbd698a6087ccb79874cfeb35a18f90994603be29cb2aacfbc65fb8ba967190ccbc41ff9ff56bfff1de40811e1bc99a08b0568f59b DIST globset-0.4.6.crate 22893 BLAKE2B d47dce5ddb342b5c544f50c01160df66e81e80ca8a0abbf90a74ba67aa9c585843c051ea98ceb7249d4a56e5c1b985b00df734ec0fd19439274a8c1f998dbe75 SHA512 aac2b1b0f47103a0e8b404f4c97bcaa8561d51683fe741a85d745b3f30b56f0523c2fa21f21a680d9e883c697eb4232180f042dca290e954ac55429ae251fcbc DIST heck-0.3.2.crate 54718 BLAKE2B 6514f604361932e0a8e1a86786d3ec7218d95f8b3b3bcfc9e21c5fddc58ebe28bc0781e2ad24de4dd4296da85e97c742d8473370c99a593e7e5fc7df00fc9b4c SHA512 cbc72c3473ab14fe445491b1d9586d50de9a462af344638b871f7309fa805069a1405bcb1e0859b561f48583fc71045f38d03b92332d35131c67e140ccd241ad DIST hermit-abi-0.1.18.crate 9936 BLAKE2B a5a1d1c9bdf83fdca8edc392f8fa7d9b9b248ac8d716e009300220befa5d8d80601643e768037be89bbbe6e21adbe6349c94c595cee3837c4b92b5f98ba838ad SHA512 54f060c6c1c80d41f40cec7102345147efb535aff9fa5cc0ed4ccd7f010bfdb6daaf40626fd5069af60ceb42058452803b59d4bbcfbed4c5546c79b57ae0f914 -DIST humantime-2.1.0.crate 16749 BLAKE2B e2ae8325b037fb175b9200cc5c1944ce579056c6662cce307beb6701894552362a25e371aad65f8fb9384945b48815ca74bb8b544a32e0a5845b7edd30b918c9 SHA512 3bf29ddd1391d82897c22baa0ff3ed58ef6d6959859f1f8ed54d324caba5b6fb4422e56790511ce82f902cd11467f93c8ab7fc7b0e0bdb719308a4d0a446ae0c -DIST ident_case-1.0.1.crate 3492 BLAKE2B bc79ebeefbb7e3ed1139e3f41d8d20fb175786bb123bdb9c1a92ea70effb4a0e5e798f24b068cd66a1bf20d53eea4bf24de495b5568c2d649ea804389a1327ab SHA512 81003a43f18da5997d644319274502e2066af9f9fd1400afda7cf2986b3ae0b7355b932302723cd3bda2d46b264340434d9279dea58425bad13785698d5808a9 -DIST itoa-0.4.7.crate 12099 BLAKE2B 0e4ffbaad504565056f74c3ef560a87eff321a0da6d7a2c8fa35813c207713c22d77080c3b830fefbb21370dd29cfbc6a2807044485b38ac1e0c9c1de3ccebc5 SHA512 c61eb50aa00591af28698b45c528c36bd92088f7cd2f453cf686a1824f4656292638bebc468cf67f903473a5045f22777af623cc0515ef3bf25146b89a7c454f DIST joshuto-0.9.0.tar.gz 581719 BLAKE2B 0b8c70a15b6d3e18943b356487fc179cd48c6294e7431fe0de877038d517331232318decd532651ecb70479fcf99e743f08dfe81ef098ad9bf092a6a593ca566 SHA512 328b1ff1caca9fd1c1ffee21e1ab56b6820f161f7cf90d9f1a8d82508a71359dbeed1e55f6c2145cb05938b6bd60a68cac3c973f417e9121162aa4b592eb2ccc DIST lazy_static-1.4.0.crate 10443 BLAKE2B 25b2e61bbac48f0dcbc79c81d7bf01f2403d8269ecb6be3ea6147bd00f7a588df15a91f44dfc18ada19b21faa71de4637c7d493a8628cbecd0e547d74e616a23 SHA512 e124c0521ec7c950f3c4a066821918da7a9c6e711115d98009ae7c351928fdddead852e7596fea5937a9c30e4e4ce8eee7099b20248b5d6e3b2494b6a6d88cb8 DIST libc-0.2.94.crate 511713 BLAKE2B 6ad3fe9aa5ea5fb06a7b2beeb68fa245e5ed7d19aa7e4b21c9e2ab73da11a9249913e604f0f87fbcc82676cceee16f14403cd2f27ae462730e1682c539666283 SHA512 316717d2e46b57c200d67d0ebb4fb162cb1f0b688895b9eb6075924cda3be8ba7fae85319692682178b6fc5cb2764e8b3a9d3e7ce234fd8a21a0a9c453ca174c DIST log-0.4.14.crate 34582 BLAKE2B ddfba35947ae1f5905cd9ecb9eb862a78af6f00ee8b8fe6258b369b140928fe677a02b1b3ca5bdec36ff2b16abd85a9f49688fd5f3d1ba2b2905e7f96b8a84c1 SHA512 796100167663d85a7bc4244cd305e9b3f0a1b1520764b63464698eb136318d0928c40c16f5d19d9f602a5bf769851275bbd48d66b088b0c37be7a6fb62def7cc -DIST maybe-uninit-2.0.0.crate 11809 BLAKE2B 5e517b8c59f9ae4f1a4f86b48679ea64d62450ec2519c8caaa914479ce9e5b3aff24707e2e37272ba74bb60499afdc602fff17756337b0c50a9184edbd8b8805 SHA512 3006fc009c7c743d9147a4122e677cdeb2546f7bb46963b2f266839614eb906f9d763c161044fd0bf3f7b54124ac0734ac9ae7f7151b1a7a5f45cbc739976434 DIST memchr-2.4.0.crate 63392 BLAKE2B a3f30546c3b58ff4eba534bd7046446e96ad793718edfd3379bd125c47eb270728c4aed4aed1c6afa27032f74078b2b2ddddd5cc6044e117e2b956bb13f902a6 SHA512 b142e308a5aef8e45910411789031e194349ee540c4ced0e2384d864dc1913299fb63a161ceb5228256e97d0949661b7f83a169ef9d4b78afbd9004cb7b8a2fb -DIST memoffset-0.6.3.crate 7697 BLAKE2B aae9b5dedf06680bc597825653c08bcfaef6429a8367c8dbb58df7f09e91b166d04a231f28856af592590eda0e255a947294e0b8064d7651f490e44e4d1e748a SHA512 5afd2f9a282e9bbc60da1abbf911a3b4480ab975c04c565149dca8a36e9975b3262023b73c67d9dcf80b2eba3e8540aa2b91466d37a2504facb3f1eae98f52bd DIST nix-0.13.1.crate 176633 BLAKE2B b1300379eef1ea43b4dc638c9a8d8ef792dd9c134a0e4e22e94e9a5f2cb247769b676a8c4cf74924c3f34abbd03083ff6676549d766408657a8ebdbe71eba628 SHA512 d5c4b588c0c394dd2420cb63bdca3d49572c83f7922fd5cedcd494a5609a31f1cc4fd806304f95c15064686af39eccee11448e54889b0a379e30b5b2dc35733b -DIST nix-0.14.1.crate 185227 BLAKE2B ecd12ae7580879c960cd828a22109e5a7f209a24c4208bc04d4392f36726886b66b147dbd3a1f3705edd35e53187553c125dfd47589a326c032aab0a3d3c9ba2 SHA512 c6393f47cdff2134cd51ca3d6becf0309697a11ac9956e3979a2d6cd00a86545d1af4efd63f6d5e417a80b2d9b247a7416b7182156d9966e00c6da25a3bfdcb3 -DIST nix-0.19.1.crate 213462 BLAKE2B 6abc355e7635272adf3933ec5835704a1b1b13b2d2a0e1a4d93280d91093184c7a0a115b75aecd44420b5f4f8e766fa0a86ae3cb96f71ab91bcbd0455a2bcc09 SHA512 0ac549babd0ea438825ad875dbaa4563d8eb90d83160dde429c0a97bb77d4ed3f19f1ad17437c61da69aed3f23382d464e99bbed0199678f7de41cd38953b51c DIST num-integer-0.1.44.crate 22216 BLAKE2B e1c08427e006cde6f2084adadb6086e87e6d6f8bb8dfa757a8228aa671e862a366e4bd8ca5e0500008c18bab128aead9bd5b1e53568a4f40afadcaf3882ee98f SHA512 d07e27ede02a1d007373935fd91e57a26e0e84ae14bbe24be66763baae6850788bd64ad2598d2bde4f4fad6c8a4675c40bfe0927164b16b9b69de5e9a83d9771 DIST num-traits-0.2.14.crate 45476 BLAKE2B ae310d9d5640acc3e45e1e5d1d2f519539795922c0058ee940c94c94b6654b39358b7c18dd23a276f2c1b16a30dd4de4cbc8575bcda6a5c11e70665d670e6439 SHA512 c3028eca9f7b718de0db3a36cf3e462bdba43562d52c9b809ed4cc0aa6af403aea542d6d4da743cd1dd541397815a3c5a84cef4d6e40122994e4be6a62319b2e -DIST num_cpus-1.13.0.crate 14704 BLAKE2B e7a26e597ad5e45309393a9500b031ba64a77831320cbb96d7861139a2f7a453b7ba06a3255439b43ac1e2e36269b0a350d514020d3cd82c2513b57934b3ebbc SHA512 e75ec298fa682be84bf4efb6cf40126da9233ef25f07e887c2fa7421ee78790204564e6406c8219466651f47421e27f69eca690bb9cdfc982b644d78cc10de3f DIST numtoa-0.1.0.crate 8999 BLAKE2B 6a8cbf17458227fa87bdd6a35404e09afc092a1ea45d68c6c035e08a9d344fdb356b1bc7b52239dd6354ed9094e9338ccac599542bd7f0caf167ab8d17ad5fa7 SHA512 41b5c774048592c5867fba217c85d4ece4540e0f3ab0eea7dd1a6af340ba46dae42bbca62ea7fe3afdb258660f39a3d3082264c99dea67d3d1ae178d00a01354 -DIST once_cell-1.7.2.crate 28250 BLAKE2B a30a55f6d6e820c691928173a9ce70a60486b28e3e79e8a01a08d87ca0bfb1725b967cc9e070cf53e71b924f73fc2eec2cf67190fc743361b60d82290762725d SHA512 30cf51249bb73e9881cfbc6a54ead7a3db709d560da8d420fd85cf248e66c727b92e8351b7c0c682913cff12b3f984684a272a69c965c56f8343948eb5a194d6 DIST open-1.7.0.crate 6101 BLAKE2B a0ab3b5c9c48999962dcd7af73231f3b2887fdc4244ac066998660029216f10c71cf32e7f08e788bb6cf4f945569acdc4ebb2ce2094d82377b7a4f38304a03da SHA512 755d199424644347dc60527865141616a64d86c2629b35960e30a8130f6f1e6c389c1f6cbb13b9c2f8746f9bfbf599ed708a54aeef95a107ab73631e8006921b DIST phf-0.8.0.crate 3902 BLAKE2B 3f1d4f9c23cfa2a3a0b7e4f809ff00783d71bb4839b27246d5244e5aee61a211498715ed576f00749e8132a6af1cdf50b2eb27d2f49896f006212981886a0e44 SHA512 a3013c4106ba72aa3cf22bd3f903eeacc24ac7cc47aad791bc5e9a63e1aff928a537399b6a86b0346c5eb37979ec01b404807e622e79a0a70a0e01e63c07a47f DIST phf_generator-0.8.0.crate 7604 BLAKE2B 936c9ad95d2d5b6b4bc97dac9bcf99813462950f6280d9cbb8c8ae9253d3197f25b8173c202cdd51c4a2d3f422ca1d6f5c9055e7a87e45b2dc5fbe5aa6aa45ce SHA512 de045f47567defd43fe32fc62191a9a892e5a478e1a84b853cff3005e94967ded68e5770eacb43f2e97e58b8f4283327a38a3bdbd55e1d5c708dab601ea66270 @@ -87,8 +54,6 @@ DIST rand_chacha-0.2.2.crate 13267 BLAKE2B 7908867ceac98243ade22e1b38f1903fe0249 DIST rand_core-0.5.1.crate 21116 BLAKE2B e74791f941a79971f2741172d489d546373c9abcb0dfbffcb7b97b858ec800b2e0c97df4ac636f3aa1b8dd6c14685edf317336d577f31b5c6cb7d89a157e547a SHA512 4f7500b35e165e6c817fdd67a50745d5497d24e554bb554705097e37258751e8755c4d6b8a69fcb5e1977708ba78620bc35d640e4e018fcd4e88d9dbdbebdcbf DIST rand_hc-0.2.0.crate 11670 BLAKE2B 55fd048f2524cecd4f0e17927a81111e3070a8cc6a5b0234a46445400ad5527194edf8c91fb5ad6538f4958d53044ab02424f61a38adb2931e2cb7568c458ee8 SHA512 bca185612bed5cee4da76fb68fe854105da276f5bf2da464e596d586b925df798cc692ed881e276ab77c36b4b0551930966c93656be122ad05899d87853533b0 DIST rand_pcg-0.2.1.crate 11291 BLAKE2B f8837f3f3dcd7ecfc90f88bb6464b9f79f7c1975ecc68289fd10a5c97323de9c1106de9847fc798f50d96044e46cca9d41f1635130be40bc789492bfaf999de9 SHA512 612c0d1cdc591f80733bf8097e251f02ef7a7e71cafb74e37b63ac68043558045c0c96196200ad07ce7aa9f2d373640c20e598ae5774935c8b52350ec20958ba -DIST rayon-1.5.1.crate 160424 BLAKE2B 1c31c8e3290f76d02347271cb020e50e8f915b7a064f133a196c12e07ae1551c0e7c31883a31ec419a05198d6c71f0057be1b8ddb21f451db9ba40da511a0e1a SHA512 a68e65aae7040a6f6b0cc33b53b4c22929c15504ed4fdf54f5eb5fcaeab137c220b00c716aed96246b6a762c4f1e8be920356231d6c4a0b3e01132b9ab96ffc9 -DIST rayon-core-1.9.1.crate 64961 BLAKE2B 7201024124324d2cf2d5785b7e79d2195adc7de576b826a9c28603dc44f1b5de46d277b791a741413c85facb4f4a552bfd55989a190f6f5ea3df4bbd32042f66 SHA512 c24c34dc488171ce476df145e8c6953d35fea93412805f6c411ba8b8e9dbbd733610b291203ee91bd265b766b78e14ba15a7b587e8f0ae8bde53f60e0644ef78 DIST redox_syscall-0.1.57.crate 17087 BLAKE2B 88e3ffcfd752e757f8fadfd4edca367f9185f09e609c329bb36f179183cf103dc182aae701c14afb717d2b4c3d72ba307b49fc671cc97aa7c9d03df1a7a1835f SHA512 c6e187087060084b7173ed0d9d0e982e4259d4f76522112268c02ff20751382e3bc8e119da6153170f5c54bd5b9cb028910f2f85c1c842099205dccd44659184 DIST redox_syscall-0.2.8.crate 23697 BLAKE2B 5a084a48e06ab0dc69f64b05058b78d994040da6c42f04c8b615b1977fa3e813cd5a531ab33402402914362301670709679aaaa321e8904424c38d35c284b7ec SHA512 250556a7683254c9daf22887b39abb010eb9d4fe08b944e52bc6595ef6d8acfed76e5f43931fe20c84bdb3743772fb62a0be154ecfb6e66c2facb4c73546eacf DIST redox_termios-0.1.2.crate 3268 BLAKE2B 5f3f4e2b7e7a8172f92e8161eb1dcd208b86320868ec351e2f7b47d8ed170b3f44ad8180e44ea7a554de0e53fc268365e683244ad59e4afabd11a09ae378d2b0 SHA512 d8624b2c78d02c5d3afcbecea9ad8d218bff508703cb50684d6ae05614a9f41bf2aa8c47440fbb7d964f01eb9085364222833fbf9c45984508e9d755dac563c1 @@ -97,70 +62,38 @@ DIST redox_users-0.4.0.crate 13023 BLAKE2B 66d0d1169f98a27a00930c86365f289c38659 DIST regex-1.5.4.crate 236581 BLAKE2B 6efaf69d1a99dc3a2e04b2d1a96b036f631e9a0ad0d3aa57263febd47f7ec12765526f06f9c52a5497bf0d9b455f1d1b39e011adc4c28530c44b65c8a453efc0 SHA512 1a9208358c4ab87c19ec91bcf5c1e35dede46f3a0c0097061b7b53fa77a1e5ad38090d243aab274956f09c491e5fbe3b3b35a91db079b82a2dde2fd9fbad4c19 DIST regex-syntax-0.6.25.crate 293293 BLAKE2B d5ca0dbc26b03c6a1818026f9a69cd226ec934e7c64094d0ebe843052b648617ffae7aa3a074f8da46d03c46996d8b547d8916576342000bd9711089b3e57d73 SHA512 a3d31f82aadc6be1796f76c03152ff24f37fe42d6ce27fb98e2f55ab102f86502bc37ccd563f6e0eba61aab20d002184c618517b678b3b93cb8f0497cc046ca5 DIST rust-argon2-0.8.3.crate 28313 BLAKE2B 2d3468c7b5dc027fbbf6ceb264d77f4ae9b03526e0634c645ffd32a4c87532f5a84c224c6c39a15c9e267d268b187ec65210a2edf7df8294913e4958fbc83352 SHA512 f336dd3f90e1a49be107b641f9e9d513b6f8098dbdd1ab8aa2bd1fae329ce6840ad11a902b599922bef45d96ffb556d52b57d61218271bdccb7c85f9fe1da033 -DIST rustc_version-0.2.3.crate 10210 BLAKE2B 1f707d1c66d907c9b1d2ef6d0bc6bc9c89990a7b922a6dfc2041865940ff3854c4d0e1daf558279fd5871af5818d4000457a32c949104f46538312fbf730443b SHA512 01fa7a758dcaa4f15c18628a0d5ee5adde5ade96a8b7dde0908e39e27b290d1e9adb20d44e2adcd379341d2d4a0c34a80dc12553a3bb4efa4758988f28989779 DIST rustyline-4.1.0.crate 61825 BLAKE2B 530eb7e525d4c2f45c123a82502462fe26a21281f86ed76fa10e4c3c9ac6b2f2635d2b6123951a3758f80c75bb7e65e3af5840c9e33634da9a13ff52f0574f48 SHA512 ab861faa1fedc10e94d7bc3b0d02fbdfb094c94f89863261473af4bc5e3ce3180d7603f87cd295a4b28c3230c62ac53c0fabaa7464924f4c0ee4180ca3e6ef0f -DIST ryu-1.0.5.crate 49570 BLAKE2B 3bfba4a5f290a429de7ac3b86823b2a973f40eb6f48c15329173d95964d31ada36f2618be4b36774a03f97f2ce61364900c6a3ad5465a294e2df311a1f4104ed SHA512 d1708ffa3112a684edf2956b6730ead040401d38f1457cde074eaaa59c249007dc8b925629e7f6df89f7ea757e9d0826649d685cc8ede0a04d50296048bf476c -DIST scopeguard-1.1.0.crate 11470 BLAKE2B f774eb90b7d3ffb2efba47518e9d1dead4017ab4b38a4bd74914daa84a5af4bf9eb63da0496e3924499d79cd0439c37447aeda4a21226f95645bddcd6becfabe SHA512 368fa5726df8f42b599993681579a9ffd0196480ee3cd0f9f671e8493f3bedd1e1779bdf2beb329e77e0005fa09b816e3385f309490c0f2781568db275d4d17d -DIST semver-0.9.0.crate 17344 BLAKE2B ae782bc78f29e45577de8574ee58959c70b54bb0b6f45a5a7b09cc4d358d9a0a80bbefc6e0f2a330e2b55adfbbe5c1f64f4ec9bb94c4adf7bb3e4fc9c142db6c SHA512 03a2ea563456f812c301721c3572370fe4934a22db60079da0dd6ffa33fa789e5e2436ef09e62fc35e0b742b06fabc290992c74eed80419a353c9de9449928dc -DIST semver-parser-0.7.0.crate 10268 BLAKE2B e46b7cf9d292f8fc54561fca4df8534dc96f6be920a5c869c405ddb31b9d1a18eab0799207113cf4910a52cc0df5017ab1bc1883a7c3787ebf2d60f09ac0ab4f SHA512 17320468ec6b9862d595f358d70c09ac6e09db7885fe0ead7a1e596f79350a6306e8bfde5bbd6512008a7c5454da1c7ae55fe1e3bc1c1ff02ac9df54c0a6121f DIST serde-1.0.125.crate 75144 BLAKE2B 0823f4cec3704ce5232c266fcb69323dbcd93d2d15712abcc8cc61a2d123d662ae8153a32b3723324ea55a40f2b9101ed654cced45c500fcf399b9d7ccc113b8 SHA512 ed2819d678e7405e2d8a0cc1b43540abf2ad8871eeda4985af5e37016a42b938d7429c4e865cec2ae5364cc7fbe1052a5a46ea51b42c3ed5b9c7c1acb596ac3b DIST serde_derive-1.0.125.crate 54155 BLAKE2B c99e9e806831dccb3ccca20675e11f603a7348c433a641a46cf9a448a7a8b7ee242d0d6110780089b08e88b8f33aef5b75e8b1d25e2e6d242a44e9093b2badfa SHA512 dd4e247c9581b437157f37e355bc3335a3927417920acce72e73d6fe05a80e19fb3160c72abede7842e7d54749c33a94335fe9f3468c2f561267b863df368a6f -DIST serde_json-1.0.64.crate 115138 BLAKE2B c61a404db9800cfb4e2ac29d4e287a7c8f388b62407d5e25e07514e2840fdf9c127476db35cb556b56143755c64c26be1c6b1facc7529067b06946ac8f54a573 SHA512 55a45dd4c60fd93d2d9331f6a8eac39fdfece9ddc1aae45ea27e3dfa81352f08c71bf03906ba99d0feb5df8d847b68547ecaa8eb5a2c76011ebbe8d4cd5bfc2d -DIST sha1-0.6.0.crate 9244 BLAKE2B d992f1803fc17f8f8081ccbafd07ebb9d78056a705444b45dd51b2f57cbdaaf071685b8e6ad9f4fa21e032cc78b4305c8101b079594c7bf6e67894bb798b16b3 SHA512 32081c99a0cd5fd6e651deb711eb4c9a8bc71c12e26b25a72b2dba9a3286502e56b23d068a2899764ce1cc0c615c2c1b22a6c7aae63e07a758745b533e70ff0c DIST shell-words-1.0.0.crate 9798 BLAKE2B b2511d6a956842346f672edc9a3a3554af6d424c3ccad4244c190a7edb5c6d9f18166d91a90ce2c4e86239b858cb04f36f3cb2ac0f1e64926bbc8377f3745d57 SHA512 f1de4606bb249fca7dea437464ef560aa49839382716b9c940738547a5def28337501d9ba77d96a63ecb956d3c49867d6f4742f14946448a2c9d0b1ecea9ebc9 DIST shellexpand-2.1.0.crate 14697 BLAKE2B 257bf22e55a71a3cb11964de7613abdf1928ffa969336584401c2976245d32108c44628a5240a6adf763a33b0fecd10bf4753e7aa62793055e86879570935ba0 SHA512 90d32a5547691c9118a50748feb71bafca44718f0d5ff90cd5d4d9ee893ed4cad2d761a562917f7f26a8ea39154a4aba8dd6351fbf38f8bbf9157aa7c7947413 -DIST shlex-0.1.1.crate 5687 BLAKE2B 8e2942051c783369a8161b667f8f5b73b2081f766db26d685b4d3060f8faeecf78e8763ab927149d4cb08a29af756105f7ec3c3408ad6be2e7618053329fbed2 SHA512 a4d202897861ca7955a3561dc1b0fd0307d77948c9b97aa0f8b9caff2b9721d2836a08760d308675973b0e9c7bae92e4d5fbd2a2497cba9e5aeefbe31075e069 DIST signal-hook-0.3.8.crate 49468 BLAKE2B ca90169e41cbc83378a7a4f665a8fbcb44de79fb254427a610c306ff5f91e42418fd0cd6734b38603f8467b2146317ffeff2671227fa118d023af96ab24dc76b SHA512 b9ec1ada7ccd33cb9afdb39cb320745d7e2472a9c18ff70e54da1e2102e90a00ca5654e9613781dae82be3b1c09c8fc5ea7d5684da54511e361b5d1f0a9e257d DIST signal-hook-registry-1.3.0.crate 17786 BLAKE2B fbd4284bc1020145b92557a99628b985860bd5020cc870ceb6067933c8e58be11d7bdb3c1f715231ca2f0ec2930487ceb88a82d9b9d1c0a31bfcf4a581a002f4 SHA512 2576d474c490deb6cbd759985f55340bb4e4ae0abac3ee02055bc30fa4008fc96ebf4d96f0a85c634b4f04d57b00243625194b333cf330f59fc82286bbeb30a9 DIST siphasher-0.3.5.crate 9455 BLAKE2B 73a09ba949dc4ea670a01e4cfc4f34d8f6ab53facd656beadda396fee087b36afd895e2acba5fecb796fb629b0f56bca84f971970c2f771ed84f74f667f9708d SHA512 4887f7b7b4c0df55c185249a16041052e16ad1f7c80d69ca69dba76af7b25095f2ace3d5b2a33346797f74b63c476a67055929c2856a6b4dff60e8fe2147f8ae -DIST skim-0.9.4.crate 121558 BLAKE2B b41f0f0f22f0bef615ec6b013c2d95149ad4a13fde438b7b25064d706388531d25fafaa8c5b576f7fbb231c2c11007e7e38446033ab23af59ffea82412b50c83 SHA512 05ae2030c7cd28e28111d8998d677eb6d5e6cb1d69cb385e373b477a794a608fef57eace4a60bec0460697fc2ef7a3fc41de86acf55d364434f80e1ea8466403 -DIST standback-0.2.17.crate 29011 BLAKE2B 96081a4036d2e17d96f24be446f5179880f7089cce5dd9acb5140277526bb8395384225055b9f60749e29d48283f2251ad514618f460b44a6850cb75eee9845a SHA512 cd953c942afeacea01b2114eaae2d80e754da7df2f399fcd2cd5c6ff31a15b0644bce4ef1bcc019bbfe60c6521ee15f370b83d77b0a1efc75dcc35a81faea662 -DIST stdweb-0.4.20.crate 194102 BLAKE2B 68a34d4729ded806846a82f0453cd8a82e7a2bf5e7761725af4fdb70be2c9d9c0022c64c5d11a23c8f449d8da7b707e285a8a994b6f027500c4d11da8458d280 SHA512 d6e608e4124e92c94f22172ad1e985dfd9a8a5182f123abf2d837680ad7f791120774f9a483ae5f8d2066fc6e658045c1ad3ee8791a19caf1884970e5882f7ce -DIST stdweb-derive-0.5.3.crate 3894 BLAKE2B 922b52eebb5e21f1f3f58866dee0db28506e37a716f8d58924cba568783098fd236954b52f432434c28f0439e9b6153468c5c3e32f4feb3748a56a49162c9b43 SHA512 d47048f9b1a84d3201ff6189873606df678e22216a7b3e26d23b5708b4115564262aa8ab51151e2ea61b4fdb633ccd5e0af73e62548fb653c30545ea4800834c -DIST stdweb-internal-macros-0.2.9.crate 11828 BLAKE2B 6343aa183e07df93082845b10b564d17af8e65aed6d938054020519a8a96af21838c19a04f6f20d0c1e7ad511d9798f85ab780ffb4dadd049a7bfa19583aa7a3 SHA512 05aee9e19565abd18f781cd6b7e60a5d7fa576ed37724265eb4808b37d9241d89d0eca1aadeed7f3be5237859cd3d905b8e3ce5001a3f1d68ff002bedb7513ea -DIST stdweb-internal-runtime-0.1.5.crate 5445 BLAKE2B 6684fb69a8add47cdfebf7d85c784b3a8f9431ee43d8033d67781dee1eaa6cac71a5330c5eb1a12f5f3d73b863caec31d33985ad8a93d32088c506f70839970d SHA512 9a73f8007d6fa52031ac19f3a2adbe49c0690cec856c484cd81d534ad5b7e4002af0e6615cc9bc8d6753d0d3c1cd5a009ea3ca3750ab518b7aedfbe39b3ae11b DIST strsim-0.8.0.crate 9309 BLAKE2B 40a8be506c43ee1ffe006ddc7dee98c3d418bdd205d57b78f5d1e4c9312feb57e1eaf952e02d92d4e0932db240c6fba45beb06ea8c4fc6de1cf1faa8b6a3a939 SHA512 1d55a8d946cd55f5f37d06aea536549ded95739fa58c0f2da285a0041154c181f663682bdcac643aa198b3e762d694a04f058db985c62ebe22b5c16327ba6d34 -DIST strsim-0.9.3.crate 10266 BLAKE2B d850a2d5199cdc2deae94c02a1934933e22b943750871c624256f3722e78878cf15750abdef6cb27a5acbbe95ed0acfc33f960305d08f942f2a4b066e93e2684 SHA512 8d7468be0f19819a454720d2fc9a139cb9afde9984f73d334b9b77085b58008d6d8ed0786f88ef91b4967c503fa1fac0ddf2fdba01391629f7bcf1ef2fe36b51 DIST structopt-0.3.21.crate 50761 BLAKE2B e48bbec27a34ef80f28e21d42b5acc8b2cf012e1944a6b7f6395f4bd420281e18767dacabed0ca37d94ad26e73ed201c9df06d5cd781a4c107b5741eb0880e53 SHA512 df8592f10456a5b1a7bc7b290357c069ce4eba14d2558ecd6face231e49c748a8892c31ffad000b426e8180d3e4dd607329db91f4b5617e971b2edda5bab42f1 DIST structopt-derive-0.4.14.crate 20116 BLAKE2B cfeb48f5e4906ca24b61afc085a5dc41edc6f69c6060a1cd7e01b844b076928111e4be2f24b3cb28e7704c09bdbbb3c3a1b2f9012ae9e23cc5f795af91fb1245 SHA512 bc20dd9d10c6dc1f5975b074a63eb84b49385ad272b62d8526962e88b28cada3998c3944dedaf8560d6577871747b875cd399dfe06851472c0a1c81fced429a0 DIST syn-1.0.72.crate 232500 BLAKE2B 8f71f7fb66426f78eec3439688b0468fbef582c8ca912781f19607acd9e8371f2230b305a96f613c16f7299e66fdb2395dc037e1093d3897864bd2bf50ab3d7e SHA512 f01e2ef74fc3f84a753c1c379c24e3c63f3c575d72ab865f8e7d51f4dee4293ac8197b4e123ebaa942e9199bf0a0d8194e57a5aa6314bee6951d3d458dfc3da9 -DIST term-0.6.1.crate 37578 BLAKE2B 6ff130b12efadff7ece7858935f3fc9481da87ce0954c49cdcf7f4210a572274048292372aee7ef58efe6c00fa38242c2abd29bbd4563d00a55fb9337e038ed3 SHA512 5e684eedfe522da12914d579fddf1b04720086325ab18498e56b0cc709b0c8a022f887731a2bba9d0ddf200c756d12948835bccdff5bfb2b19af7d071051eacd -DIST termcolor-1.1.2.crate 17287 BLAKE2B 5ff748064c9fb6663befce2fd299edf6a6deb06ea72d21a62d6e77642934cca0933e10340fa84f636631cc08c76ba83ef2284b2212759129d54248e5fccb4c49 SHA512 f37b034345382cd621b1344a3fb301ca3d4d9db8b5858ac1ea82372c983229fce3c0ea8213d6b7e91291b6034affe11e2c3e593dbd95256294ce5c584b33e14c DIST termion-1.5.6.crate 22677 BLAKE2B b918dc82bfa370bb9662bace34211bc7afa03a042dbd25f4456a7e3859521d4f32ab755780e58070f29eb7903f3b4f8129eb9447cda953b9190f9df3b7eb3aea SHA512 228b6fa7e2f280d6bfc7cef77e7a1d0d8f597178e66af0bde1b1fb6553857b511ba8a6786165815aac6d8a082fd37191f4ea35a47f1e1182f7f2c6086eb34a8c DIST textwrap-0.11.0.crate 17322 BLAKE2B 257428908342774593bbd3528fcdae710712ff54e8a711393a24356d8ba0e16e466a4b20c05f942c48ca76b3b5b5aaa90ec202f782cad892caa8b71ccf124da6 SHA512 f5c0fe4f28ff1a3a0931e8e235b5157a45f67967985bcc752418c5ec3481fca44a8ae4800088889b37e8cd0533f53d3c456d5ffd19b767b3f83a87b49a2e209a -DIST thread_local-1.1.3.crate 13111 BLAKE2B 1ac2d9f6b9d5f685857cec0377f41faa2941614c9a0642b8c8d209590ce72c0dcf16f89b5da58d016b26a41e6103407811658a81217716cde0b0c69bc3939877 SHA512 89fe00c005b2bcbb77f2286475dc04f1400b3cd3bc165162f70c1a91f7fe98132f5d0a65e5f1bb36fd8c33617e6d548f3a68df7a2302ea3a177717c71fc112b6 DIST time-0.1.43.crate 28653 BLAKE2B 95fe69647e8d52784be1fd3457578896aa38279d00f51f1070eadab111d39450583c63854c73d4384f2e4349b0250f1c9bff9901529b776c596846c057c93335 SHA512 c3e0c68cab1ed2f33f41955f83e632c51924e4d3c1d22dd0c4ae98499e03f3cafde8b0c2d9e69b67a78d6e4055e464ee00d1ed6af5eb9fa75052405b43e24a25 -DIST time-0.2.26.crate 65327 BLAKE2B 7d66f2b7fd2041897ac65a703ebe02d0ee32a9ae423b42523f4d0b202d1e12dc77e1d7a5c22680fd9d190ae8319105e7aa360b2d1672478d58ced85773fb3085 SHA512 4e3a1d7c48882ae861294fdaad9192b584ff7fa2f11946bb287104ced8d8c7e4b9c8103244b8e87349f13cf971ce83f3c99cb0344c2c7c5e573dc040962c5602 -DIST time-macros-0.1.1.crate 5447 BLAKE2B 4b9dbc879711804f4af172e46e10421d35177242a10c6dcc32bbfe9cad7ed865c7c3d18cd9b8ffee79bc47f0ce5622bc9609ba511d7750a358b6e5cab8426934 SHA512 c6792be54dab0847d621684b4afe2e9803f2004bc3d4f01d84802af7f557799cf4d2b5ff6fe58e0b4018d92ab3868feb9b5df5691b2c8ee188e6e7b39deb8c8c -DIST time-macros-impl-0.1.1.crate 10384 BLAKE2B eb19fd944b379dce462e2b9f8fc5cc974765792d8c2f89082d9894e50e6556f54c2203a2a08adf0eda827cfef911ac177a15f0ce012c51b53543dd7f7d677394 SHA512 c153f9e9f2acd6a9e7190a899bed3050b922eea0cdc8d0fa7ea4c67e03856189bddc745150b3e3c19320ae79e8923f9201aec8923e977c6e407833d08e1a1990 -DIST timer-0.2.0.crate 12190 BLAKE2B 51a84f110fa814a9d844bbc7b81cb68f931e85a1a73f437874b0915458b539b27e90fc6872594f882d2f3d88117f605982c21129dfd2ada105ce207504758b8f SHA512 631997776e6b3d7e7abb4d42b7a4cbb12c3ac4337a11ed2cd83d783ee732b56ef27fc0bdf4156dca331494029b8c207d3c8df6936278b6eacd23348c44a4d757 DIST toml-0.5.8.crate 54219 BLAKE2B b4f9f563e5ba4574d4f2dcbe244378a2e1e984bd9fbbbfa5a06bdd5f8b8d677394f0db9cb8696f6936c80a52caa86b1b3ebaf3885c53855af23f03d318785f19 SHA512 26b7901ee4b7cbb4cf8ea57d365a99ed05e0a76e73452e47d4bcb3b4eeb7bbd393c13eea9ea33dc13622942efcda39acdba9425b74b40c920c9f19673a1f2082 DIST trash-1.3.0.crate 7786 BLAKE2B 095ce34bddc502c109a6cba1489fac4639b86257b5b63d8aedf2fa56bd85f19af76bbdc374b464e8bb39ae2fd4a7c492ae366d5d53f2a47ccd087b45da8faefa SHA512 05408e15a26ff1e28f9957e450ab941e39ee77f2d30d20bb3fbab5345d068ff4f838eeb556590ad728f5ac7927d8a31809028a72946274d52c0ba9c0d486c62c DIST tui-0.15.0.crate 139975 BLAKE2B 889ea1a56c797e862cd2af85dc6d3f85e253b02d40fe5ea29008b2083f63c5d078dc614401d98461d7c9daa3367283c3a91274a023a3f220361ee6cd73b06277 SHA512 2df5234f369d0ebb9724d63399a8c88a26dff878e7b618bd7697cc1e60a61098119c7f8845ed469486156c25998d8211d93fab8d9b5c10292cb637604adfd3b6 -DIST tuikit-0.4.5.crate 45011 BLAKE2B e5ed7beb7bf2a154207468624ed8823625e4737320a2da97d8a76d9ce9550df06ee3db19a98b7b873f84007940410ba2dc2c1e6d52c2356be4d5fb486a43b0da SHA512 889237cf6dc45b8ecdba8948fbf103f7aa0ae72d45472d472512402ba2c9bf357b4bb7bb790dbfb921c85150516f8c7df969d46bc2176e4027c598e99f0073f8 DIST unicode-segmentation-1.7.1.crate 93066 BLAKE2B 80058a79c64972dfff897b08a24e9f18ae0fa312a50f86fc321961eeab83c5546bdbc30534315870d891e648bde1d7d77f459ec9744455bdebb94bf6e326f2ef SHA512 183ca68d456a8d53e6f255129e8fd07b87d8da23b8f18187231d6fa70dac80e4069eb6c501d45155d9f0050b6bd713964e55f0e4b25a40546c4d245a17fc8dc6 DIST unicode-width-0.1.8.crate 16732 BLAKE2B 5aa7b87eef1322e4151a3fcf981ade311b8fa030527d7561815950e58d3f15156163dfe34da6a708c37dccc3f7652bf7fc2cd899fe8bb0118b67c4113ff3a2d2 SHA512 0abba6da6981a2451e01d93bbd47652c46eb6fb07cc0214f33259fb29945bfd5ee2b302e883ddca8f68e921635f222701b7310e7da2a5e225f854980d1e474b0 DIST unicode-xid-0.2.2.crate 14955 BLAKE2B 6c6da49ac08dbd8b3248272224d6bff96b9cd1f36029b1937a58a0b929c3a48326053305ed49e73edd70f572f5abbc4817cedc899c69e3457805ad056669f6af SHA512 92ffd0dd34e3ca235ecf110b38c447d3ec1faa23d76c112457f28d432f92fa6b5f428bc5e1bfd278f361f55426dd96e19ecb0d3eff6cf250892f069c52bd89a8 DIST users-0.11.0.crate 21980 BLAKE2B c106e9ed67b9ad766bb7318506261579768185aea3d956d9e8b2adb52349525fe69703ee3bb2e4fb02aa223bfa6fc92a14d8128412623f70654254f842d7322c SHA512 e28028f895780bd59a11069b81b87470a287a447e42566cfb8de0e2d4ba8c90a3ce92901e253dcd2628383c8ed06c10714bc0181a57bf257f7edb3510936e596 DIST utf8parse-0.1.1.crate 13995 BLAKE2B 6b1de4afdb2837a76637de72f6e6a81e73aa683d8da04ebc94cf7ee3c542845d2244e721840511ee2725320f2f882722e2bea67914435131d7af1ab29291d1eb SHA512 543d4daddce8248b181deb1c3952ca15303d78616480b23af163ca6253a059b5ce9494652839a051c48a47816c3dd719465bbe5bb7930db676a16bcdac47c517 -DIST utf8parse-0.2.0.crate 13392 BLAKE2B 05296f48fe429a871f42e729e3540ec3a974a69892c6bc9da95e23c0aee2163c9b115a9614eb1943363076793e17ac4c89e28066a9816cab30c451524a5832c0 SHA512 1f6a2eca32e42c8e4b53d28c4fea54c426ed66fc01447b3cf8fc0fd75694453eadbe3ba000ac8ee0347d16dbfec47681254117949109081798eab5370886827c DIST vec_map-0.8.2.crate 14466 BLAKE2B 8f109fbff19604b82ea2aa61c952e2ce9b5597ccc8e1ef4e847648e2de08dece8c4debe92889edeccb8d393645fd0b62436b49d236ded7ad181c4a51239a9539 SHA512 4f1ef59bc2c437e79f1f84fe021bce5aa8ccd581f500f3d5776913d5f17d45b03ccee64f5bd03d47656318cfc9344a1f4311079d471fa409a8e4e94c143973f9 DIST version_check-0.9.3.crate 12547 BLAKE2B 85761c300a8d755e0b376191ef0604728ae641261fdb10682a3134a828eadc4a33216426d286bcdbd8d0c5fcfe6ca8ba20ed078c4f53066b959739a0e73daec0 SHA512 4b3b428214a0322af536a18e6f050438398766af6589389f20a804121a6721962ba411e2dcfded60aaa74313128fb0e831bea31378e2695c29b29bdc24d7cbfd DIST void-1.0.2.crate 2356 BLAKE2B 41578fb5507f94e7d135f9595cec107ed00a926f4968df8b59792d1676ba5b6980cd67310f820fc37a9c14ebe43a171833fa8dfc09eac5dd42f2ebe808632a83 SHA512 1cc7d282600dc0164d7e410aa895d5dc99de1174991549c6733c94cc2027026517f66797751d737869eae58c560fa26edbf43f36b3015eb2fd99828fe40e0aa1 -DIST vte-0.9.0.crate 24930 BLAKE2B 91b3c85493037d35563337e43ab64e14503e997b029bd2cc68e56a4e95cd25f1e65b9bbd24cde567e170f5744d55fa965f1b7abba407486cb44f84a21d0bedbf SHA512 ac7c947a01ec404132133740efbaba0bb7fe441fb97373c144dfe4f19a6e5d300657768c2a93fbc7be78247efffcf90257ac2373d5f1a283abd98a968f88b5c7 -DIST vte_generate_state_changes-0.1.1.crate 2422 BLAKE2B 6e8fb4ce0ca0fd6b9a4dcccdfb02445babbc13d47de5fae9bbb81e8c67ada8a40e8dc5e57c120c36876293b111ccc71e1069ea3fdabade6f9ba5ea2d44ff4632 SHA512 ba09352e037cbd279cbf5641c9783a24f76e54f1f09e13f0ab1ca99c9646c1e3c958e8e302d7cc88431073bad2e2d5619410f2f93f96f1db25f0f0ded0236f7e DIST wasi-0.10.2+wasi-snapshot-preview1.crate 27505 BLAKE2B 4eb8644b945633d6e856ad80dd74990be19eb6af99823b147163384f61d471e2d9ec054d78a7064072344be53783e57073e8fffc6d5555c149b4834a9bf31dba SHA512 06977a294d76369a3867c45abdd8a87ea5c84e5a3681075ba0d14af1aee3114ff24495c7e7f7fe1e6e42230e65fba0e062898e69bc89e0209af62c2d14094ec7 DIST wasi-0.9.0+wasi-snapshot-preview1.crate 31521 BLAKE2B 716bdd2ec46d0bc9911c5e5e29fc783840559931b2563d8619675fc11da9527ddbe653a0f1ce0b782ee0c5f7a3131aba2b0867d415f003aa9c2389357569e7dc SHA512 dbe641f796ee3a5daafcaafc911ecc6dff170340f477c2df7a61fb4858a85aefc2637c9e61973ecce66a987aa8e08a736273a4aad3ef47eaf61ed4268dbf9c47 -DIST wasm-bindgen-0.2.74.crate 158439 BLAKE2B 28a0be539d0bdec4e23d4c5a613ec0727c00112d1da1948c050d4ce6f5f42a07fce6d1f2fafa7a66ecee9183fee9a7c23845e12eb50d206f760bfc76dad41491 SHA512 21ac04c54be9f3d3f32edbcffcd24cb9401418e0a398a3f00b6d4a0302bb32b7b044b513163a12952b09b9465b07ec7e4c26a83ad88f8ae39ac5fdc9439a1af5 -DIST wasm-bindgen-backend-0.2.74.crate 25434 BLAKE2B 211365a4407865646376bc40fbfd9865715b137aadc18f267a9d32be8e0e585d05286f8a40cba20060e3591e3a5afa49f678bac6546cde7ef88c2bde36909724 SHA512 df9fdca6c48ecf1926552c4fe06a5936f7ea0523d62e0c62f104ce5eeae7ced1fa33875e2d3ef43d58a6395f77dd37e4882850443eb1d6aa59f0ec0bcf537cfb -DIST wasm-bindgen-macro-0.2.74.crate 11536 BLAKE2B 65cd4b6206cc3f8303f89a76628cf54f7e31b31857eac3cc2c377b4a11f7c32548faf6a87f4a821e4ac6f66ca8d36427f4563eac8cc84e2612d5a9438b8df861 SHA512 34c7f3703ee1ee2060ba6ae638bc69193d32ced9e30c40d75bae1431efdd76b4f3adca8f9a72fb7c75f894de42a478556828e1a3854e436427bbd5dc6dc7b838 -DIST wasm-bindgen-macro-support-0.2.74.crate 17831 BLAKE2B 29f3828f58b0e8eaae04e1d73bbf0b4cea7b75c1a5ae4348938a5f77d9eb1a1ee13dd137f9750f4c8defa6f2f5444d66b6715bc5052c57a603bf3a94cb05a428 SHA512 feab4a3661a879d5fdef852531e3261060db46f1d80106926bc8a8294a19adb104a9cfb59f3fead693abf3707118084a063906248d3f4c566b43e9aa9c2983b4 -DIST wasm-bindgen-shared-0.2.74.crate 7163 BLAKE2B 076464004d12495342a4b24f1dedc629f0ebb49993fce74271a5e59cd39e9a38ceea9a287716c65c2e61744c829388f7cdd7597a541da22b4f794b8bc3d44094 SHA512 4613c677d04abcabe6132f8f2a5a24f622cb1cb0c084f535e2f97584acba7a0faa12fd0636186b58756a7e4a82f364b04ea73330d7841940917f5e3324d0e60a DIST which-4.1.0.crate 7684 BLAKE2B 4d8eb0a263c14b506f446fa808d9326c6e4e781cc2d79a1f6efcf7b9bb9a294d3266a2f3de4526ac0ec08ca65a18622ac064e9ae1e86dd1b325b122f684371f8 SHA512 4fffd3dd4ac73f5c232ee8a53bbc948a7295a2a51ec3f792d5d0aa84ceb6c2322fc11b35d29f5d3181c763b34c434c5ea2807ae6cc3393cd30d68b0fd44c7a22 DIST whoami-0.9.0.crate 19488 BLAKE2B 8be3a62bc0025722c607bca89ba55957de550c8c4e4a7dd938c5543836182dde4c01dcbc50c1e34596e3ffc45a1f4335c60d297f2076177b109ea7c7e0be6199 SHA512 3b02ac85a8e2606bf976b451ef2542940f9808520e3c8e68c9aaba8ae7e1176e0dc53795415a1b40e5eb293b696481af47e48d46587a39a67e9ad0c062939f03 DIST winapi-0.3.9.crate 1200382 BLAKE2B cb5799749ccd935ea2d7068d953cecf19f543d9db7dc16ad4584bb7005373ada34937a3ced7225544d8bc765da599911c7a3190efefb3a25b7c1bb7123b4f673 SHA512 ff8b7b78065f3d8999ec03c725a0460ebc059771bf071c7a3df3f0ecd733edf3b0a2450024d4e24e1aedddaecd9038ce1376c0d8bbf45132068cf45cf4a53a97 DIST winapi-i686-pc-windows-gnu-0.4.0.crate 2918815 BLAKE2B 4d357e4d30f9552972170d65b9a5358b69c46a3e772fe05efc22f3d4ffc1caeeaad7aacdc7abd503a7ad0545f8bd7d22bf351dcb6df76f812fa4d45c34d65df0 SHA512 a672ccefd0730a8166fef1d4e39f9034d9ae426a3f5e28d1f4169fa5c5790767693f281d890e7804773b34acdb0ae1febac33cde8c50c0044a5a6152c7209ec2 -DIST winapi-util-0.1.5.crate 10164 BLAKE2B fc800aceae5249a858c806c3e969ef2545766099872d856ebee51c883d9acf1122278db9607d50ca53eac351502b700fd2463900932d342240f97f683d517963 SHA512 7baeb661f397c4693dfa001fdc774b323c51a7c55caad40f2de5112a1cefd1d6151e3df41fa4ee193460a5905917c83d2b1de5fa10b4bd014ad96690af95c0fd DIST winapi-x86_64-pc-windows-gnu-0.4.0.crate 2947998 BLAKE2B 2ad1ea8b5fa07d544e910ccba043ae925269b76b26c9da356305b34b86741dd8b9aff0b9ffe3d562db4fcd7d7c46a11ce9e3168b782b1d89ae6881742b7ede82 SHA512 4a654af6a5d649dc87e00497245096b35a2894ae66f155cb62389902c3b93ddcc5cf7d0d8b9dd97b291d2d80bc686af2298e80abef6ac69883f4a54e79712513 DIST xdg-2.2.0.crate 13387 BLAKE2B f1a5909b6a4544eaf28d1d051e05a6b9b09043060e14e394410778ed175e9f27246afadf3851dec21020c5e2ca81ef4db44a34e58d9229972b2475ff5f40d6c9 SHA512 16342b8396b4a329801a0ce3b9db82c4c767d09339f895d9f000c64b7160df11019b320cda632f99d8d5b9f65c97894b09091ee4e2ccafac0cd671481fa5c61e -EBUILD joshuto-0.9.0.ebuild 3605 BLAKE2B f9a8d02bfae930eee42a9ab607152ba6c5c298fee8f1963d2a48fcfad66fcfb01b16e7dbd13c69d50bf09d2d9c4c6a9ca436857c19844e4df678c47db4b6c7aa SHA512 211acefe252415392f60cc33bc5f0cd46dd72cbb21802026ee6ac387a511e32826bb63e19e8bd88ed83e7eae1aee3270068ab569a2aa61c2ea342a9516e8d195 +EBUILD joshuto-0.9.0.ebuild 2415 BLAKE2B 1fee02c44239b38ec05f07b771a20aa8778795bafc67f57f9aac8597f84ee5ce7df32f07eef9a1a798ca9f8b8588a652e3f0556975876be03d61ff1f7089911d SHA512 e01b13bd590e1cea4226def7250067014fa86d4f4c50693785b394773e26461afb7c856c14858f8afbd654f9306f40fffd1e99a1099862e227fce5dab6fc38f3 diff --git a/app-misc/joshuto/files/0001-add-additional-configuration-directories.patch b/app-misc/joshuto/files/0001-add-additional-configuration-directories.patch new file mode 100644 index 0000000..38432c2 --- /dev/null +++ b/app-misc/joshuto/files/0001-add-additional-configuration-directories.patch @@ -0,0 +1,75 @@ +From 10f2eed693d6418ec3f477080f06b0d31420f2fd Mon Sep 17 00:00:00 2001 +From: Jeff Zhao +Date: Sun, 30 May 2021 22:57:30 -0400 +Subject: [PATCH] add additional configuration directories +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 8bit + + - in order of precedence: + - $JOSHUTO_CONFIG_DIR + - $XDG_CONFIG_HOME/joshuto + - $HOME/.config/joshuto + +Signed-off-by: Alexander Miroshnichenko +--- + src/main.rs | 33 ++++++++++++++++++++++++--------- + 1 file changed, 24 insertions(+), 9 deletions(-) + +diff --git a/src/main.rs b/src/main.rs +index 1716ece75e07..a3e0f3658683 100644 +--- a/src/main.rs ++++ b/src/main.rs +@@ -34,16 +34,32 @@ const PREVIEW_FILE: &str = "preview.toml"; + lazy_static! { + // dynamically builds the config hierarchy + static ref CONFIG_HIERARCHY: Vec = { +- let mut temp = vec![]; +- match xdg::BaseDirectories::with_prefix(PROGRAM_NAME) { +- Ok(dirs) => temp.push(dirs.get_config_home()), +- Err(e) => eprintln!("{}", e), +- }; ++ let mut config_dirs = vec![]; ++ ++ if let Ok(p) = std::env::var("JOSHUTO_CONFIG_HOME") { ++ let p = PathBuf::from(p); ++ if p.is_dir() { ++ config_dirs.push(p); ++ } ++ } ++ ++ if let Ok(dirs) = xdg::BaseDirectories::with_prefix(PROGRAM_NAME) { ++ config_dirs.push(dirs.get_config_home()); ++ } ++ ++ if let Ok(p) = std::env::var("HOME") { ++ let mut p = PathBuf::from(p); ++ p.push(".config/joshuto"); ++ if p.is_dir() { ++ config_dirs.push(p); ++ } ++ } ++ + // adds the default config files to the config hierarchy if running through cargo + if cfg!(debug_assertions) { +- temp.push(PathBuf::from("./config")); ++ config_dirs.push(PathBuf::from("./config")); + } +- temp ++ config_dirs + }; + static ref THEME_T: AppTheme = AppTheme::get_config(THEME_FILE); + static ref MIMETYPE_T: AppMimetypeRegistry = AppMimetypeRegistry::get_config(MIMETYPE_FILE); +@@ -80,9 +96,8 @@ fn run_joshuto(args: Args) -> Result<(), JoshutoError> { + let config = AppConfig::get_config(CONFIG_FILE); + let keymap = AppKeyMapping::get_config(KEYMAP_FILE); + +- let mut context = AppContext::new(config); +- + { ++ let mut context = AppContext::new(config); + let mut backend: ui::TuiBackend = ui::TuiBackend::new()?; + run(&mut backend, &mut context, keymap)?; + } +-- +2.26.2 + diff --git a/app-misc/joshuto/files/72aaf0c5d10db0004d48e27c58d18d8f2c568f8f.patch b/app-misc/joshuto/files/72aaf0c5d10db0004d48e27c58d18d8f2c568f8f.patch deleted file mode 100644 index 19b7a5a..0000000 --- a/app-misc/joshuto/files/72aaf0c5d10db0004d48e27c58d18d8f2c568f8f.patch +++ /dev/null @@ -1,5082 +0,0 @@ -diff -ur a/Cargo.lock b/Cargo.lock ---- a/Cargo.lock 2021-05-08 03:04:44.000000000 +0300 -+++ b/Cargo.lock 2021-08-07 11:25:14.695474018 +0300 -@@ -54,12 +54,24 @@ - checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - - [[package]] -+name = "base-x" -+version = "0.2.8" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" -+ -+[[package]] - name = "base64" - version = "0.13.0" - source = "registry+https://github.com/rust-lang/crates.io-index" - checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - - [[package]] -+name = "beef" -+version = "0.5.0" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "6736e2428df2ca2848d846c43e88745121a6654696e349ce0054a420815a7409" -+ -+[[package]] - name = "bitflags" - version = "1.2.1" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -86,6 +98,12 @@ - ] - - [[package]] -+name = "bumpalo" -+version = "3.6.1" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" -+ -+[[package]] - name = "cassowary" - version = "0.3.0" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -118,7 +136,7 @@ - "libc", - "num-integer", - "num-traits", -- "time", -+ "time 0.1.43", - "winapi", - ] - -@@ -131,19 +149,110 @@ - "ansi_term", - "atty", - "bitflags", -- "strsim", -+ "strsim 0.8.0", - "textwrap", - "unicode-width", - "vec_map", - ] - - [[package]] -+name = "colors-transform" -+version = "0.2.11" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "9226dbc05df4fb986f48d730b001532580883c4c06c5d1c213f4b34c1c157178" -+ -+[[package]] -+name = "const_fn" -+version = "0.4.8" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "f92cfa0fd5690b3cf8c1ef2cabbd9b7ef22fa53cf5e1f92b05103f6d5d1cf6e7" -+ -+[[package]] - name = "constant_time_eq" - version = "0.1.5" - source = "registry+https://github.com/rust-lang/crates.io-index" - checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - - [[package]] -+name = "crossbeam" -+version = "0.8.0" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "fd01a6eb3daaafa260f6fc94c3a6c36390abc2080e38e3e34ced87393fb77d80" -+dependencies = [ -+ "cfg-if 1.0.0", -+ "crossbeam-channel 0.5.1", -+ "crossbeam-deque", -+ "crossbeam-epoch", -+ "crossbeam-queue", -+ "crossbeam-utils 0.8.4", -+] -+ -+[[package]] -+name = "crossbeam-channel" -+version = "0.4.4" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" -+dependencies = [ -+ "crossbeam-utils 0.7.2", -+ "maybe-uninit", -+] -+ -+[[package]] -+name = "crossbeam-channel" -+version = "0.5.1" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" -+dependencies = [ -+ "cfg-if 1.0.0", -+ "crossbeam-utils 0.8.4", -+] -+ -+[[package]] -+name = "crossbeam-deque" -+version = "0.8.0" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" -+dependencies = [ -+ "cfg-if 1.0.0", -+ "crossbeam-epoch", -+ "crossbeam-utils 0.8.4", -+] -+ -+[[package]] -+name = "crossbeam-epoch" -+version = "0.9.4" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "52fb27eab85b17fbb9f6fd667089e07d6a2eb8743d02639ee7f6a7a7729c9c94" -+dependencies = [ -+ "cfg-if 1.0.0", -+ "crossbeam-utils 0.8.4", -+ "lazy_static", -+ "memoffset", -+ "scopeguard", -+] -+ -+[[package]] -+name = "crossbeam-queue" -+version = "0.3.1" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "0f6cb3c7f5b8e51bc3ebb73a2327ad4abdbd119dc13223f14f961d2f38486756" -+dependencies = [ -+ "cfg-if 1.0.0", -+ "crossbeam-utils 0.8.4", -+] -+ -+[[package]] -+name = "crossbeam-utils" -+version = "0.7.2" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -+dependencies = [ -+ "autocfg", -+ "cfg-if 0.1.10", -+ "lazy_static", -+] -+ -+[[package]] - name = "crossbeam-utils" - version = "0.8.4" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -155,6 +264,76 @@ - ] - - [[package]] -+name = "darling" -+version = "0.10.2" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" -+dependencies = [ -+ "darling_core", -+ "darling_macro", -+] -+ -+[[package]] -+name = "darling_core" -+version = "0.10.2" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" -+dependencies = [ -+ "fnv", -+ "ident_case", -+ "proc-macro2", -+ "quote", -+ "strsim 0.9.3", -+ "syn", -+] -+ -+[[package]] -+name = "darling_macro" -+version = "0.10.2" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" -+dependencies = [ -+ "darling_core", -+ "quote", -+ "syn", -+] -+ -+[[package]] -+name = "defer-drop" -+version = "1.0.1" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "18ae055245e14ed411f56dddf2a78caae87c25d9d6a18fb61f398a596cad77b4" -+dependencies = [ -+ "crossbeam-channel 0.4.4", -+ "once_cell", -+] -+ -+[[package]] -+name = "derive_builder" -+version = "0.9.0" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0" -+dependencies = [ -+ "darling", -+ "derive_builder_core", -+ "proc-macro2", -+ "quote", -+ "syn", -+] -+ -+[[package]] -+name = "derive_builder_core" -+version = "0.9.0" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef" -+dependencies = [ -+ "darling", -+ "proc-macro2", -+ "quote", -+ "syn", -+] -+ -+[[package]] - name = "dirs" - version = "1.0.5" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -166,6 +345,16 @@ - ] - - [[package]] -+name = "dirs" -+version = "2.0.2" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" -+dependencies = [ -+ "cfg-if 0.1.10", -+ "dirs-sys", -+] -+ -+[[package]] - name = "dirs-next" - version = "2.0.0" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -176,6 +365,17 @@ - ] - - [[package]] -+name = "dirs-sys" -+version = "0.3.6" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" -+dependencies = [ -+ "libc", -+ "redox_users 0.4.0", -+ "winapi", -+] -+ -+[[package]] - name = "dirs-sys-next" - version = "0.1.2" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -187,18 +387,58 @@ - ] - - [[package]] -+name = "discard" -+version = "1.0.4" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" -+ -+[[package]] - name = "either" - version = "1.6.1" - source = "registry+https://github.com/rust-lang/crates.io-index" - checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - - [[package]] -+name = "env_logger" -+version = "0.8.3" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f" -+dependencies = [ -+ "atty", -+ "humantime", -+ "log", -+ "regex", -+ "termcolor", -+] -+ -+[[package]] -+name = "filetime" -+version = "0.2.14" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8" -+dependencies = [ -+ "cfg-if 1.0.0", -+ "libc", -+ "redox_syscall 0.2.8", -+ "winapi", -+] -+ -+[[package]] - name = "fnv" - version = "1.0.7" - source = "registry+https://github.com/rust-lang/crates.io-index" - checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - - [[package]] -+name = "fuzzy-matcher" -+version = "0.3.7" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" -+dependencies = [ -+ "thread_local", -+] -+ -+[[package]] - name = "getrandom" - version = "0.1.16" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -252,29 +492,51 @@ - ] - - [[package]] -+name = "humantime" -+version = "2.1.0" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -+ -+[[package]] -+name = "ident_case" -+version = "1.0.1" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -+ -+[[package]] -+name = "itoa" -+version = "0.4.7" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" -+ -+[[package]] - name = "joshuto" --version = "0.8.6" -+version = "0.9.0" - dependencies = [ - "alphanumeric-sort", - "chrono", -+ "colors-transform", - "dirs-next", -+ "filetime", - "globset", - "lazy_static", - "libc", - "open", - "phf", -- "rand 0.8.3", -+ "rand", - "rustyline", - "serde", - "serde_derive", - "shell-words", - "shellexpand", - "signal-hook", -+ "skim", - "structopt", - "termion", - "toml", - "trash", - "tui", -+ "unicode-segmentation", - "unicode-width", - "users", - "whoami", -@@ -303,12 +565,27 @@ - ] - - [[package]] -+name = "maybe-uninit" -+version = "2.0.0" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" -+ -+[[package]] - name = "memchr" - version = "2.4.0" - source = "registry+https://github.com/rust-lang/crates.io-index" - checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" - - [[package]] -+name = "memoffset" -+version = "0.6.3" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d" -+dependencies = [ -+ "autocfg", -+] -+ -+[[package]] - name = "nix" - version = "0.13.1" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -322,6 +599,31 @@ - ] - - [[package]] -+name = "nix" -+version = "0.14.1" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" -+dependencies = [ -+ "bitflags", -+ "cc", -+ "cfg-if 0.1.10", -+ "libc", -+ "void", -+] -+ -+[[package]] -+name = "nix" -+version = "0.19.1" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2" -+dependencies = [ -+ "bitflags", -+ "cc", -+ "cfg-if 1.0.0", -+ "libc", -+] -+ -+[[package]] - name = "num-integer" - version = "0.1.44" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -341,12 +643,28 @@ - ] - - [[package]] -+name = "num_cpus" -+version = "1.13.0" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -+dependencies = [ -+ "hermit-abi", -+ "libc", -+] -+ -+[[package]] - name = "numtoa" - version = "0.1.0" - source = "registry+https://github.com/rust-lang/crates.io-index" - checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" - - [[package]] -+name = "once_cell" -+version = "1.7.2" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" -+ -+[[package]] - name = "open" - version = "1.7.0" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -374,7 +692,7 @@ - checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" - dependencies = [ - "phf_shared", -- "rand 0.7.3", -+ "rand", - ] - - [[package]] -@@ -462,42 +780,20 @@ - dependencies = [ - "getrandom 0.1.16", - "libc", -- "rand_chacha 0.2.2", -- "rand_core 0.5.1", -- "rand_hc 0.2.0", -+ "rand_chacha", -+ "rand_core", -+ "rand_hc", - "rand_pcg", - ] - - [[package]] --name = "rand" --version = "0.8.3" --source = "registry+https://github.com/rust-lang/crates.io-index" --checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" --dependencies = [ -- "libc", -- "rand_chacha 0.3.0", -- "rand_core 0.6.2", -- "rand_hc 0.3.0", --] -- --[[package]] - name = "rand_chacha" - version = "0.2.2" - source = "registry+https://github.com/rust-lang/crates.io-index" - checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" - dependencies = [ - "ppv-lite86", -- "rand_core 0.5.1", --] -- --[[package]] --name = "rand_chacha" --version = "0.3.0" --source = "registry+https://github.com/rust-lang/crates.io-index" --checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" --dependencies = [ -- "ppv-lite86", -- "rand_core 0.6.2", -+ "rand_core", - ] - - [[package]] -@@ -510,39 +806,46 @@ - ] - - [[package]] --name = "rand_core" --version = "0.6.2" -+name = "rand_hc" -+version = "0.2.0" - source = "registry+https://github.com/rust-lang/crates.io-index" --checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" -+checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" - dependencies = [ -- "getrandom 0.2.2", -+ "rand_core", - ] - - [[package]] --name = "rand_hc" --version = "0.2.0" -+name = "rand_pcg" -+version = "0.2.1" - source = "registry+https://github.com/rust-lang/crates.io-index" --checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -+checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" - dependencies = [ -- "rand_core 0.5.1", -+ "rand_core", - ] - - [[package]] --name = "rand_hc" --version = "0.3.0" -+name = "rayon" -+version = "1.5.1" - source = "registry+https://github.com/rust-lang/crates.io-index" --checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" -+checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" - dependencies = [ -- "rand_core 0.6.2", -+ "autocfg", -+ "crossbeam-deque", -+ "either", -+ "rayon-core", - ] - - [[package]] --name = "rand_pcg" --version = "0.2.1" -+name = "rayon-core" -+version = "1.9.1" - source = "registry+https://github.com/rust-lang/crates.io-index" --checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -+checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" - dependencies = [ -- "rand_core 0.5.1", -+ "crossbeam-channel 0.5.1", -+ "crossbeam-deque", -+ "crossbeam-utils 0.8.4", -+ "lazy_static", -+ "num_cpus", - ] - - [[package]] -@@ -616,7 +919,16 @@ - "base64", - "blake2b_simd", - "constant_time_eq", -- "crossbeam-utils", -+ "crossbeam-utils 0.8.4", -+] -+ -+[[package]] -+name = "rustc_version" -+version = "0.2.3" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -+dependencies = [ -+ "semver", - ] - - [[package]] -@@ -625,18 +937,45 @@ - source = "registry+https://github.com/rust-lang/crates.io-index" - checksum = "0f47ea1ceb347d2deae482d655dc8eef4bd82363d3329baffa3818bd76fea48b" - dependencies = [ -- "dirs", -+ "dirs 1.0.5", - "libc", - "log", - "memchr", -- "nix", -+ "nix 0.13.1", - "unicode-segmentation", - "unicode-width", -- "utf8parse", -+ "utf8parse 0.1.1", - "winapi", - ] - - [[package]] -+name = "ryu" -+version = "1.0.5" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" -+ -+[[package]] -+name = "scopeguard" -+version = "1.1.0" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -+ -+[[package]] -+name = "semver" -+version = "0.9.0" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -+dependencies = [ -+ "semver-parser", -+] -+ -+[[package]] -+name = "semver-parser" -+version = "0.7.0" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -+ -+[[package]] - name = "serde" - version = "1.0.125" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -654,6 +993,23 @@ - ] - - [[package]] -+name = "serde_json" -+version = "1.0.64" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" -+dependencies = [ -+ "itoa", -+ "ryu", -+ "serde", -+] -+ -+[[package]] -+name = "sha1" -+version = "0.6.0" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" -+ -+[[package]] - name = "shell-words" - version = "1.0.0" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -669,6 +1025,12 @@ - ] - - [[package]] -+name = "shlex" -+version = "0.1.1" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" -+ -+[[package]] - name = "signal-hook" - version = "0.3.8" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -694,12 +1056,105 @@ - checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27" - - [[package]] -+name = "skim" -+version = "0.9.4" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "4b9d19f904221fab15163486d2ce116cb86e60296470bb4e956d6687f04ebbb4" -+dependencies = [ -+ "atty", -+ "beef", -+ "bitflags", -+ "chrono", -+ "clap", -+ "crossbeam", -+ "defer-drop", -+ "derive_builder", -+ "env_logger", -+ "fuzzy-matcher", -+ "lazy_static", -+ "log", -+ "nix 0.19.1", -+ "rayon", -+ "regex", -+ "shlex", -+ "time 0.2.26", -+ "timer", -+ "tuikit", -+ "unicode-width", -+ "vte", -+] -+ -+[[package]] -+name = "standback" -+version = "0.2.17" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" -+dependencies = [ -+ "version_check", -+] -+ -+[[package]] -+name = "stdweb" -+version = "0.4.20" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" -+dependencies = [ -+ "discard", -+ "rustc_version", -+ "stdweb-derive", -+ "stdweb-internal-macros", -+ "stdweb-internal-runtime", -+ "wasm-bindgen", -+] -+ -+[[package]] -+name = "stdweb-derive" -+version = "0.5.3" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" -+dependencies = [ -+ "proc-macro2", -+ "quote", -+ "serde", -+ "serde_derive", -+ "syn", -+] -+ -+[[package]] -+name = "stdweb-internal-macros" -+version = "0.2.9" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" -+dependencies = [ -+ "base-x", -+ "proc-macro2", -+ "quote", -+ "serde", -+ "serde_derive", -+ "serde_json", -+ "sha1", -+ "syn", -+] -+ -+[[package]] -+name = "stdweb-internal-runtime" -+version = "0.1.5" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" -+ -+[[package]] - name = "strsim" - version = "0.8.0" - source = "registry+https://github.com/rust-lang/crates.io-index" - checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - - [[package]] -+name = "strsim" -+version = "0.9.3" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" -+ -+[[package]] - name = "structopt" - version = "0.3.21" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -735,6 +1190,25 @@ - ] - - [[package]] -+name = "term" -+version = "0.6.1" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5" -+dependencies = [ -+ "dirs 2.0.2", -+ "winapi", -+] -+ -+[[package]] -+name = "termcolor" -+version = "1.1.2" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" -+dependencies = [ -+ "winapi-util", -+] -+ -+[[package]] - name = "termion" - version = "1.5.6" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -756,6 +1230,15 @@ - ] - - [[package]] -+name = "thread_local" -+version = "1.1.3" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" -+dependencies = [ -+ "once_cell", -+] -+ -+[[package]] - name = "time" - version = "0.1.43" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -766,6 +1249,53 @@ - ] - - [[package]] -+name = "time" -+version = "0.2.26" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "08a8cbfbf47955132d0202d1662f49b2423ae35862aee471f3ba4b133358f372" -+dependencies = [ -+ "const_fn", -+ "libc", -+ "standback", -+ "stdweb", -+ "time-macros", -+ "version_check", -+ "winapi", -+] -+ -+[[package]] -+name = "time-macros" -+version = "0.1.1" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" -+dependencies = [ -+ "proc-macro-hack", -+ "time-macros-impl", -+] -+ -+[[package]] -+name = "time-macros-impl" -+version = "0.1.1" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "e5c3be1edfad6027c69f5491cf4cb310d1a71ecd6af742788c6ff8bced86b8fa" -+dependencies = [ -+ "proc-macro-hack", -+ "proc-macro2", -+ "quote", -+ "standback", -+ "syn", -+] -+ -+[[package]] -+name = "timer" -+version = "0.2.0" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "31d42176308937165701f50638db1c31586f183f1aab416268216577aec7306b" -+dependencies = [ -+ "chrono", -+] -+ -+[[package]] - name = "toml" - version = "0.5.8" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -797,6 +1327,20 @@ - ] - - [[package]] -+name = "tuikit" -+version = "0.4.5" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "8c628cfc5752254a33ebccf73eb79ef6508fab77de5d5ef76246b5e45010a51f" -+dependencies = [ -+ "bitflags", -+ "lazy_static", -+ "log", -+ "nix 0.14.1", -+ "term", -+ "unicode-width", -+] -+ -+[[package]] - name = "unicode-segmentation" - version = "1.7.1" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -831,6 +1375,12 @@ - checksum = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d" - - [[package]] -+name = "utf8parse" -+version = "0.2.0" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" -+ -+[[package]] - name = "vec_map" - version = "0.8.2" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -849,6 +1399,27 @@ - checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - - [[package]] -+name = "vte" -+version = "0.9.0" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "6e7745610024d50ab1ebfa41f8f8ee361c567f7ab51032f93cc1cc4cbf0c547a" -+dependencies = [ -+ "arrayvec", -+ "utf8parse 0.2.0", -+ "vte_generate_state_changes", -+] -+ -+[[package]] -+name = "vte_generate_state_changes" -+version = "0.1.1" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" -+dependencies = [ -+ "proc-macro2", -+ "quote", -+] -+ -+[[package]] - name = "wasi" - version = "0.9.0+wasi-snapshot-preview1" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -861,6 +1432,60 @@ - checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - - [[package]] -+name = "wasm-bindgen" -+version = "0.2.74" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd" -+dependencies = [ -+ "cfg-if 1.0.0", -+ "wasm-bindgen-macro", -+] -+ -+[[package]] -+name = "wasm-bindgen-backend" -+version = "0.2.74" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900" -+dependencies = [ -+ "bumpalo", -+ "lazy_static", -+ "log", -+ "proc-macro2", -+ "quote", -+ "syn", -+ "wasm-bindgen-shared", -+] -+ -+[[package]] -+name = "wasm-bindgen-macro" -+version = "0.2.74" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4" -+dependencies = [ -+ "quote", -+ "wasm-bindgen-macro-support", -+] -+ -+[[package]] -+name = "wasm-bindgen-macro-support" -+version = "0.2.74" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97" -+dependencies = [ -+ "proc-macro2", -+ "quote", -+ "syn", -+ "wasm-bindgen-backend", -+ "wasm-bindgen-shared", -+] -+ -+[[package]] -+name = "wasm-bindgen-shared" -+version = "0.2.74" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f" -+ -+[[package]] - name = "which" - version = "4.1.0" - source = "registry+https://github.com/rust-lang/crates.io-index" -@@ -893,6 +1518,15 @@ - checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - - [[package]] -+name = "winapi-util" -+version = "0.1.5" -+source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -+dependencies = [ -+ "winapi", -+] -+ -+[[package]] - name = "winapi-x86_64-pc-windows-gnu" - version = "0.4.0" - source = "registry+https://github.com/rust-lang/crates.io-index" -diff -ur a/Cargo.toml b/Cargo.toml ---- a/Cargo.toml 2021-05-08 03:04:44.000000000 +0300 -+++ b/Cargo.toml 2021-08-07 11:25:14.695474018 +0300 -@@ -10,7 +10,9 @@ - [dependencies] - alphanumeric-sort = "^1" - chrono = "^0" -+colors-transform = "^0" - dirs-next = "^2" -+filetime = "^0" - globset = "^0" - lazy_static = "^1" - libc = "^0" -@@ -22,6 +24,7 @@ - shell-words = "^1" - shellexpand = "^2" - signal-hook = "^0" -+skim = "^0" - structopt = "^0" - termion = "^1" - toml = "^0" -@@ -32,7 +35,7 @@ - xdg = "^2" - phf = { version = "^0", features = ["macros"], optional = true } - trash = { version = "^1", optional = true } -- -+unicode-segmentation = "^1" - [features] - devicons = [ "phf" ] - file_mimetype = [] -diff -ur a/config/joshuto.toml b/config/joshuto.toml ---- a/config/joshuto.toml 2021-05-08 03:04:44.000000000 +0300 -+++ b/config/joshuto.toml 2021-08-07 11:25:14.695474018 +0300 -@@ -4,9 +4,6 @@ - xdg_open = false - use_trash = true - --# currently does not work --max_preview_size = 2097152 # 2MB -- - [display] - # ratios for parent view, current view and preview - collapse_preview = true -@@ -23,3 +20,12 @@ - case_sensitive = false - directories_first = true - reverse = false -+ -+[preview] -+max_preview_size = 2097152 # 2MB -+preview_images = false -+preview_script = "~/.config/joshuto/preview.sh" -+ -+[tab] -+# inherit, home, root -+home_page = "home" -diff -ur a/config/keymap.toml b/config/keymap.toml ---- a/config/keymap.toml 2021-05-08 03:04:44.000000000 +0300 -+++ b/config/keymap.toml 2021-08-07 11:25:14.695474018 +0300 -@@ -36,13 +36,13 @@ - - [[mapcommand]] - command = "cursor_move_up" --keys = [ "up" ] -+keys = [ "arrow_up" ] - [[mapcommand]] - command = "cursor_move_up" - keys = [ "k" ] - [[mapcommand]] - command = "cursor_move_down" --keys = [ "down" ] -+keys = [ "arrow_down" ] - [[mapcommand]] - command = "cursor_move_down" - keys = [ "j" ] -@@ -73,16 +73,16 @@ - keys = [ "]" ] - - [[mapcommand]] --command = "open_file" --keys = [ "right" ] -+command = "open" -+keys = [ "arrow_right" ] - [[mapcommand]] --command = "open_file" -+command = "open" - keys = [ "l" ] - [[mapcommand]] --command = "open_file" -+command = "open" - keys = [ "\n" ] - [[mapcommand]] --command = "open_file_with" -+command = "open_with" - keys = [ "r" ] - - [[mapcommand]] -@@ -90,7 +90,7 @@ - keys = [ "c", "d" ] - [[mapcommand]] - command = "cd .." --keys = [ "left" ] -+keys = [ "arrow_left" ] - [[mapcommand]] - command = "cd .." - keys = [ "h" ] -@@ -102,6 +102,15 @@ - command = "copy_files" - keys = [ "y", "y" ] - [[mapcommand]] -+command = "copy_filename" -+keys = [ "y", "n" ] -+[[mapcommand]] -+command = "copy_filepath" -+keys = [ "y", "p" ] -+[[mapcommand]] -+command = "copy_dirname" -+keys = [ "y", "d" ] -+[[mapcommand]] - command = "paste_files" - keys = [ "p", "p" ] - [[mapcommand]] -@@ -152,11 +161,17 @@ - command = ":" - keys = [ ";" ] - [[mapcommand]] -+command = ":" -+keys = [ ":" ] -+[[mapcommand]] - command = ":mkdir " - keys = [ "m", "k" ] - [[mapcommand]] - command = ":rename " - keys = [ "c", "w" ] -+[[mapcommand]] -+command = ":touch" -+keys = [ "f", "t" ] - - [[mapcommand]] - command = "sort lexical" -@@ -168,6 +183,9 @@ - command = "sort natural" - keys = [ "s", "n" ] - [[mapcommand]] -+command = "sort ext" -+keys = [ "s", "e" ] -+[[mapcommand]] - command = "sort reverse" - keys = [ "s", "r" ] - -diff -ur a/config/mimetype.toml b/config/mimetype.toml ---- a/config/mimetype.toml 2021-05-08 03:04:44.000000000 +0300 -+++ b/config/mimetype.toml 2021-08-07 11:25:14.695474018 +0300 -@@ -1,314 +1,156 @@ --[extension] -- --## image formats --bmp = [ -- { command = "qimgv", fork = true, silent = true }, -- { command = "krita", fork = true, silent = true }, -- { command = "mediainfo", confirm_exit = true } ] --gif = [ -- { command = "qimgv", fork = true, silent = true }, -- { command = "krita", fork = true, silent = true }, -- { command = "mediainfo", confirm_exit = true } ] --heic = [ -- { command = "qimgv", fork = true, silent = true }, -- { command = "krita", fork = true, silent = true }, -+[class] -+audio_default = [ -+ { command = "mpv", args = [ "--" ] }, - { command = "mediainfo", confirm_exit = true } ] --jpeg = [ -- { command = "qimgv", fork = true, silent = true }, -- { command = "krita", fork = true, silent = true }, -- { command = "mediainfo", confirm_exit = true }, --jpe = [ -- { command = "qimgv", fork = true, silent = true }, -- { command = "krita", fork = true, silent = true }, -- { command = "mediainfo", confirm_exit = true }, --jpg = [ -- { command = "qimgv", fork = true, silent = true }, -- { command = "krita", fork = true, silent = true }, -- { command = "mediainfo", confirm_exit = true }, --pgm = [ -- { command = "qimgv", fork = true, silent = true }, -- { command = "krita", fork = true, silent = true }, -- { command = "mediainfo", confirm_exit = true }, --png = [ -+ -+image_default = [ - { command = "qimgv", fork = true, silent = true }, - { command = "krita", fork = true, silent = true }, - { command = "mediainfo", confirm_exit = true }, --ppm = [ -- { command = "qimgv", fork = true, silent = true }, -- { command = "krita", fork = true, silent = true }, -+ { command = "swappy", args = [ "-f" ], fork = true } ] -+ -+video_default = [ -+ { command = "mpv", args = [ "--" ] , fork = true, silent = true }, - { command = "mediainfo", confirm_exit = true }, --svg = [ -+ { command = "mpv", args = [ "--mute", "on", "--" ], fork = true, silent = true } ] -+ -+text_default = [ -+ { command = "micro" }, -+ { command = "gedit", fork = true, silent = true }, -+ { command = "bat", confirm_exit = true } ] -+ -+[extension] -+ -+## image formats -+bmp.inherit = "image_default" -+gif.inherit = "image_default" -+heic.inherit = "image_default" -+jpeg.inherit = "image_default" -+jpe.inherit = "image_default" -+jpg.inherit = "image_default" -+pgm.inherit = "image_default" -+png.inherit = "image_default" -+ppm.inherit = "image_default" -+ -+svg.app_list = [ - { command = "inkview", fork = true, silent = true }, - { command = "inkscape", fork = true, silent = true } ] --tiff = [ -+tiff.app_list = [ - { command = "qimgv", fork = true, silent = true }, - { command = "krita", fork = true, silent = true } ] - - ## audio formats --flac = [ -- { command = "mpv", args = [ "--" ] }, -- { command = "mediainfo", confirm_exit = true } ] --m4a = [ -- { command = "mpv", args = [ "--" ] }, -- { command = "mediainfo", confirm_exit = true } ] --mp3 = [ -- { command = "mpv", args = [ "--" ] }, -- { command = "mediainfo", confirm_exit = true } ] --ogg = [ -- { command = "mpv", args = [ "--" ] }, -- { command = "mediainfo", confirm_exit = true } ] --wav = [ -- { command = "mpv", args = [ "--" ] }, -- { command = "mediainfo", confirm_exit = true } ] --ts = [ -- { command = "mpv", args = [ "--" ] , fork = true, silent = true }, -- { command = "mpv" }, -- { command = "mediainfo", confirm_exit = true } ] -+flac.inherit = "audio_default" -+m4a.inherit = "audio_default" -+mp3.inherit = "audio_default" -+ogg.inherit = "audio_default" -+wav.inherit = "audio_default" -+ts.inherit = "audio_default" - - ## video formats --avi = [ -- { command = "mpv", args = [ "--" ] , fork = true, silent = true }, -- { command = "mediainfo", confirm_exit = true }, --av1 = [ -- { command = "mpv", args = [ "--" ] , fork = true, silent = true }, -- { command = "mediainfo", confirm_exit = true }, --flv = [ -- { command = "mpv", args = [ "--" ] , fork = true, silent = true }, -- { command = "mediainfo", confirm_exit = true }, --mkv = [ -- { command = "mpv", args = [ "--" ] , fork = true, silent = true }, -- { command = "mediainfo", confirm_exit = true }, --m4v = [ -- { command = "mpv", args = [ "--" ] , fork = true, silent = true }, -- { command = "mediainfo", confirm_exit = true }, --mov = [ -- { command = "mpv", args = [ "--" ] , fork = true, silent = true }, -- { command = "mediainfo", confirm_exit = true }, --mp4 = [ -- { command = "mpv", args = [ "--" ] , fork = true, silent = true }, -- { command = "mediainfo", confirm_exit = true }, --webm = [ -- { command = "mpv", args = [ "--" ] , fork = true, silent = true }, -- { command = "mediainfo", confirm_exit = true }, --wmv = [ -- { command = "mpv", args = [ "--" ] , fork = true, silent = true }, -- { command = "mediainfo", confirm_exit = true }, -+avi.inherit = "video_default" -+av1.inherit = "video_default" -+flv.inherit = "video_default" -+mkv.inherit = "video_default" -+m4v.inherit = "video_default" -+mov.inherit = "video_default" -+mp4.inherit = "video_default" -+webm.inherit = "video_default" -+webp.inherit = "video_default" -+wmv.inherit = "video_default" - - ## text formats --build = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --c = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --cmake = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --conf = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --cpp = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --css = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --csv = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --cu = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --eex = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --env = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --ex = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --exs = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --go = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --h = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --hpp = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --hs = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --html = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --ini = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --java = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --js = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --json = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --kt = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --lua = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --log = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --md = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --micro = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --ninja = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --py = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --rkt = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --rs = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --scss = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --sh = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --srt = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --svelte = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --toml = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --tsx = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --txt = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --vim = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --xml = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --yaml = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] --yml = [ -- { command = "micro" }, -- { command = "gedit", fork = true, silent = true }, -- { command = "bat", confirm_exit = true } ] -+build.inherit = "text_default" -+c.inherit = "text_default" -+cmake.inherit = "text_default" -+conf.inherit = "text_default" -+cpp.inherit = "text_default" -+css.inherit = "text_default" -+csv.inherit = "text_default" -+cu.inherit = "text_default" -+eex.inherit = "text_default" -+env.inherit = "text_default" -+ex.inherit = "text_default" -+exs.inherit = "text_default" -+go.inherit = "text_default" -+h.inherit = "text_default" -+hpp.inherit = "text_default" -+hs.inherit = "text_default" -+html.inherit = "text_default" -+ini.inherit = "text_default" -+java.inherit = "text_default" -+js.inherit = "text_default" -+json.inherit = "text_default" -+kt.inherit = "text_default" -+lua.inherit = "text_default" -+log.inherit = "text_default" -+md.inherit = "text_default" -+micro.inherit = "text_default" -+ninja.inherit = "text_default" -+py.inherit = "text_default" -+rkt.inherit = "text_default" -+rs.inherit = "text_default" -+scss.inherit = "text_default" -+sh.inherit = "text_default" -+srt.inherit = "text_default" -+svelte.inherit = "text_default" -+toml.inherit = "text_default" -+tsx.inherit = "text_default" -+txt.inherit = "text_default" -+vim.inherit = "text_default" -+xml.inherit = "text_default" -+yaml.inherit = "text_default" -+yml.inherit = "text_default" - - # archive formats --7z = [ -+7z.app_list = [ - { command = "7z", args = [ "x" ], confirm_exit = true }, - { command = "file-roller", fork = true, silent = true } ] --bz2 = [ -+bz2.app_list = [ - { command = "tar", args = [ "-xvjf" ], confirm_exit = true }, - { command = "file-roller", fork = true, silent = true } ] --gz = [ -+gz.app_list = [ - { command = "tar", args = [ "-xvzf" ], confirm_exit = true }, - { command = "file-roller", fork = true, silent = true } ] --tar = [ -+tar.app_list = [ - { command = "tar", args = [ "-xvf" ], confirm_exit = true }, - { command = "file-roller", fork = true, silent = true } ] --tgz = [ -+tgz.app_list = [ - { command = "tar", args = [ "-xvzf" ], confirm_exit = true }, - { command = "file-roller", fork = true, silent = true } ] --rar = [ -+rar.app_list = [ - { command = "unrar", args = [ "e" ], confirm_exit = true }, - { command = "file-roller", fork = true, silent = true } ] --xz = [ -+xz.app_list = [ - { command = "tar", args = [ "-xvJf" ], confirm_exit = true }, - { command = "file-roller", fork = true, silent = true } ] --zip = [ -+zip.app_list = [ - { command = "unzip", confirm_exit = true }, - { command = "file-roller", fork = true, silent = true } ] - - # misc formats --aup = [ -+aup.app_list = [ - { command = "audacity", fork = true, silent = true } ] - --m3u = [ -+m3u.app_list = [ - { command = "micro" }, - { command = "mpv" }, - { command = "gedit", fork = true, silent = true }, - { command = "bat", confirm_exit = true } ] --docx = [ -+docx.app_list = [ - { command = "libreoffice", fork = true, silent = true } ] --odt = [ -+odt.app_list = [ - { command = "libreoffice", fork = true, silent = true } ] --odf = [ -+odf.app_list = [ - { command = "libreoffice", fork = true, silent = true } ] --pdf = [ -+pdf.app_list = [ - { command = "evince", fork = true, silent = true } ] - --tex = [ -+tex.app_list = [ - { command = "micro" }, - { command = "gedit", fork = true, silent = true }, - { command = "bat", confirm_exit = true }, - { command = "pdflatex" } ] - --torrent = [ -+torrent.app_list = [ - { command = "transmission-gtk" } ] -diff -ur a/config/theme.toml b/config/theme.toml ---- a/config/theme.toml 2021-05-08 03:04:44.000000000 +0300 -+++ b/config/theme.toml 2021-08-07 11:25:14.695474018 +0300 -@@ -34,6 +34,8 @@ - fg = "yellow" - [ext.png] - fg = "yellow" -+[ext.webp] -+fg = "yellow" - [ext.ppm] - fg = "yellow" - [ext.svg] -Только в b: .git -Только в b/.github/workflows: rust-linux-dev.yml -Только в b/.github/workflows: rust-linux-main.yml -Только в a/.github/workflows: rust-linux.yml -Только в b/.github/workflows: rust-macos-dev.yml -Только в b/.github/workflows: rust-macos-main.yml -Только в a/.github/workflows: rust-macos.yml -diff -ur a/README.md b/README.md ---- a/README.md 2021-05-08 03:04:44.000000000 +0300 -+++ b/README.md 2021-08-07 11:25:14.695474018 +0300 -@@ -1,6 +1,6 @@ --[![Linux Build](https://github.com/kamiyaa/joshuto/actions/workflows/rust-linux.yml/badge.svg)](https://github.com/kamiyaa/joshuto/actions/workflows/rust-linux.yml) -+[![Linux build](https://github.com/kamiyaa/joshuto/actions/workflows/rust-linux-main.yml/badge.svg)](https://github.com/kamiyaa/joshuto/actions/workflows/rust-linux-main.yml) - --[![MacOS Build](https://github.com/kamiyaa/joshuto/actions/workflows/rust-macos.yml/badge.svg)](https://github.com/kamiyaa/joshuto/actions/workflows/rust-macos.yml) -+[![MacOS build](https://github.com/kamiyaa/joshuto/actions/workflows/rust-macos-main.yml/badge.svg)](https://github.com/kamiyaa/joshuto/actions/workflows/rust-macos-main.yml) - - # joshuto - -@@ -45,6 +45,18 @@ - sudo dnf install joshuto - ``` - -+##### Arch ([AUR](https://aur.archlinux.org)) -+ -+* [release](https://aur.archlinux.org/packages/joshuto) -+``` -+[yay/paru] -S joshuto -+``` -+ -+* [build from source](https://aur.archlinux.org/packages/joshuto-git) -+``` -+[yay/paru] -S joshuto-git -+``` -+ - ## Usage - - ``` -@@ -53,30 +65,24 @@ - - ## Configuration - --Place config files inside `$XDG_CONFIG_HOME/joshuto` (usually `$HOME/.config/joshuto/` for GNU/Linux). -- --Joshuto can currently be configured using the following files: -+Check out [wiki/Configuration](https://github.com/kamiyaa/joshuto/wiki/Configuration) for details -+and [config/](config/) for examples - - #### [joshuto.toml](config/joshuto.toml) -- - - general configurations - - #### [keymap.toml](/config/keymap.toml) -- - - for keybindings, please take a look at [src/util/key_mapping.rs](/src/util/key_mapping.rs#L18) for non-printable keys - - for commands, please take a look at [src/commands/commands.rs](/src/commands/commands.rs#L139) - - #### [mimetype.toml](/config/mimetype.toml) -- - - for opening files with applications - - #### [theme.toml](/config/theme.toml) -- - - color customizations - - ## Contributing -- --Please create a pull request :) -+See [wiki/Contributing](https://github.com/kamiyaa/joshuto/wiki/Contributing) - - ## Features/Bugs - -@@ -87,8 +93,10 @@ - - [x] Migrate to [tui-rs](https://github.com/fdehau/tui-rs) - - [x] Tab support - - [x] Ctrl/Shift/Alt support --- [x] Asynch File IO (cut/copy/paste/delete/rename) (in progress) -+- [x] Asynch File IO (cut/copy/paste) - - [ ] Built-in command line (in progress) -+ - Currently implementation is kind of janky - - [ ] File previews (in progress) -+ - Waiting for tui-rs to support parsing ANSI color codes - - [ ] Tab autocomplete (in progress) - - [x] Bulk rename -diff -ur a/src/commands/bulk_rename.rs b/src/commands/bulk_rename.rs ---- a/src/commands/bulk_rename.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/commands/bulk_rename.rs 2021-08-07 11:25:14.702140722 +0300 -@@ -81,6 +81,9 @@ - )); - } - -+ println!("{}", termion::clear::All); -+ termion::cursor::Goto(0, 0); -+ - for (p, q) in paths.iter().zip(paths_renamed.iter()) { - println!("{:?} -> {:?}", p, q); - } -diff -ur a/src/commands/change_directory.rs b/src/commands/change_directory.rs ---- a/src/commands/change_directory.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/commands/change_directory.rs 2021-08-07 11:25:14.702140722 +0300 -@@ -3,7 +3,6 @@ - use crate::context::AppContext; - use crate::error::JoshutoResult; - use crate::history::DirectoryHistory; --use crate::util::load_child::LoadChild; - - pub fn cd(path: &path::Path, context: &mut AppContext) -> std::io::Result<()> { - std::env::set_current_dir(path)?; -@@ -25,6 +24,5 @@ - - pub fn change_directory(context: &mut AppContext, path: &path::Path) -> JoshutoResult<()> { - _change_directory(path, context)?; -- LoadChild::load_child(context)?; - Ok(()) - } -diff -ur a/src/commands/command_line.rs b/src/commands/command_line.rs ---- a/src/commands/command_line.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/commands/command_line.rs 2021-08-07 11:25:14.702140722 +0300 -@@ -1,3 +1,5 @@ -+use std::str::FromStr; -+ - use crate::commands::KeyCommand; - use crate::context::AppContext; - use crate::error::JoshutoResult; -@@ -21,7 +23,7 @@ - - if let Some(s) = user_input { - let trimmed = s.trim_start(); -- let command = KeyCommand::parse_command(trimmed)?; -+ let command = KeyCommand::from_str(trimmed)?; - command.execute(context, backend) - } else { - Ok(()) -diff -ur a/src/commands/cursor_move.rs b/src/commands/cursor_move.rs ---- a/src/commands/cursor_move.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/commands/cursor_move.rs 2021-08-07 11:25:14.702140722 +0300 -@@ -1,7 +1,7 @@ - use crate::context::AppContext; - use crate::error::JoshutoResult; --use crate::history::DirectoryHistory; - use crate::ui::TuiBackend; -+ - use std::path::PathBuf; - - pub fn cursor_move(new_index: usize, context: &mut AppContext) -> JoshutoResult<()> { -@@ -20,18 +20,6 @@ - path = Some(entry.file_path().to_path_buf()) - } - } -- -- // get preview -- if let Some(path) = path { -- if path.is_dir() { -- let options = context.config_ref().display_options_ref().clone(); -- context -- .tab_context_mut() -- .curr_tab_mut() -- .history_mut() -- .create_or_soft_update(path.as_path(), &options)?; -- } -- } - Ok(()) - } - -@@ -96,18 +84,33 @@ - Ok(()) - } - --pub fn page_up(context: &mut AppContext, backend: &mut TuiBackend) -> JoshutoResult<()> { -- let half_page = { -- match backend.terminal.as_ref().unwrap().size() { -- Ok(rect) => rect.height as usize - 2, -- _ => 10, -+fn get_page_size(context: &AppContext, backend: &TuiBackend) -> Option { -+ let config = context.config_ref(); -+ let rect = backend.terminal.as_ref().map(|t| t.size())?.ok()?; -+ -+ let rect_height = rect.height as usize; -+ if config.display_options_ref().show_borders() { -+ if rect_height >= 4 { -+ Some(rect_height - 4) -+ } else { -+ None -+ } -+ } else { -+ if rect_height >= 2 { -+ Some(rect_height - 2) -+ } else { -+ None - } -- }; -+ } -+} -+ -+pub fn page_up(context: &mut AppContext, backend: &mut TuiBackend) -> JoshutoResult<()> { -+ let page_size = get_page_size(context, backend).unwrap_or(10); - - let movement = match context.tab_context_ref().curr_tab_ref().curr_list_ref() { - Some(curr_list) => curr_list - .index -- .map(|idx| if idx > half_page { idx - half_page } else { 0 }), -+ .map(|idx| if idx > page_size { idx - page_size } else { 0 }), - None => None, - }; - -@@ -118,21 +121,16 @@ - } - - pub fn page_down(context: &mut AppContext, backend: &mut TuiBackend) -> JoshutoResult<()> { -- let half_page = { -- match backend.terminal.as_ref().unwrap().size() { -- Ok(rect) => rect.height as usize - 2, -- _ => 10, -- } -- }; -+ let page_size = get_page_size(context, backend).unwrap_or(10); - - let movement = match context.tab_context_ref().curr_tab_ref().curr_list_ref() { - Some(curr_list) => { - let dir_len = curr_list.len(); - curr_list.index.map(|idx| { -- if idx + half_page > dir_len - 1 { -+ if idx + page_size > dir_len - 1 { - dir_len - 1 - } else { -- idx + half_page -+ idx + page_size - } - }) - } -diff -ur a/src/commands/delete_files.rs b/src/commands/delete_files.rs ---- a/src/commands/delete_files.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/commands/delete_files.rs 2021-08-07 11:25:14.702140722 +0300 -@@ -7,7 +7,6 @@ - use crate::history::DirectoryHistory; - use crate::ui::widgets::TuiPrompt; - use crate::ui::TuiBackend; --use crate::util::load_child::LoadChild; - - use super::reload; - -@@ -116,6 +115,5 @@ - for tab in context.tab_context_mut().iter_mut() { - tab.history_mut().reload(&curr_path, &options)?; - } -- LoadChild::load_child(context)?; - Ok(()) - } -diff -ur a/src/commands/file_ops.rs b/src/commands/file_ops.rs ---- a/src/commands/file_ops.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/commands/file_ops.rs 2021-08-07 11:25:14.702140722 +0300 -@@ -49,45 +49,76 @@ - } - - pub fn copy_filename(context: &mut AppContext) -> JoshutoResult<()> { -- let entry_file_name = match context -+ let entry_file_name = context - .tab_context_ref() - .curr_tab_ref() - .curr_list_ref() - .and_then(|c| c.curr_entry_ref()) -- { -- Some(entry) => Some(entry.file_name().to_string()), -- None => None, -- }; -+ .map(|entry| entry.file_name().to_string()); -+ - if let Some(file_name) = entry_file_name { -- let clipboards = [ -- ( -- "wl-copy", -- format!("printf '%s' {} | {} 2> /dev/null", file_name, "wl-copy"), -- ), -- ( -- "xsel", -- format!("printf '%s' {} | {} -ib 2> /dev/null", file_name, "xsel"), -- ), -- ( -- "xclip", -- format!( -- "printf '%s' {} | {} -selection clipboard 2> /dev/null", -- file_name, "xclip" -- ), -+ copy_string_to_buffer(file_name)?; -+ } -+ Ok(()) -+} -+ -+pub fn copy_filepath(context: &mut AppContext) -> JoshutoResult<()> { -+ let entry_file_path = context -+ .tab_context_ref() -+ .curr_tab_ref() -+ .curr_list_ref() -+ .and_then(|c| c.curr_entry_ref()) -+ .and_then(|entry| entry.file_path().to_str()) -+ .map(|s| s.to_string()); -+ -+ if let Some(file_path) = entry_file_path { -+ copy_string_to_buffer(file_path)?; -+ } -+ Ok(()) -+} -+ -+pub fn copy_dirname(context: &mut AppContext) -> JoshutoResult<()> { -+ let opt_entry = context -+ .tab_context_ref() -+ .curr_tab_ref() -+ .curr_list_ref() -+ .map(|dirlist| dirlist.file_path()); -+ -+ if let Some(pathbuf) = opt_entry { -+ if let Some(dir) = pathbuf.to_str().map(String::from) { -+ copy_string_to_buffer(dir)? -+ } -+ }; -+ Ok(()) -+} -+ -+fn copy_string_to_buffer(string: String) -> JoshutoResult<()> { -+ let clipboards = [ -+ ( -+ "wl-copy", -+ format!("printf '%s' {} | {} 2> /dev/null", string, "wl-copy"), -+ ), -+ ( -+ "xsel", -+ format!("printf '%s' {} | {} -ib 2> /dev/null", string, "xsel"), -+ ), -+ ( -+ "xclip", -+ format!( -+ "printf '%s' {} | {} -selection clipboard 2> /dev/null", -+ string, "xclip" - ), -- ]; -+ ), -+ ]; - -- for (_, command) in clipboards.iter() { -- match Command::new("sh").args(&["-c", command.as_str()]).status() { -- Ok(s) if s.success() => return Ok(()), -- _ => {} -- } -+ for (_, command) in clipboards.iter() { -+ match Command::new("sh").args(&["-c", command.as_str()]).status() { -+ Ok(s) if s.success() => return Ok(()), -+ _ => {} - } -- let err = Err(JoshutoError::new( -- JoshutoErrorKind::ClipboardError, -- "Failed to copy to clipboard".to_string(), -- )); -- return err; - } -- Ok(()) -+ Err(JoshutoError::new( -+ JoshutoErrorKind::ClipboardError, -+ "Failed to copy to clipboard".to_string(), -+ )) - } -diff -ur a/src/commands/key_command.rs b/src/commands/key_command.rs ---- a/src/commands/key_command.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/commands/key_command.rs 2021-08-07 11:25:14.702140722 +0300 -@@ -4,7 +4,6 @@ - use crate::error::{JoshutoError, JoshutoErrorKind, JoshutoResult}; - use crate::io::IoWorkerOptions; - use crate::ui::TuiBackend; --use crate::util::load_child::LoadChild; - use crate::util::select::SelectOption; - use crate::util::sort::SortType; - -@@ -24,6 +23,8 @@ - CopyFiles, - PasteFiles(IoWorkerOptions), - CopyFileName, -+ CopyFilePath, -+ CopyDirName, - - CursorMoveUp(usize), - CursorMoveDown(usize), -@@ -40,7 +41,7 @@ - DeleteFiles, - NewDirectory(path::PathBuf), - OpenFile, -- OpenFileWith, -+ OpenFileWith(Option), - ParentDirectory, - - Quit, -@@ -49,15 +50,17 @@ - RenameFile(path::PathBuf), - RenameFileAppend, - RenameFilePrepend, -+ TouchFile(String), - - SearchGlob(String), - SearchString(String), -+ SearchSkim, - SearchNext, - SearchPrev, - - SelectFiles(String, SelectOption), - SetMode, -- ShellCommand(Vec), -+ SubProcess(Vec, bool), - ShowWorkers, - - ToggleHiddenFiles, -@@ -77,12 +80,14 @@ - Self::ChangeDirectory(_) => "cd", - Self::NewTab => "new_tab", - Self::CloseTab => "close_tab", -- Self::CommandLine(_, _) => "console", -+ Self::CommandLine(_, _) => ":", - - Self::CutFiles => "cut_files", - Self::CopyFiles => "copy_files", - Self::PasteFiles(_) => "paste_files", - Self::CopyFileName => "copy_filename", -+ Self::CopyFilePath => "copy_filepath", -+ Self::CopyDirName => "copy_dirname", - - Self::CursorMoveUp(_) => "cursor_move_up", - Self::CursorMoveDown(_) => "cursor_move_down", -@@ -95,26 +100,29 @@ - Self::ParentCursorMoveDown(_) => "parent_cursor_move_down", - - Self::DeleteFiles => "delete_files", -- Self::NewDirectory(_) => "new_directory", -+ Self::NewDirectory(_) => "mkdir", - Self::OpenFile => "open", -- Self::OpenFileWith => "open_with", -+ Self::OpenFileWith(_) => "open_with", - Self::ParentDirectory => "cd ..", - - Self::Quit => "quit", - Self::ForceQuit => "force_quit", - Self::ReloadDirList => "reload_dirlist", -- Self::RenameFile(_) => "rename_file", -+ Self::RenameFile(_) => "rename", -+ Self::TouchFile(_) => "touch", - Self::RenameFileAppend => "rename_append", - Self::RenameFilePrepend => "rename_prepend", - - Self::SearchString(_) => "search", - Self::SearchGlob(_) => "search_glob", -+ Self::SearchSkim => "search_skim", - Self::SearchNext => "search_next", - Self::SearchPrev => "search_prev", - - Self::SelectFiles(_, _) => "select", - Self::SetMode => "set_mode", -- Self::ShellCommand(_) => "shell", -+ Self::SubProcess(_, false) => "shell", -+ Self::SubProcess(_, true) => "spawn", - Self::ShowWorkers => "show_workers", - - Self::ToggleHiddenFiles => "toggle_hidden", -@@ -125,8 +133,12 @@ - Self::TabSwitch(_) => "tab_switch", - } - } -+} -+ -+impl std::str::FromStr for KeyCommand { -+ type Err = JoshutoError; - -- pub fn parse_command(s: &str) -> JoshutoResult { -+ fn from_str(s: &str) -> Result { - if let Some(stripped) = s.strip_prefix(':') { - return Ok(Self::CommandLine(stripped.to_owned(), "".to_owned())); - } -@@ -155,6 +167,8 @@ - "close_tab" => Ok(Self::CloseTab), - "copy_files" => Ok(Self::CopyFiles), - "copy_filename" => Ok(Self::CopyFileName), -+ "copy_filepath" => Ok(Self::CopyFilePath), -+ "copy_dirname" => Ok(Self::CopyDirName), - "cursor_move_home" => Ok(Self::CursorMoveHome), - "cursor_move_end" => Ok(Self::CursorMoveEnd), - "cursor_move_page_up" => Ok(Self::CursorMovePageUp), -@@ -206,16 +220,24 @@ - if arg.is_empty() { - Err(JoshutoError::new( - JoshutoErrorKind::InvalidParameters, -- format!("{}: missing additional parameter", command), -+ format!("{}: no directory name given", command), - )) - } else { - Ok(Self::NewDirectory(path::PathBuf::from(arg))) - } - } - "new_tab" => Ok(Self::NewTab), -- -- "open_file" => Ok(Self::OpenFile), -- "open_file_with" => Ok(Self::OpenFileWith), -+ "open" => Ok(Self::OpenFile), -+ "open_with" => match arg { -+ "" => Ok(Self::OpenFileWith(None)), -+ arg => match arg.trim().parse::() { -+ Ok(s) => Ok(Self::OpenFileWith(Some(s))), -+ Err(e) => Err(JoshutoError::new( -+ JoshutoErrorKind::ParseError, -+ e.to_string(), -+ )), -+ }, -+ }, - "paste_files" => { - let mut options = IoWorkerOptions::default(); - for arg in arg.split_whitespace() { -@@ -246,6 +268,7 @@ - Ok(Self::RenameFile(path)) - } - }, -+ "touch" => Ok(Self::TouchFile(arg.to_string())), - "rename_append" => Ok(Self::RenameFileAppend), - "rename_prepend" => Ok(Self::RenameFilePrepend), - "search" => match arg { -@@ -262,6 +285,7 @@ - )), - arg => Ok(Self::SearchGlob(arg.to_string())), - }, -+ "search_skim" => Ok(Self::SearchSkim), - "search_next" => Ok(Self::SearchNext), - "search_prev" => Ok(Self::SearchPrev), - "select" => { -@@ -289,11 +313,11 @@ - } - } - "set_mode" => Ok(Self::SetMode), -- "shell" => match shell_words::split(arg) { -- Ok(s) if !s.is_empty() => Ok(Self::ShellCommand(s)), -+ "shell" | "spawn" => match shell_words::split(arg) { -+ Ok(s) if !s.is_empty() => Ok(Self::SubProcess(s, command == "spawn")), - Ok(_) => Err(JoshutoError::new( - JoshutoErrorKind::InvalidParameters, -- format!("sort: args {}", arg), -+ format!("{}: No commands given", command), - )), - Err(e) => Err(JoshutoError::new( - JoshutoErrorKind::InvalidParameters, -@@ -307,7 +331,7 @@ - Some(s) => Ok(Self::Sort(s)), - None => Err(JoshutoError::new( - JoshutoErrorKind::InvalidParameters, -- format!("sort: Unknown option {}", arg), -+ format!("{}: Unknown option '{}'", command, arg), - )), - }, - }, -@@ -321,7 +345,7 @@ - "toggle_hidden" => Ok(Self::ToggleHiddenFiles), - inp => Err(JoshutoError::new( - JoshutoErrorKind::UnrecognizedCommand, -- format!("Unknown command: {}", inp), -+ format!("Unrecognized command '{}'", inp), - )), - } - } -@@ -333,7 +357,6 @@ - Self::BulkRename => bulk_rename::bulk_rename(context, backend), - Self::ChangeDirectory(p) => { - change_directory::change_directory(context, p.as_path())?; -- LoadChild::load_child(context)?; - Ok(()) - } - Self::NewTab => tab_ops::new_tab(context), -@@ -345,6 +368,8 @@ - Self::CopyFiles => file_ops::copy(context), - Self::PasteFiles(options) => file_ops::paste(context, options.clone()), - Self::CopyFileName => file_ops::copy_filename(context), -+ Self::CopyFilePath => file_ops::copy_filepath(context), -+ Self::CopyDirName => file_ops::copy_dirname(context), - - Self::CursorMoveUp(u) => cursor_move::up(context, *u), - Self::CursorMoveDown(u) => cursor_move::down(context, *u), -@@ -362,7 +387,8 @@ - } - Self::NewDirectory(p) => new_directory::new_directory(context, p.as_path()), - Self::OpenFile => open_file::open(context, backend), -- Self::OpenFileWith => open_file::open_with(context, backend), -+ Self::OpenFileWith(None) => open_file::open_with_interactive(context, backend), -+ Self::OpenFileWith(Some(i)) => open_file::open_with_index(context, backend, *i), - Self::ParentDirectory => parent_directory::parent_directory(context), - - Self::Quit => quit::quit(context), -@@ -371,8 +397,10 @@ - Self::RenameFile(p) => rename_file::rename_file(context, p.as_path()), - Self::RenameFileAppend => rename_file::rename_file_append(context, backend), - Self::RenameFilePrepend => rename_file::rename_file_prepend(context, backend), -+ Self::TouchFile(arg) => touch_file::touch_file(context, arg.as_str()), - Self::SearchGlob(pattern) => search_glob::search_glob(context, pattern.as_str()), - Self::SearchString(pattern) => search_string::search_string(context, pattern.as_str()), -+ Self::SearchSkim => search_skim::search_skim(context, backend), - Self::SearchNext => search::search_next(context), - Self::SearchPrev => search::search_prev(context), - -@@ -380,7 +408,9 @@ - selection::select_files(context, pattern.as_str(), &options) - } - Self::SetMode => set_mode::set_mode(context, backend), -- Self::ShellCommand(v) => shell::shell(context, backend, v.as_slice()), -+ Self::SubProcess(v, spawn) => { -+ sub_process::sub_process(context, backend, v.as_slice(), *spawn) -+ } - Self::ShowWorkers => show_workers::show_workers(context, backend), - - Self::ToggleHiddenFiles => show_hidden::toggle_hidden(context), -@@ -415,7 +445,7 @@ - Self::SelectFiles(pattern, options) => { - write!(f, "{} {} {}", self.command(), pattern, options) - } -- Self::ShellCommand(c) => write!(f, "{} {:?}", self.command(), c), -+ Self::SubProcess(c, _) => write!(f, "{} {:?}", self.command(), c), - Self::Sort(t) => write!(f, "{} {}", self.command(), t), - Self::TabSwitch(i) => write!(f, "{} {}", self.command(), i), - _ => write!(f, "{}", self.command()), -diff -ur a/src/commands/mod.rs b/src/commands/mod.rs ---- a/src/commands/mod.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/commands/mod.rs 2021-08-07 11:25:14.702140722 +0300 -@@ -13,14 +13,16 @@ - pub mod rename_file; - pub mod search; - pub mod search_glob; -+pub mod search_skim; - pub mod search_string; - pub mod selection; - pub mod set_mode; --pub mod shell; - pub mod show_hidden; - pub mod show_workers; - pub mod sort; -+pub mod sub_process; - pub mod tab_ops; -+pub mod touch_file; - - pub mod command_keybind; - pub mod key_command; -diff -ur a/src/commands/new_directory.rs b/src/commands/new_directory.rs ---- a/src/commands/new_directory.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/commands/new_directory.rs 2021-08-07 11:25:14.702140722 +0300 -@@ -3,7 +3,6 @@ - use crate::context::AppContext; - use crate::error::JoshutoResult; - use crate::history::DirectoryHistory; --use crate::util::load_child::LoadChild; - - pub fn new_directory(context: &mut AppContext, p: &path::Path) -> JoshutoResult<()> { - std::fs::create_dir_all(p)?; -@@ -12,6 +11,5 @@ - for tab in context.tab_context_mut().iter_mut() { - tab.history_mut().reload(&curr_path, &options)?; - } -- LoadChild::load_child(context)?; - Ok(()) - } -diff -ur a/src/commands/open_file.rs b/src/commands/open_file.rs ---- a/src/commands/open_file.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/commands/open_file.rs 2021-08-07 11:25:14.702140722 +0300 -@@ -6,7 +6,6 @@ - use crate::error::{JoshutoError, JoshutoErrorKind, JoshutoResult}; - use crate::ui::views::TuiTextField; - use crate::ui::TuiBackend; --use crate::util::load_child::LoadChild; - - use super::change_directory; - -@@ -16,7 +15,7 @@ - let mut options: Vec<&AppMimetypeEntry> = Vec::new(); - if let Some(file_ext) = path.extension() { - if let Some(file_ext) = file_ext.to_str() { -- let ext_entries = MIMETYPE_T.get_entries_for_ext(file_ext); -+ let ext_entries = MIMETYPE_T.app_list_for_ext(file_ext); - options.extend(ext_entries); - } - } -@@ -24,6 +23,8 @@ - } - - pub fn open(context: &mut AppContext, backend: &mut TuiBackend) -> JoshutoResult<()> { -+ let config = context.config_ref(); -+ - if let Some(entry) = context - .tab_context_ref() - .curr_tab_ref() -@@ -33,7 +34,6 @@ - if entry.file_path().is_dir() { - let path = entry.file_path().to_path_buf(); - change_directory::cd(path.as_path(), context)?; -- LoadChild::load_child(context)?; - } else { - let paths = context - .tab_context_ref() -@@ -48,6 +48,7 @@ - )); - } - let files: Vec<&std::ffi::OsStr> = paths.iter().filter_map(|e| e.file_name()).collect(); -+ - let options = get_options(paths[0].as_path()); - - if !options.is_empty() { -@@ -59,6 +60,10 @@ - backend.terminal_restore()?; - res?; - } -+ } else if config.xdg_open { -+ backend.terminal_drop(); -+ open::that(paths[0].as_path())?; -+ backend.terminal_restore()?; - } else { - open_with_helper(context, backend, options, files)?; - } -@@ -133,7 +138,10 @@ - } - } - --pub fn open_with(context: &mut AppContext, backend: &mut TuiBackend) -> JoshutoResult<()> { -+pub fn open_with_interactive( -+ context: &mut AppContext, -+ backend: &mut TuiBackend, -+) -> JoshutoResult<()> { - let paths = context - .tab_context_ref() - .curr_tab_ref() -@@ -152,3 +160,43 @@ - open_with_helper(context, backend, options, files)?; - Ok(()) - } -+ -+pub fn open_with_index( -+ context: &mut AppContext, -+ backend: &mut TuiBackend, -+ index: usize, -+) -> JoshutoResult<()> { -+ let paths = context -+ .tab_context_ref() -+ .curr_tab_ref() -+ .curr_list_ref() -+ .map_or(vec![], |s| s.get_selected_paths()); -+ -+ if paths.is_empty() { -+ return Err(JoshutoError::new( -+ JoshutoErrorKind::Io(io::ErrorKind::NotFound), -+ String::from("No files selected"), -+ )); -+ } -+ let files: Vec<&std::ffi::OsStr> = paths.iter().filter_map(|e| e.file_name()).collect(); -+ let options = get_options(paths[0].as_path()); -+ -+ if index >= options.len() { -+ return Err(JoshutoError::new( -+ JoshutoErrorKind::Io(std::io::ErrorKind::InvalidData), -+ "option does not exist".to_string(), -+ )); -+ } -+ -+ let mimetype_entry = &options[index]; -+ if mimetype_entry.get_fork() { -+ mimetype_entry.execute_with(files.as_slice())?; -+ Ok(()) -+ } else { -+ backend.terminal_drop(); -+ let res = mimetype_entry.execute_with(files.as_slice()); -+ backend.terminal_restore()?; -+ res?; -+ Ok(()) -+ } -+} -diff -ur a/src/commands/parent_directory.rs b/src/commands/parent_directory.rs ---- a/src/commands/parent_directory.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/commands/parent_directory.rs 2021-08-07 11:25:14.702140722 +0300 -@@ -1,6 +1,5 @@ - use crate::context::AppContext; - use crate::error::JoshutoResult; --use crate::util::load_child::LoadChild; - - use super::reload; - -@@ -24,6 +23,5 @@ - pub fn parent_directory(context: &mut AppContext) -> JoshutoResult<()> { - parent_directory_helper(context)?; - reload::soft_reload(context.tab_context_ref().index, context)?; -- LoadChild::load_child(context)?; - Ok(()) - } -diff -ur a/src/commands/reload.rs b/src/commands/reload.rs ---- a/src/commands/reload.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/commands/reload.rs 2021-08-07 11:25:14.705474074 +0300 -@@ -1,6 +1,5 @@ - use crate::context::AppContext; - use crate::error::JoshutoResult; --use crate::util::load_child::LoadChild; - - pub fn soft_reload(index: usize, context: &mut AppContext) -> std::io::Result<()> { - let options = context.config_ref().display_options_ref().clone(); -@@ -42,6 +41,5 @@ - - pub fn reload_dirlist(context: &mut AppContext) -> JoshutoResult<()> { - reload(context, context.tab_context_ref().index)?; -- LoadChild::load_child(context)?; - Ok(()) - } -diff -ur a/src/commands/rename_file.rs b/src/commands/rename_file.rs ---- a/src/commands/rename_file.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/commands/rename_file.rs 2021-08-07 11:25:14.705474074 +0300 -@@ -3,7 +3,6 @@ - use crate::context::AppContext; - use crate::error::JoshutoResult; - use crate::ui::TuiBackend; --use crate::util::load_child::LoadChild; - - use super::command_line; - -@@ -31,12 +30,11 @@ - .curr_tab_ref() - .curr_list_ref() - .and_then(|s| s.curr_entry_ref()) -- .and_then(|s| Some(s.file_path().to_path_buf())); -+ .map(|s| s.file_path().to_path_buf()); - - if let Some(path) = path { - _rename_file(context, path.as_path(), dest)?; - } -- LoadChild::load_child(context)?; - Ok(()) - } - -Только в b/src/commands: search_skim.rs -diff -ur a/src/commands/set_mode.rs b/src/commands/set_mode.rs ---- a/src/commands/set_mode.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/commands/set_mode.rs 2021-08-07 11:25:14.705474074 +0300 -@@ -1,3 +1,5 @@ -+use std::fs; -+ - use crate::context::AppContext; - use crate::error::JoshutoResult; - use crate::ui::views::TuiTextField; -@@ -9,6 +11,7 @@ - #[derive(Clone, Debug)] - pub struct SetMode; - -+#[cfg(unix)] - const LIBC_PERMISSION_VALS: [(libc::mode_t, char); 9] = [ - (libc::S_IRUSR, 'r'), - (libc::S_IWUSR, 'w'), -@@ -23,7 +26,7 @@ - - pub fn str_to_mode(s: &str) -> u32 { - let mut mode: u32 = 0; -- for (i, ch) in s.chars().enumerate() { -+ for (i, ch) in s.chars().enumerate().take(LIBC_PERMISSION_VALS.len()) { - if ch == LIBC_PERMISSION_VALS[i].1 { - let val: u32 = LIBC_PERMISSION_VALS[i].0 as u32; - mode |= val; -@@ -33,6 +36,7 @@ - } - - pub fn set_mode(context: &mut AppContext, backend: &mut TuiBackend) -> JoshutoResult<()> { -+ #[cfg(unix)] - use std::os::unix::fs::PermissionsExt; - - const PREFIX: &str = "set_mode "; -@@ -44,9 +48,10 @@ - - let user_input = match entry { - Some(entry) => { -- context.flush_event(); - let mode = entry.metadata.permissions_ref().mode(); - let mode_string = unix::mode_to_string(mode); -+ -+ context.flush_event(); - TuiTextField::default() - .prompt(":") - .prefix(PREFIX) -@@ -58,19 +63,28 @@ - - if let Some(s) = user_input { - if let Some(stripped) = s.strip_prefix(PREFIX) { -- let s = stripped; -- let mode = str_to_mode(s); -- -- let entry = context -- .tab_context_mut() -- .curr_tab_mut() -- .curr_list_mut() -- .and_then(|x| x.curr_entry_mut()) -- .unwrap(); -- -- unix::set_mode(entry.file_path(), mode); -- entry.metadata.permissions_mut().set_mode(mode); -- cursor_move::down(context, 1)?; -+ let mode = str_to_mode(stripped); -+ if let Some(curr_list) = context.tab_context_mut().curr_tab_mut().curr_list_mut() { -+ if curr_list.any_selected() { -+ for entry in curr_list.iter_selected_mut() { -+ let mut permissions = entry.metadata.permissions_ref().clone(); -+ let file_mode = (permissions.mode() >> 12) << 12 | mode; -+ permissions.set_mode(file_mode); -+ -+ fs::set_permissions(entry.file_path(), permissions)?; -+ entry.metadata.permissions_mut().set_mode(file_mode); -+ } -+ } else if let Some(entry) = curr_list.curr_entry_mut() { -+ let mut permissions = entry.metadata.permissions_ref().clone(); -+ let file_mode = (permissions.mode() >> 12) << 12 | mode; -+ permissions.set_mode(file_mode); -+ -+ fs::set_permissions(entry.file_path(), permissions)?; -+ entry.metadata.permissions_mut().set_mode(file_mode); -+ -+ cursor_move::down(context, 1)?; -+ } -+ } - } - } - Ok(()) -Только в a/src/commands: shell.rs -diff -ur a/src/commands/sort.rs b/src/commands/sort.rs ---- a/src/commands/sort.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/commands/sort.rs 2021-08-07 11:25:14.705474074 +0300 -@@ -1,22 +1,19 @@ - use crate::context::AppContext; - use crate::error::JoshutoResult; - use crate::history::DirectoryHistory; -- --use crate::util::load_child::LoadChild; - use crate::util::sort::SortType; - - use super::reload; - - pub fn set_sort(context: &mut AppContext, method: SortType) -> JoshutoResult<()> { -- context.config_mut().sort_options_mut().sort_method = method; -- -+ context -+ .config_mut() -+ .sort_options_mut() -+ .set_sort_method(method); - for tab in context.tab_context_mut().iter_mut() { - tab.history_mut().depreciate_all_entries(); - } -- -- reload::soft_reload(context.tab_context_ref().index, context)?; -- LoadChild::load_child(context)?; -- Ok(()) -+ refresh(context) - } - - pub fn toggle_reverse(context: &mut AppContext) -> JoshutoResult<()> { -@@ -26,7 +23,10 @@ - for tab in context.tab_context_mut().iter_mut() { - tab.history_mut().depreciate_all_entries(); - } -+ refresh(context) -+} -+ -+fn refresh(context: &mut AppContext) -> JoshutoResult<()> { - reload::soft_reload(context.tab_context_ref().index, context)?; -- LoadChild::load_child(context)?; - Ok(()) - } -Только в b/src/commands: sub_process.rs -diff -ur a/src/commands/tab_ops.rs b/src/commands/tab_ops.rs ---- a/src/commands/tab_ops.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/commands/tab_ops.rs 2021-08-07 11:25:14.705474074 +0300 -@@ -3,8 +3,7 @@ - use crate::context::AppContext; - use crate::error::JoshutoResult; - use crate::history::DirectoryHistory; --use crate::tab::JoshutoTab; --use crate::util::load_child::LoadChild; -+use crate::tab::{JoshutoTab, TabHomePage}; - - use crate::HOME_DIR; - -@@ -51,19 +50,25 @@ - _tab_switch(new_index, context) - } - -+pub fn new_tab_home_path(context: &AppContext) -> path::PathBuf { -+ match context.config_ref().tab_options_ref().home_page() { -+ TabHomePage::Home => match HOME_DIR.as_ref() { -+ Some(s) => s.clone(), -+ None => path::PathBuf::from("/"), -+ }, -+ TabHomePage::Inherit => context.tab_context_ref().curr_tab_ref().cwd().to_path_buf(), -+ TabHomePage::Root => path::PathBuf::from("/"), -+ } -+} -+ - pub fn new_tab(context: &mut AppContext) -> JoshutoResult<()> { -- /* start the new tab in $HOME or root */ -- let curr_path = match HOME_DIR.as_ref() { -- Some(s) => s.clone(), -- None => path::PathBuf::from("/"), -- }; -+ let new_tab_path = new_tab_home_path(context); - -- let tab = JoshutoTab::new(curr_path, context.config_ref().display_options_ref())?; -+ let tab = JoshutoTab::new(new_tab_path, context.config_ref().display_options_ref())?; - context.tab_context_mut().push_tab(tab); - let new_index = context.tab_context_ref().len() - 1; - context.tab_context_mut().index = new_index; - _tab_switch(new_index, context)?; -- LoadChild::load_child(context)?; - Ok(()) - } - -Только в b/src/commands: touch_file.rs -diff -ur a/src/config/default/config.rs b/src/config/default/config.rs ---- a/src/config/default/config.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/config/default/config.rs 2021-08-07 11:25:14.705474074 +0300 -@@ -1,6 +1,9 @@ - use serde_derive::Deserialize; - -+use super::preview::{PreviewOption, PreviewRawOption}; -+use super::tab::{TabOption, TabRawOption}; - use super::DisplayRawOption; -+ - use crate::config::{parse_to_config_file, ConfigStructure, Flattenable}; - use crate::util::display::DisplayOption; - use crate::util::sort; -@@ -11,9 +14,6 @@ - const fn default_scroll_offset() -> usize { - 6 - } --const fn default_max_preview_size() -> u64 { -- 2 * 1024 * 1024 // 2 MB --} - - #[derive(Clone, Debug, Deserialize)] - pub struct RawAppConfig { -@@ -23,31 +23,35 @@ - use_trash: bool, - #[serde(default)] - xdg_open: bool, -- #[serde(default = "default_max_preview_size")] -- max_preview_size: u64, - #[serde(default, rename = "display")] - display_options: DisplayRawOption, -+ #[serde(default, rename = "preview")] -+ preview_options: PreviewRawOption, -+ #[serde(default, rename = "tab")] -+ tab_options: TabRawOption, - } - - impl Flattenable for RawAppConfig { - fn flatten(self) -> AppConfig { - AppConfig { -- max_preview_size: self.max_preview_size, - scroll_offset: self.scroll_offset, - use_trash: self.use_trash, - xdg_open: self.xdg_open, - _display_options: self.display_options.flatten(), -+ _preview_options: self.preview_options.flatten(), -+ _tab_options: self.tab_options.flatten(), - } - } - } - - #[derive(Debug, Clone)] - pub struct AppConfig { -- pub max_preview_size: u64, - pub scroll_offset: usize, - pub use_trash: bool, - pub xdg_open: bool, - _display_options: DisplayOption, -+ _preview_options: PreviewOption, -+ _tab_options: TabOption, - } - - impl AppConfig { -@@ -58,12 +62,26 @@ - &mut self._display_options - } - -+ pub fn preview_options_ref(&self) -> &PreviewOption { -+ &self._preview_options -+ } -+ pub fn preview_options_mut(&mut self) -> &mut PreviewOption { -+ &mut self._preview_options -+ } -+ - pub fn sort_options_ref(&self) -> &sort::SortOption { - self.display_options_ref().sort_options_ref() - } - pub fn sort_options_mut(&mut self) -> &mut sort::SortOption { - self.display_options_mut().sort_options_mut() - } -+ -+ pub fn tab_options_ref(&self) -> &TabOption { -+ &self._tab_options -+ } -+ pub fn tab_options_mut(&mut self) -> &mut TabOption { -+ &mut self._tab_options -+ } - } - - impl ConfigStructure for AppConfig { -@@ -75,11 +93,12 @@ - impl std::default::Default for AppConfig { - fn default() -> Self { - Self { -- max_preview_size: default_max_preview_size(), - scroll_offset: default_scroll_offset(), - use_trash: true, - xdg_open: false, - _display_options: DisplayOption::default(), -+ _preview_options: PreviewOption::default(), -+ _tab_options: TabOption::default(), - } - } - } -diff -ur a/src/config/default/mod.rs b/src/config/default/mod.rs ---- a/src/config/default/mod.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/config/default/mod.rs 2021-08-07 11:25:14.705474074 +0300 -@@ -1,7 +1,11 @@ - pub mod config; - pub mod display; -+pub mod preview; - pub mod sort; -+pub mod tab; - - pub use self::config::AppConfig; - pub use self::display::DisplayRawOption; -+pub use self::preview::{PreviewOption, PreviewRawOption}; - pub use self::sort::SortRawOption; -+pub use self::tab::{TabOption, TabRawOption}; -Только в b/src/config/default: preview.rs -diff -ur a/src/config/default/sort.rs b/src/config/default/sort.rs ---- a/src/config/default/sort.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/config/default/sort.rs 2021-08-07 11:25:14.705474074 +0300 -@@ -24,11 +24,15 @@ - Some(s) => sort::SortType::parse(s).unwrap_or(sort::SortType::Natural), - None => sort::SortType::Natural, - }; -+ -+ let mut sort_methods = sort::SortTypes::default(); -+ sort_methods.reorganize(sort_method); -+ - sort::SortOption { - directories_first: self.directories_first, - case_sensitive: self.case_sensitive, - reverse: self.reverse, -- sort_method, -+ sort_methods, - } - } - } -Только в b/src/config/default: tab.rs -diff -ur a/src/config/keymap/keymapping.rs b/src/config/keymap/keymapping.rs ---- a/src/config/keymap/keymapping.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/config/keymap/keymapping.rs 2021-08-07 11:25:14.708807426 +0300 -@@ -1,6 +1,7 @@ - use serde_derive::Deserialize; - - use std::collections::{hash_map::Entry, HashMap}; -+use std::str::FromStr; - - #[cfg(feature = "mouse")] - use termion::event::MouseEvent; -@@ -27,7 +28,7 @@ - fn flatten(self) -> AppKeyMapping { - let mut keymaps = AppKeyMapping::new(); - for m in self.mapcommand { -- match KeyCommand::parse_command(m.command.as_str()) { -+ match KeyCommand::from_str(m.command.as_str()) { - Ok(command) => { - let events: Vec = m - .keys -@@ -167,7 +168,7 @@ - let keys = [Event::Key(Key::BackTab)]; - insert_keycommand(&mut m, cmd, &keys)?; - -- let cmd = KeyCommand::OpenFileWith; -+ let cmd = KeyCommand::OpenFileWith(None); - let keys = [Event::Key(Key::Char('r'))]; - insert_keycommand(&mut m, cmd, &keys)?; - -@@ -223,6 +224,10 @@ - let keys = [Event::Key(Key::Char(';'))]; - insert_keycommand(&mut m, cmd, &keys)?; - -+ let cmd = KeyCommand::CommandLine("".to_string(), "".to_string()); -+ let keys = [Event::Key(Key::Char(':'))]; -+ insert_keycommand(&mut m, cmd, &keys)?; -+ - let cmd = KeyCommand::CommandLine("mkdir ".to_string(), "".to_string()); - let keys = [Event::Key(Key::Char('m')), Event::Key(Key::Char('k'))]; - insert_keycommand(&mut m, cmd, &keys)?; -diff -ur a/src/config/keymap/keyparse.rs b/src/config/keymap/keyparse.rs ---- a/src/config/keymap/keyparse.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/config/keymap/keyparse.rs 2021-08-07 11:25:14.708807426 +0300 -@@ -18,10 +18,10 @@ - let key = match s { - "backspace" => Some(Key::Backspace), - "backtab" => Some(Key::BackTab), -- "left" => Some(Key::Left), -- "right" => Some(Key::Right), -- "up" => Some(Key::Up), -- "down" => Some(Key::Down), -+ "arrow_left" => Some(Key::Left), -+ "arrow_right" => Some(Key::Right), -+ "arrow_up" => Some(Key::Up), -+ "arrow_down" => Some(Key::Down), - "home" => Some(Key::Home), - "end" => Some(Key::End), - "page_up" => Some(Key::PageUp), -diff -ur a/src/config/mimetype/entry.rs b/src/config/mimetype/entry.rs ---- a/src/config/mimetype/entry.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/config/mimetype/entry.rs 2021-08-07 11:25:14.708807426 +0300 -@@ -3,7 +3,32 @@ - use std::io::Read; - use std::process; - --#[derive(Debug, Deserialize)] -+#[derive(Clone, Debug, Deserialize)] -+pub struct AppList { -+ #[serde(default, rename = "inherit")] -+ _inherit: String, -+ #[serde(default, rename = "app_list")] -+ _app_list: Vec, -+} -+ -+impl AppList { -+ pub fn new(_inherit: String, _app_list: Vec) -> Self { -+ Self { -+ _inherit, -+ _app_list, -+ } -+ } -+ -+ pub fn parent(&self) -> &str { -+ self._inherit.as_str() -+ } -+ -+ pub fn app_list(&self) -> &[AppMimetypeEntry] { -+ &self._app_list.as_slice() -+ } -+} -+ -+#[derive(Clone, Debug, Deserialize)] - pub struct AppMimetypeEntry { - #[serde(rename = "command")] - _command: String, -diff -ur a/src/config/mimetype/mod.rs b/src/config/mimetype/mod.rs ---- a/src/config/mimetype/mod.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/config/mimetype/mod.rs 2021-08-07 11:25:14.708807426 +0300 -@@ -1,5 +1,5 @@ - mod entry; - mod registry; - --pub use self::entry::AppMimetypeEntry; -+pub use self::entry::{AppList, AppMimetypeEntry}; - pub use self::registry::AppMimetypeRegistry; -diff -ur a/src/config/mimetype/registry.rs b/src/config/mimetype/registry.rs ---- a/src/config/mimetype/registry.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/config/mimetype/registry.rs 2021-08-07 11:25:14.708807426 +0300 -@@ -1,39 +1,69 @@ - use serde_derive::Deserialize; - use std::collections::HashMap; - --use super::AppMimetypeEntry; --use crate::config::{parse_config_file, ConfigStructure}; -+use super::{AppList, AppMimetypeEntry}; -+use crate::config::{parse_to_config_file, ConfigStructure, Flattenable}; - --pub type MimetypeRegistry = HashMap>; -+pub type MimetypeRegistry = HashMap; - - #[derive(Debug, Deserialize)] -+pub struct RawAppMimetypeRegistry { -+ #[serde(default, rename = "class")] -+ pub _class: HashMap>, -+ #[serde(default, rename = "extension")] -+ pub _extension: MimetypeRegistry, -+} -+ -+impl Flattenable for RawAppMimetypeRegistry { -+ fn flatten(self) -> AppMimetypeRegistry { -+ let mut registry = MimetypeRegistry::new(); -+ -+ for (ext, app_list) in self._extension { -+ let class = app_list.parent(); -+ let mut combined_app_list: Vec = self -+ ._class -+ .get(class) -+ .map(|v| (*v).clone()) -+ .unwrap_or_default(); -+ combined_app_list.extend_from_slice(app_list.app_list()); -+ let combined_app_list = AppList::new(class.to_string(), combined_app_list); -+ registry.insert(ext, combined_app_list); -+ } -+ -+ AppMimetypeRegistry { -+ _extension: registry, -+ } -+ } -+} -+ -+#[derive(Debug)] - pub struct AppMimetypeRegistry { -- #[serde(default, skip)] -- empty_vec: Vec, -- #[serde(default)] -- pub extension: MimetypeRegistry, -+ // pub _class: HashMap>, -+ pub _extension: MimetypeRegistry, - } - -+pub const EMPTY_ARR: [AppMimetypeEntry; 0] = []; -+ - impl AppMimetypeRegistry { -- pub fn get_entries_for_ext(&self, extension: &str) -> &[AppMimetypeEntry] { -- match self.extension.get(extension) { -- Some(s) => s, -- None => &self.empty_vec, -+ pub fn app_list_for_ext(&self, extension: &str) -> &[AppMimetypeEntry] { -+ match self._extension.get(extension) { -+ Some(s) => s.app_list(), -+ None => &EMPTY_ARR, - } - } - } - - impl ConfigStructure for AppMimetypeRegistry { - fn get_config(file_name: &str) -> Self { -- parse_config_file::(file_name).unwrap_or_else(Self::default) -+ parse_to_config_file::(file_name) -+ .unwrap_or_else(Self::default) - } - } - - impl std::default::Default for AppMimetypeRegistry { - fn default() -> Self { - Self { -- empty_vec: Vec::new(), -- extension: MimetypeRegistry::new(), -+ _extension: MimetypeRegistry::new(), - } - } - } -diff -ur a/src/config/mod.rs b/src/config/mod.rs ---- a/src/config/mod.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/config/mod.rs 2021-08-07 11:25:14.708807426 +0300 -@@ -61,26 +61,3 @@ - }; - Some(config.flatten()) - } -- --// parses a config file into its appropriate format --fn parse_config_file(filename: &str) -> Option --where -- T: DeserializeOwned, --{ -- let file_path = search_directories(filename, &CONFIG_HIERARCHY)?; -- let file_contents = match fs::read_to_string(&file_path) { -- Ok(content) => content, -- Err(e) => { -- eprintln!("Error reading {} file: {}", filename, e); -- return None; -- } -- }; -- -- match toml::from_str::(&file_contents) { -- Ok(config) => Some(config), -- Err(e) => { -- eprintln!("Error parsing {} file: {}", filename, e); -- None -- } -- } --} -diff -ur a/src/config/theme/style.rs b/src/config/theme/style.rs ---- a/src/config/theme/style.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/config/theme/style.rs 2021-08-07 11:25:14.708807426 +0300 -@@ -1,9 +1,11 @@ -+use colors_transform::{Color, Rgb}; -+ - use serde_derive::Deserialize; - --use tui::style::{Color, Modifier}; -+use tui::style; - --const fn default_color() -> Color { -- Color::Reset -+const fn default_color() -> style::Color { -+ style::Color::Reset - } - - #[derive(Clone, Debug, Deserialize)] -@@ -25,39 +27,49 @@ - let bg = Self::str_to_color(self.bg.as_str()); - let fg = Self::str_to_color(self.fg.as_str()); - -- let mut modifier = Modifier::empty(); -+ let mut modifier = style::Modifier::empty(); - if self.bold { -- modifier.insert(Modifier::BOLD); -+ modifier.insert(style::Modifier::BOLD); - } - if self.underline { -- modifier.insert(Modifier::UNDERLINED); -+ modifier.insert(style::Modifier::UNDERLINED); - } - if self.invert { -- modifier.insert(Modifier::REVERSED); -+ modifier.insert(style::Modifier::REVERSED); - } - - AppStyle::default().set_fg(fg).set_bg(bg).insert(modifier) - } - -- pub fn str_to_color(s: &str) -> Color { -+ pub fn str_to_color(s: &str) -> style::Color { - match s { -- "black" => Color::Black, -- "red" => Color::Red, -- "blue" => Color::Blue, -- "green" => Color::Green, -- "yellow" => Color::Yellow, -- "magenta" => Color::Magenta, -- "cyan" => Color::Cyan, -- "white" => Color::White, -- "gray" => Color::Gray, -- "dark_gray" => Color::DarkGray, -- "light_red" => Color::LightRed, -- "light_green" => Color::LightGreen, -- "light_yellow" => Color::LightYellow, -- "light_blue" => Color::LightBlue, -- "light_magenta" => Color::LightMagenta, -- "light_cyan" => Color::LightCyan, -- _ => Color::Reset, -+ "black" => style::Color::Black, -+ "red" => style::Color::Red, -+ "green" => style::Color::Green, -+ "yellow" => style::Color::Yellow, -+ "blue" => style::Color::Blue, -+ "magenta" => style::Color::Magenta, -+ "cyan" => style::Color::Cyan, -+ "gray" => style::Color::Gray, -+ "dark_gray" => style::Color::DarkGray, -+ "light_red" => style::Color::LightRed, -+ "light_green" => style::Color::LightGreen, -+ "light_yellow" => style::Color::LightYellow, -+ "light_blue" => style::Color::LightBlue, -+ "light_magenta" => style::Color::LightMagenta, -+ "light_cyan" => style::Color::LightCyan, -+ "white" => style::Color::White, -+ "reset" => style::Color::Reset, -+ s if s.is_empty() => style::Color::Reset, -+ s => match s.parse::() { -+ Ok(rgb) => { -+ let r = rgb.get_red() as u8; -+ let g = rgb.get_green() as u8; -+ let b = rgb.get_blue() as u8; -+ style::Color::Rgb(r, g, b) -+ } -+ Err(_) => style::Color::Reset, -+ }, - } - } - } -@@ -76,22 +88,22 @@ - - #[derive(Clone, Debug)] - pub struct AppStyle { -- pub fg: Color, -- pub bg: Color, -- pub modifier: Modifier, -+ pub fg: style::Color, -+ pub bg: style::Color, -+ pub modifier: style::Modifier, - } - - impl AppStyle { -- pub fn set_bg(mut self, bg: Color) -> Self { -+ pub fn set_bg(mut self, bg: style::Color) -> Self { - self.bg = bg; - self - } -- pub fn set_fg(mut self, fg: Color) -> Self { -+ pub fn set_fg(mut self, fg: style::Color) -> Self { - self.fg = fg; - self - } - -- pub fn insert(mut self, modifier: Modifier) -> Self { -+ pub fn insert(mut self, modifier: style::Modifier) -> Self { - self.modifier.insert(modifier); - self - } -@@ -102,7 +114,7 @@ - Self { - fg: default_color(), - bg: default_color(), -- modifier: Modifier::empty(), -+ modifier: style::Modifier::empty(), - } - } - } -diff -ur a/src/context/app_context.rs b/src/context/app_context.rs ---- a/src/context/app_context.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/context/app_context.rs 2021-08-07 11:25:14.708807426 +0300 -@@ -3,7 +3,7 @@ - - use crate::config; - use crate::context::{LocalStateContext, TabContext, WorkerContext}; --use crate::util::event::{AppEvent, Events}; -+use crate::event::{AppEvent, Events}; - use crate::util::search::SearchPattern; - - pub struct AppContext { -@@ -11,7 +11,7 @@ - // app config - config: config::AppConfig, - // event loop querying -- events: Events, -+ pub events: Events, - // context related to tabs - tab_context: TabContext, - // context related to local file state -diff -ur a/src/context/worker_context.rs b/src/context/worker_context.rs ---- a/src/context/worker_context.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/context/worker_context.rs 2021-08-07 11:25:14.708807426 +0300 -@@ -3,8 +3,8 @@ - use std::sync::mpsc; - use std::thread; - -+use crate::event::AppEvent; - use crate::io::{IoWorkerObserver, IoWorkerProgress, IoWorkerThread}; --use crate::util::event::AppEvent; - - pub struct WorkerContext { - // queue of IO workers -Только в b/src: event.rs -diff -ur a/src/fs/dirlist.rs b/src/fs/dirlist.rs ---- a/src/fs/dirlist.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/fs/dirlist.rs 2021-08-07 11:25:14.712140779 +0300 -@@ -108,13 +108,21 @@ - Ok(()) - } - -- pub fn selected_entries(&self) -> impl Iterator { -+ pub fn any_selected(&self) -> bool { -+ self.contents.iter().any(|e| e.is_selected()) -+ } -+ -+ pub fn iter_selected(&self) -> impl Iterator { - self.contents.iter().filter(|entry| entry.is_selected()) - } - -+ pub fn iter_selected_mut(&mut self) -> impl Iterator { -+ self.contents.iter_mut().filter(|entry| entry.is_selected()) -+ } -+ - pub fn get_selected_paths(&self) -> Vec { - let vec: Vec = self -- .selected_entries() -+ .iter_selected() - .map(|e| e.file_path().to_path_buf()) - .collect(); - if !vec.is_empty() { -@@ -135,6 +143,17 @@ - self.get_curr_mut_(self.index?) - } - -+ /// For a given number of entries, visible in a UI, this method returns the index of the entry -+ /// with which the UI should start to list the entries. -+ /// -+ /// This method assures that the cursor is always in the viewport of the UI. -+ pub fn first_index_for_viewport(&self, viewport_height: usize) -> usize { -+ match self.index { -+ Some(index) => index / viewport_height as usize * viewport_height as usize, -+ None => 0, -+ } -+ } -+ - fn get_curr_mut_(&mut self, index: usize) -> Option<&mut JoshutoDirEntry> { - if index < self.contents.len() { - Some(&mut self.contents[index]) -diff -ur a/src/fs/entry.rs b/src/fs/entry.rs ---- a/src/fs/entry.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/fs/entry.rs 2021-08-07 11:25:14.712140779 +0300 -@@ -18,6 +18,7 @@ - impl JoshutoDirEntry { - pub fn from(direntry: &fs::DirEntry, show_icons: bool) -> std::io::Result { - let path = direntry.path(); -+ - let metadata = JoshutoMetadata::from(&path)?; - let name = direntry - .file_name() -@@ -86,6 +87,14 @@ - pub fn set_selected(&mut self, selected: bool) { - self.selected = selected; - } -+ -+ pub fn get_ext(&self) -> &str { -+ let fname = self.file_name(); -+ match fname.rfind('.') { -+ Some(pos) => &fname[pos..], -+ None => "", -+ } -+ } - } - - impl std::fmt::Display for JoshutoDirEntry { -diff -ur a/src/fs/metadata.rs b/src/fs/metadata.rs ---- a/src/fs/metadata.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/fs/metadata.rs 2021-08-07 11:25:14.712140779 +0300 -@@ -3,16 +3,23 @@ - #[derive(Clone, Debug)] - pub enum FileType { - Directory, -- Symlink(String), - File, - } - - #[derive(Clone, Debug)] -+pub enum LinkType { -+ Normal, -+ Symlink(String), -+} -+ -+#[derive(Clone, Debug)] - pub struct JoshutoMetadata { - _len: u64, -+ _directory_size: Option, - _modified: time::SystemTime, - _permissions: fs::Permissions, - _file_type: FileType, -+ _link_type: LinkType, - #[cfg(unix)] - pub uid: u32, - #[cfg(unix)] -@@ -26,40 +33,46 @@ - #[cfg(unix)] - use std::os::unix::fs::MetadataExt; - -- let metadata = fs::symlink_metadata(path)?; -+ let symlink_metadata = fs::symlink_metadata(path)?; -+ let metadata = fs::metadata(path)?; - - let _len = metadata.len(); - let _modified = metadata.modified()?; - let _permissions = metadata.permissions(); -- let file_type = metadata.file_type(); -- -- let file_type = if file_type.is_dir() { -- FileType::Directory -- } else if file_type.is_symlink() { -- let mut link = "".to_string(); -- -- if let Ok(path) = fs::read_link(path) { -- if let Some(s) = path.to_str() { -- link = s.to_string(); -+ let (_file_type, _directory_size) = if metadata.file_type().is_dir() { -+ let _directory_size = fs::read_dir(path).map(|s| s.count()).ok(); -+ (FileType::Directory, _directory_size) -+ } else { -+ (FileType::File, None) -+ }; -+ let _link_type = match symlink_metadata.file_type().is_symlink() { -+ true => { -+ let mut link = "".to_string(); -+ -+ if let Ok(path) = fs::read_link(path) { -+ if let Some(s) = path.to_str() { -+ link = s.to_string(); -+ } - } -+ LinkType::Symlink(link) - } -- FileType::Symlink(link) -- } else { -- FileType::File -+ false => LinkType::Normal, - }; - - #[cfg(unix)] -- let uid = metadata.uid(); -+ let uid = symlink_metadata.uid(); - #[cfg(unix)] -- let gid = metadata.gid(); -+ let gid = symlink_metadata.gid(); - #[cfg(unix)] -- let mode = metadata.mode(); -+ let mode = symlink_metadata.mode(); - - Ok(Self { - _len, -+ _directory_size, - _modified, - _permissions, -- _file_type: file_type, -+ _file_type, -+ _link_type, - #[cfg(unix)] - uid, - #[cfg(unix)] -@@ -73,6 +86,10 @@ - self._len - } - -+ pub fn directory_size(&self) -> Option { -+ self._directory_size -+ } -+ - pub fn modified(&self) -> time::SystemTime { - self._modified - } -@@ -88,4 +105,8 @@ - pub fn file_type(&self) -> &FileType { - &self._file_type - } -+ -+ pub fn link_type(&self) -> &LinkType { -+ &self._link_type -+ } - } -diff -ur a/src/fs/mod.rs b/src/fs/mod.rs ---- a/src/fs/mod.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/fs/mod.rs 2021-08-07 11:25:14.712140779 +0300 -@@ -4,4 +4,4 @@ - - pub use self::dirlist::JoshutoDirList; - pub use self::entry::JoshutoDirEntry; --pub use self::metadata::{FileType, JoshutoMetadata}; -+pub use self::metadata::{FileType, JoshutoMetadata, LinkType}; -diff -ur a/src/io/io_observer.rs b/src/io/io_observer.rs ---- a/src/io/io_observer.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/io/io_observer.rs 2021-08-07 11:25:14.712140779 +0300 -@@ -34,18 +34,20 @@ - match self.progress.as_ref() { - None => {} - Some(progress) => { -- let size_str = format::file_size_to_string(progress.bytes_processed()); - let op_str = match progress.kind() { - FileOp::Cut => "Moving", - FileOp::Copy => "Copying", - }; -+ let processed_size = format::file_size_to_string(progress.bytes_processed()); -+ let total_size = format::file_size_to_string(progress.total_bytes()); - - let msg = format!( -- "{} ({}/{}) {} completed", -+ "{} ({}/{}) ({}/{}) completed", - op_str, -- progress.completed() + 1, -- progress.len(), -- size_str -+ progress.files_processed() + 1, -+ progress.total_files(), -+ processed_size, -+ total_size, - ); - self.msg = msg; - } -diff -ur a/src/io/io_worker.rs b/src/io/io_worker.rs ---- a/src/io/io_worker.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/io/io_worker.rs 2021-08-07 11:25:14.712140779 +0300 -@@ -12,21 +12,12 @@ - Copy, - } - --#[derive(Clone, Debug)] -+#[derive(Clone, Copy, Debug, Default)] - pub struct IoWorkerOptions { - pub overwrite: bool, - pub skip_exist: bool, - } - --impl std::default::Default for IoWorkerOptions { -- fn default() -> Self { -- Self { -- overwrite: false, -- skip_exist: false, -- } -- } --} -- - impl std::fmt::Display for IoWorkerOptions { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!( -@@ -40,18 +31,26 @@ - #[derive(Clone, Debug)] - pub struct IoWorkerProgress { - _kind: FileOp, -- _completed: usize, -- _len: usize, -+ _files_processed: usize, -+ _total_files: usize, - _bytes_processed: u64, -+ _total_bytes: u64, - } - - impl IoWorkerProgress { -- pub fn new(_kind: FileOp, _completed: usize, _len: usize, _bytes_processed: u64) -> Self { -+ pub fn new( -+ _kind: FileOp, -+ _files_processed: usize, -+ _total_files: usize, -+ _bytes_processed: u64, -+ _total_bytes: u64, -+ ) -> Self { - Self { - _kind, -- _completed, -- _len, -+ _files_processed, -+ _total_files, - _bytes_processed, -+ _total_bytes, - } - } - -@@ -59,16 +58,16 @@ - self._kind - } - -- pub fn completed(&self) -> usize { -- self._completed -+ pub fn files_processed(&self) -> usize { -+ self._files_processed - } - -- pub fn increment_completed(&mut self) { -- self._completed += 1; -+ pub fn set_files_processed(&mut self, files_processed: usize) { -+ self._files_processed = files_processed; - } - -- pub fn len(&self) -> usize { -- self._len -+ pub fn total_files(&self) -> usize { -+ self._total_files - } - - pub fn bytes_processed(&self) -> u64 { -@@ -78,6 +77,10 @@ - pub fn set_bytes_processed(&mut self, _bytes_processed: u64) { - self._bytes_processed = _bytes_processed; - } -+ -+ pub fn total_bytes(&self) -> u64 { -+ self._total_bytes -+ } - } - - #[derive(Debug)] -@@ -107,89 +110,92 @@ - self._kind - } - -- pub fn start(&self, tx: mpsc::Sender) -> std::io::Result { -+ pub fn start(&self, tx: mpsc::Sender) -> io::Result { - match self.kind() { - FileOp::Cut => self.paste_cut(tx), - FileOp::Copy => self.paste_copy(tx), - } - } - -- fn query_number_of_items(&self) -> io::Result { -+ fn query_number_of_items(&self) -> io::Result<(usize, u64)> { -+ let mut total_bytes = 0; -+ let mut total_files = 0; -+ - let mut dirs: VecDeque = VecDeque::new(); - for path in self.paths.iter() { - let metadata = path.symlink_metadata()?; - if metadata.is_dir() { - dirs.push_back(path.clone()); -+ } else { -+ let metadata = path.symlink_metadata()?; -+ total_bytes += metadata.len(); -+ total_files += 1; - } - } - -- let mut total = self.paths.len() - dirs.len(); -- - while let Some(dir) = dirs.pop_front() { - for entry in fs::read_dir(dir)? { - let path = entry?.path(); - if path.is_dir() { - dirs.push_back(path); - } else { -- total += 1; -+ let metadata = path.symlink_metadata()?; -+ total_bytes += metadata.len(); -+ total_files += 1; - } - } - } -- Ok(total) -+ Ok((total_files, total_bytes)) - } - -- fn paste_copy(&self, tx: mpsc::Sender) -> std::io::Result { -- let num_items = self.query_number_of_items()?; -- let mut progress = IoWorkerProgress::new(self.kind(), 0, num_items, 0); -+ fn paste_copy(&self, tx: mpsc::Sender) -> io::Result { -+ let (total_files, total_bytes) = self.query_number_of_items()?; -+ let mut progress = IoWorkerProgress::new(self.kind(), 0, total_files, 0, total_bytes); - for path in self.paths.iter() { - let _ = tx.send(progress.clone()); - recursive_copy( -+ self.options, - path.as_path(), - self.dest.as_path(), - tx.clone(), - &mut progress, - )?; - } -- Ok(IoWorkerProgress::new( -- self.kind(), -- self.paths.len(), -- self.paths.len(), -- progress.bytes_processed(), -- )) -+ Ok(progress) - } - -- fn paste_cut(&self, tx: mpsc::Sender) -> std::io::Result { -- let num_items = self.query_number_of_items()?; -- let mut progress = IoWorkerProgress::new(self.kind(), 0, num_items, 0); -+ fn paste_cut(&self, tx: mpsc::Sender) -> io::Result { -+ let (total_files, total_bytes) = self.query_number_of_items()?; -+ let mut progress = IoWorkerProgress::new(self.kind(), 0, total_files, 0, total_bytes); -+ - for path in self.paths.iter() { - let _ = tx.send(progress.clone()); - recursive_cut( -+ self.options, - path.as_path(), - self.dest.as_path(), - tx.clone(), - &mut progress, - )?; - } -- Ok(IoWorkerProgress::new( -- self.kind(), -- self.paths.len(), -- self.paths.len(), -- progress.bytes_processed(), -- )) -+ Ok(progress) - } - } - - pub fn recursive_copy( -+ options: IoWorkerOptions, - src: &path::Path, - dest: &path::Path, - tx: mpsc::Sender, - progress: &mut IoWorkerProgress, --) -> std::io::Result<()> { -+) -> io::Result<()> { - let mut dest_buf = dest.to_path_buf(); - if let Some(s) = src.file_name() { - dest_buf.push(s); - } -- rename_filename_conflict(&mut dest_buf); -+ if !options.overwrite { -+ rename_filename_conflict(&mut dest_buf); -+ } - let file_type = fs::symlink_metadata(src)?.file_type(); - if file_type.is_dir() { - fs::create_dir(dest_buf.as_path())?; -@@ -197,6 +203,7 @@ - let entry = entry?; - let entry_path = entry.path(); - recursive_copy( -+ options, - entry_path.as_path(), - dest_buf.as_path(), - tx.clone(), -@@ -208,12 +215,12 @@ - } else if file_type.is_file() { - let bytes_processed = progress.bytes_processed() + fs::copy(src, dest_buf)?; - progress.set_bytes_processed(bytes_processed); -- progress.increment_completed(); -+ progress.set_files_processed(progress.files_processed() + 1); - Ok(()) - } else if file_type.is_symlink() { - let link_path = fs::read_link(src)?; - std::os::unix::fs::symlink(link_path, dest_buf)?; -- progress.increment_completed(); -+ progress.set_files_processed(progress.files_processed() + 1); - Ok(()) - } else { - Ok(()) -@@ -221,29 +228,36 @@ - } - - pub fn recursive_cut( -+ options: IoWorkerOptions, - src: &path::Path, - dest: &path::Path, - tx: mpsc::Sender, - progress: &mut IoWorkerProgress, --) -> std::io::Result<()> { -+) -> io::Result<()> { - let mut dest_buf = dest.to_path_buf(); - if let Some(s) = src.file_name() { - dest_buf.push(s); - } -- rename_filename_conflict(&mut dest_buf); -+ if !options.overwrite { -+ rename_filename_conflict(&mut dest_buf); -+ } - let metadata = fs::symlink_metadata(src)?; - let file_type = metadata.file_type(); -- if file_type.is_dir() { -- match fs::rename(src, dest_buf.as_path()) { -- Ok(_) => { -- let processed = progress.bytes_processed() + metadata.len(); -- progress.set_bytes_processed(processed); -- } -- Err(_) => { -+ -+ match fs::rename(src, dest_buf.as_path()) { -+ Ok(_) => { -+ let bytes_processed = progress.bytes_processed() + metadata.len(); -+ progress.set_bytes_processed(bytes_processed); -+ progress.set_files_processed(progress.files_processed() + 1); -+ Ok(()) -+ } -+ Err(e) if e.kind() == io::ErrorKind::Other => { -+ if file_type.is_dir() { - fs::create_dir(dest_buf.as_path())?; - for entry in fs::read_dir(src)? { - let entry_path = entry?.path(); - recursive_cut( -+ options, - entry_path.as_path(), - dest_buf.as_path(), - tx.clone(), -@@ -251,23 +265,21 @@ - )?; - } - fs::remove_dir(src)?; -+ } else if file_type.is_symlink() { -+ let link_path = fs::read_link(src)?; -+ std::os::unix::fs::symlink(link_path, dest_buf)?; -+ fs::remove_file(src)?; -+ let processed = progress.bytes_processed() + metadata.len(); -+ progress.set_bytes_processed(processed); -+ progress.set_files_processed(progress.files_processed() + 1); -+ } else { -+ let processed = progress.bytes_processed() + fs::copy(src, dest_buf.as_path())?; -+ fs::remove_file(src)?; -+ progress.set_bytes_processed(processed); -+ progress.set_files_processed(progress.files_processed() + 1); - } -+ Ok(()) - } -- } else if file_type.is_file() { -- if fs::rename(src, dest_buf.as_path()).is_err() { -- fs::copy(src, dest_buf.as_path())?; -- fs::remove_file(src)?; -- let processed = progress.bytes_processed() + metadata.len(); -- progress.set_bytes_processed(processed); -- } -- progress.increment_completed(); -- } else if file_type.is_symlink() { -- let link_path = fs::read_link(src)?; -- std::os::unix::fs::symlink(link_path, dest_buf)?; -- fs::remove_file(src)?; -- let processed = progress.bytes_processed() + metadata.len(); -- progress.set_bytes_processed(processed); -- progress.increment_completed(); -+ e => e, - } -- Ok(()) - } -diff -ur a/src/main.rs b/src/main.rs ---- a/src/main.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/main.rs 2021-08-07 11:25:14.712140779 +0300 -@@ -2,9 +2,11 @@ - mod config; - mod context; - mod error; -+mod event; - mod fs; - mod history; - mod io; -+mod preview; - mod run; - mod tab; - mod ui; -@@ -34,16 +36,32 @@ - lazy_static! { - // dynamically builds the config hierarchy - static ref CONFIG_HIERARCHY: Vec = { -- let mut temp = vec![]; -- match xdg::BaseDirectories::with_prefix(PROGRAM_NAME) { -- Ok(dirs) => temp.push(dirs.get_config_home()), -- Err(e) => eprintln!("{}", e), -- }; -+ let mut config_dirs = vec![]; -+ -+ if let Ok(p) = std::env::var("JOSHUTO_CONFIG_HOME") { -+ let p = PathBuf::from(p); -+ if p.is_dir() { -+ config_dirs.push(p); -+ } -+ } -+ -+ if let Ok(dirs) = xdg::BaseDirectories::with_prefix(PROGRAM_NAME) { -+ config_dirs.push(dirs.get_config_home()); -+ } -+ -+ if let Ok(p) = std::env::var("HOME") { -+ let mut p = PathBuf::from(p); -+ p.push(".config/joshuto"); -+ if p.is_dir() { -+ config_dirs.push(p); -+ } -+ } -+ - // adds the default config files to the config hierarchy if running through cargo - if cfg!(debug_assertions) { -- temp.push(PathBuf::from("./config")); -+ config_dirs.push(PathBuf::from("./config")); - } -- temp -+ config_dirs - }; - static ref THEME_T: AppTheme = AppTheme::get_config(THEME_FILE); - static ref MIMETYPE_T: AppMimetypeRegistry = AppMimetypeRegistry::get_config(MIMETYPE_FILE); -@@ -71,21 +89,17 @@ - return Ok(()); - } - if let Some(p) = args.path.as_ref() { -- match std::env::set_current_dir(p.as_path()) { -- Ok(_) => {} -- Err(e) => { -- eprintln!("{}", e); -- process::exit(1); -- } -+ if let Err(e) = std::env::set_current_dir(p.as_path()) { -+ eprintln!("{}", e); -+ process::exit(1); - } - } - - let config = AppConfig::get_config(CONFIG_FILE); - let keymap = AppKeyMapping::get_config(KEYMAP_FILE); - -- let mut context = AppContext::new(config); -- - { -+ let mut context = AppContext::new(config); - let mut backend: ui::TuiBackend = ui::TuiBackend::new()?; - run(&mut backend, &mut context, keymap)?; - } -@@ -108,11 +122,8 @@ - fn main() { - let args = Args::from_args(); - -- match run_joshuto(args) { -- Ok(_) => {} -- Err(e) => { -- eprintln!("{}", e.to_string()); -- process::exit(1); -- } -+ if let Err(e) = run_joshuto(args) { -+ eprintln!("{}", e.to_string()); -+ process::exit(1); - } - } -Только в b/src: preview -diff -ur a/src/run.rs b/src/run.rs ---- a/src/run.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/run.rs 2021-08-07 11:25:14.712140779 +0300 -@@ -3,12 +3,12 @@ - use crate::commands::{AppExecute, CommandKeybind, KeyCommand}; - use crate::config::AppKeyMapping; - use crate::context::AppContext; -+use crate::event::AppEvent; -+use crate::preview::preview_default; - use crate::tab::JoshutoTab; - use crate::ui; - use crate::ui::views::{TuiCommandMenu, TuiView}; --use crate::util::event::AppEvent; - use crate::util::input; --use crate::util::load_child::LoadChild; - use crate::util::to_string::ToString; - - pub fn run( -@@ -23,7 +23,7 @@ - context.tab_context_mut().push_tab(tab); - - // trigger a preview of child -- LoadChild::load_child(context)?; -+ preview_default::load_preview(context, backend); - } - - while !context.exit { -@@ -40,6 +40,7 @@ - match event { - AppEvent::Termion(Event::Mouse(event)) => { - input::process_mouse(event, context, backend); -+ preview_default::load_preview(context, backend); - } - AppEvent::Termion(key) => { - if !context.message_queue_ref().is_empty() { -@@ -82,6 +83,7 @@ - }, - } - context.flush_event(); -+ preview_default::load_preview(context, backend); - } - event => input::process_noninteractive(event, context), - } -diff -ur a/src/tab.rs b/src/tab.rs ---- a/src/tab.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/tab.rs 2021-08-07 11:25:14.712140779 +0300 -@@ -4,6 +4,13 @@ - use crate::history::{DirectoryHistory, JoshutoHistory}; - use crate::util::display::DisplayOption; - -+#[derive(Clone, Copy, Debug)] -+pub enum TabHomePage { -+ Inherit, -+ Home, -+ Root, -+} -+ - pub struct JoshutoTab { - history: JoshutoHistory, - _cwd: path::PathBuf, -diff -ur a/src/ui/views/tui_command_menu.rs b/src/ui/views/tui_command_menu.rs ---- a/src/ui/views/tui_command_menu.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/ui/views/tui_command_menu.rs 2021-08-07 11:25:14.712140779 +0300 -@@ -7,10 +7,10 @@ - use crate::commands::{CommandKeybind, KeyCommand}; - use crate::config::AppKeyMapping; - use crate::context::AppContext; -+use crate::event::AppEvent; - use crate::ui::views::TuiView; - use crate::ui::widgets::TuiMenu; - use crate::ui::TuiBackend; --use crate::util::event::AppEvent; - use crate::util::input; - use crate::util::to_string::ToString; - -@@ -36,11 +36,11 @@ - - loop { - let _ = terminal.draw(|frame| { -- let f_size: Rect = frame.size(); -+ let area = frame.size(); - - { - let view = TuiView::new(&context); -- frame.render_widget(view, f_size); -+ frame.render_widget(view, area); - } - - { -@@ -54,21 +54,27 @@ - let display_str: Vec<&str> = display_vec.iter().map(|v| v.as_str()).collect(); - let display_str_len = display_str.len(); - -- let y = if (f_size.height as usize) -+ let y = if (area.height as usize) - < display_str_len + BORDER_HEIGHT + BOTTOM_MARGIN - { - 0 - } else { -- f_size.height -+ area.height - - (BORDER_HEIGHT + BOTTOM_MARGIN) as u16 - - display_str_len as u16 - }; - -+ let menu_height = if display_str_len + BORDER_HEIGHT > area.height as usize { -+ area.height -+ } else { -+ (display_str_len + BORDER_HEIGHT) as u16 -+ }; -+ - let menu_rect = Rect { - x: 0, - y, -- width: f_size.width, -- height: (display_str_len + BORDER_HEIGHT) as u16, -+ width: area.width, -+ height: menu_height, - }; - - frame.render_widget(Clear, menu_rect); -diff -ur a/src/ui/views/tui_folder_view.rs b/src/ui/views/tui_folder_view.rs ---- a/src/ui/views/tui_folder_view.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/ui/views/tui_folder_view.rs 2021-08-07 11:25:14.712140779 +0300 -@@ -1,6 +1,7 @@ - use tui::buffer::Buffer; - use tui::layout::{Constraint, Direction, Layout, Rect}; - use tui::style::{Color, Style}; -+use tui::symbols::line::{HORIZONTAL_DOWN, HORIZONTAL_UP}; - use tui::text::Span; - use tui::widgets::{Block, Borders, Paragraph, Widget, Wrap}; - -@@ -48,6 +49,7 @@ - height: area.height - 2, - ..area - }; -+ - let block = Block::default().borders(Borders::ALL); - let inner = block.inner(area); - block.render(area, buf); -@@ -57,6 +59,25 @@ - .constraints(constraints.as_ref()) - .split(inner); - -+ // Render inner borders properly. -+ { -+ let top = area.top(); -+ let bottom = area.bottom() - 1; -+ let left = layout_rect[1].left() - 1; -+ let right = layout_rect[2].left(); -+ let intersections = Intersections { -+ top, -+ bottom, -+ left, -+ right, -+ }; -+ -+ intersections.render_left(buf); -+ if child_list.as_ref().is_some() { -+ intersections.render_right(buf); -+ } -+ } -+ - let block = Block::default().borders(Borders::RIGHT); - let inner1 = block.inner(layout_rect[0]); - block.render(layout_rect[0], buf); -@@ -160,3 +181,24 @@ - } - } - } -+ -+struct Intersections { -+ top: u16, -+ bottom: u16, -+ left: u16, -+ right: u16, -+} -+ -+impl Intersections { -+ fn render_left(&self, buf: &mut Buffer) { -+ buf.get_mut(self.left, self.top).set_symbol(HORIZONTAL_DOWN); -+ buf.get_mut(self.left, self.bottom) -+ .set_symbol(HORIZONTAL_UP); -+ } -+ fn render_right(&self, buf: &mut Buffer) { -+ buf.get_mut(self.right, self.top) -+ .set_symbol(HORIZONTAL_DOWN); -+ buf.get_mut(self.right, self.bottom) -+ .set_symbol(HORIZONTAL_UP); -+ } -+} -diff -ur a/src/ui/views/tui_textfield.rs b/src/ui/views/tui_textfield.rs ---- a/src/ui/views/tui_textfield.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/ui/views/tui_textfield.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -7,10 +7,10 @@ - use unicode_width::UnicodeWidthStr; - - use crate::context::AppContext; -+use crate::event::AppEvent; - use crate::ui::views::TuiView; - use crate::ui::widgets::{TuiMenu, TuiMultilineText}; - use crate::ui::TuiBackend; --use crate::util::event::AppEvent; - use crate::util::input; - - struct CompletionTracker { -diff -ur a/src/ui/views/tui_worker_view.rs b/src/ui/views/tui_worker_view.rs ---- a/src/ui/views/tui_worker_view.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/ui/views/tui_worker_view.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -3,9 +3,9 @@ - use tui::layout::Rect; - - use crate::context::AppContext; -+use crate::event::AppEvent; - use crate::ui::widgets::{TuiTopBar, TuiWorker}; - use crate::ui::TuiBackend; --use crate::util::event::AppEvent; - use crate::util::input; - - pub struct TuiWorkerView {} -@@ -43,11 +43,8 @@ - if let Ok(event) = context.poll_event() { - match event { - AppEvent::Termion(event) => { -- match event { -- Event::Key(Key::Esc) => { -- break; -- } -- _ => {} -+ if let Event::Key(Key::Esc) = event { -+ break; - } - context.flush_event(); - } -diff -ur a/src/ui/widgets/mod.rs b/src/ui/widgets/mod.rs ---- a/src/ui/widgets/mod.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/ui/widgets/mod.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -9,7 +9,7 @@ - mod tui_worker; - - pub use self::tui_dirlist::TuiDirList; --pub use self::tui_dirlist_detailed::TuiDirListDetailed; -+pub use self::tui_dirlist_detailed::{trim_file_label, TuiDirListDetailed}; - pub use self::tui_footer::TuiFooter; - pub use self::tui_menu::TuiMenu; - pub use self::tui_prompt::TuiPrompt; -diff -ur a/src/ui/widgets/tui_dirlist_detailed.rs b/src/ui/widgets/tui_dirlist_detailed.rs ---- a/src/ui/widgets/tui_dirlist_detailed.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/ui/widgets/tui_dirlist_detailed.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -2,13 +2,14 @@ - use tui::layout::Rect; - use tui::style::{Color, Modifier, Style}; - use tui::widgets::Widget; --use unicode_width::UnicodeWidthStr; - --use crate::fs::{FileType, JoshutoDirEntry, JoshutoDirList}; -+use crate::fs::{FileType, JoshutoDirEntry, JoshutoDirList, LinkType}; - use crate::util::format; -+use crate::util::string::UnicodeTruncate; - use crate::util::style; -+use unicode_width::UnicodeWidthStr; - --const FILE_SIZE_WIDTH: usize = 8; -+const MIN_LEFT_LABEL_WIDTH: i32 = 15; - - const ELLIPSIS: &str = "…"; - -@@ -40,7 +41,7 @@ - }; - - let drawing_width = area.width as usize; -- let skip_dist = curr_index / area.height as usize * area.height as usize; -+ let skip_dist = self.dirlist.first_index_for_viewport(area.height as usize); - - // draw every entry - self.dirlist -@@ -79,77 +80,223 @@ - (x, y): (u16, u16), - drawing_width: usize, - ) { -- let name = entry.label(); -- let name_width = name.width(); -+ let size_string = match entry.metadata.file_type() { -+ FileType::Directory => entry -+ .metadata -+ .directory_size() -+ .map(|n| n.to_string()) -+ .unwrap_or("".to_string()), -+ FileType::File => format::file_size_to_string(entry.metadata.len()), -+ }; -+ let symlink_string = match entry.metadata.link_type() { -+ LinkType::Normal => "", -+ LinkType::Symlink(_) => "-> ", -+ }; -+ let left_label_original = entry.label(); -+ let right_label_original = format!(" {}{} ", symlink_string, size_string); -+ -+ let (left_label, right_label) = factor_labels_for_entry( -+ left_label_original, -+ right_label_original.as_str(), -+ drawing_width, -+ ); -+ -+ let right_width = right_label.width(); -+ buf.set_stringn(x, y, left_label, drawing_width, style); -+ buf.set_stringn( -+ x + drawing_width as u16 - right_width as u16, -+ y, -+ right_label, -+ drawing_width, -+ style, -+ ); -+} - -- match entry.metadata.file_type() { -- FileType::Directory => { -- // print filename -- buf.set_stringn(x, y, name, drawing_width, style); -- if name_width > drawing_width { -- buf.set_string(x + drawing_width as u16 - 1, y, ELLIPSIS, style); -- } -- } -- FileType::Symlink(_) => { -- // print filename -- buf.set_stringn(x, y, name, drawing_width, style); -- buf.set_string(x + drawing_width as u16 - 4, y, "->", style); -- if name_width >= drawing_width - 4 { -- buf.set_string(x + drawing_width as u16 - 1, y, ELLIPSIS, style); -- } -+fn factor_labels_for_entry<'a>( -+ left_label_original: &'a str, -+ right_label_original: &'a str, -+ drawing_width: usize, -+) -> (String, &'a str) { -+ let left_label_original_width = left_label_original.width(); -+ let right_label_original_width = right_label_original.width(); -+ -+ let left_width_remainder = drawing_width as i32 - right_label_original_width as i32; -+ let width_remainder = left_width_remainder as i32 - left_label_original_width as i32; -+ -+ if drawing_width == 0 { -+ ("".to_string(), "") -+ } else if width_remainder >= 0 { -+ (left_label_original.to_string(), right_label_original) -+ } else { -+ if left_width_remainder < MIN_LEFT_LABEL_WIDTH { -+ ( -+ if left_label_original.width() as i32 <= left_width_remainder { -+ trim_file_label(left_label_original, drawing_width) -+ } else { -+ left_label_original.to_string() -+ }, -+ "", -+ ) -+ } else { -+ ( -+ trim_file_label(left_label_original, left_width_remainder as usize), -+ right_label_original, -+ ) - } -- FileType::File => { -- if drawing_width < FILE_SIZE_WIDTH { -- return; -- } -- let file_drawing_width = drawing_width - FILE_SIZE_WIDTH; -+ } -+} - -- let (stem, extension) = match name.rfind('.') { -- None => (name, ""), -- Some(i) => name.split_at(i), -- }; -- if stem.is_empty() { -- let ext_width = extension.width(); -- buf.set_stringn(x, y, extension, file_drawing_width, style); -- if ext_width > drawing_width { -- buf.set_string(x + drawing_width as u16 - 1, y, ELLIPSIS, style); -- } -- } else if extension.is_empty() { -- let stem_width = stem.width(); -- buf.set_stringn(x, y, stem, file_drawing_width, style); -- if stem_width > file_drawing_width { -- buf.set_string(x + drawing_width as u16 - 1, y, ELLIPSIS, style); -- } -- } else { -- let stem_width = stem.width(); -- let ext_width = extension.width(); -- buf.set_stringn(x, y, stem, file_drawing_width, style); -- if stem_width + ext_width > file_drawing_width { -- let ext_start_idx = if file_drawing_width < ext_width { -- 0 -- } else { -- (file_drawing_width - ext_width) as u16 -- }; -- buf.set_string(x + ext_start_idx, y, extension, style); -- let ext_start_idx = if ext_start_idx > 0 { -- ext_start_idx - 1 -- } else { -- 0 -- }; -- buf.set_string(x + ext_start_idx, y, ELLIPSIS, style); -- } else { -- buf.set_string(x + stem_width as u16, y, extension, style); -- } -- } -- // print file size -- let file_size_string = format::file_size_to_string(entry.metadata.len()); -- buf.set_string(x + file_drawing_width as u16, y, " ", style); -- buf.set_string( -- x + file_drawing_width as u16 + 1, -- y, -- file_size_string, -- style, -- ); -+pub fn trim_file_label(name: &str, drawing_width: usize) -> String { -+ // pre-condition: string name is longer than width -+ let (stem, extension) = match name.rfind('.') { -+ None => (name, ""), -+ Some(i) => name.split_at(i), -+ }; -+ if drawing_width < 1 { -+ String::from("") -+ } else if stem.is_empty() || extension.is_empty() { -+ let full = format!("{}{}", stem, extension); -+ let mut truncated = full.trunc(drawing_width - 1); -+ truncated.push_str(ELLIPSIS); -+ truncated -+ } else { -+ let ext_width = extension.width(); -+ if ext_width > drawing_width { -+ // file ext does not fit -+ ELLIPSIS.to_string() -+ } else if ext_width == drawing_width { -+ extension.replacen('.', ELLIPSIS, 1).to_string() -+ } else { -+ let stem_width = drawing_width - ext_width; -+ let truncated_stem = stem.trunc(stem_width - 1); -+ format!("{}{}{}", truncated_stem, ELLIPSIS, extension) - } - } - } -+ -+#[cfg(test)] -+mod test_factor_labels { -+ use super::{factor_labels_for_entry, MIN_LEFT_LABEL_WIDTH}; -+ -+ #[test] -+ fn both_labels_empty_if_drawing_width_zero() { -+ let left = "foo.ext"; -+ let right = "right"; -+ assert_eq!( -+ ("".to_string(), ""), -+ factor_labels_for_entry(left, right, 0) -+ ); -+ } -+ -+ #[test] -+ fn nothing_changes_if_all_labels_fit_easily() { -+ let left = "foo.ext"; -+ let right = "right"; -+ assert_eq!( -+ (left.to_string(), right), -+ factor_labels_for_entry(left, right, 20) -+ ); -+ } -+ -+ #[test] -+ fn nothing_changes_if_all_labels_just_fit() { -+ let left = "foo.ext"; -+ let right = "right"; -+ assert_eq!( -+ (left.to_string(), right), -+ factor_labels_for_entry(left, right, 12) -+ ); -+ } -+ -+ #[test] -+ fn right_label_omitted_if_left_label_would_need_to_be_shortened_below_min_left_label_width() { -+ let left = "foobarbazfo.ext"; -+ let right = "right"; -+ assert!(left.chars().count() as i32 == MIN_LEFT_LABEL_WIDTH); -+ assert_eq!( -+ ("foobarbazfo.ext".to_string(), ""), -+ factor_labels_for_entry(left, right, MIN_LEFT_LABEL_WIDTH as usize) -+ ); -+ } -+ -+ #[test] -+ fn right_label_is_kept_if_left_label_is_not_shortened_below_min_left_label_width() { -+ let left = "foobarbazfoobarbaz.ext"; -+ let right = "right"; -+ assert!(left.chars().count() as i32 > MIN_LEFT_LABEL_WIDTH + right.chars().count() as i32); -+ assert_eq!( -+ ("foobarbazf….ext".to_string(), right), -+ factor_labels_for_entry( -+ left, -+ right, -+ MIN_LEFT_LABEL_WIDTH as usize + right.chars().count() -+ ) -+ ); -+ } -+ -+ #[test] -+ // regression -+ fn file_name_which_is_smaller_or_equal_drawing_width_does_not_cause_right_label_to_be_omitted() -+ { -+ let left = "foooooobaaaaaaarbaaaaaaaaaz"; -+ let right = "right"; -+ assert!(left.chars().count() as i32 > MIN_LEFT_LABEL_WIDTH); -+ assert_eq!( -+ ("foooooobaaaaaaarbaaaa…".to_string(), right), -+ factor_labels_for_entry(left, right, left.chars().count()) -+ ); -+ } -+} -+ -+#[cfg(test)] -+mod test_trim_file_label { -+ use super::trim_file_label; -+ -+ #[test] -+ fn dotfiles_get_an_ellipsis_at_the_end_if_they_dont_fit() { -+ let label = ".joshuto"; -+ assert_eq!(".jos…".to_string(), trim_file_label(label, 5)); -+ } -+ -+ #[test] -+ fn dotless_files_get_an_ellipsis_at_the_end_if_they_dont_fit() { -+ let label = "Desktop"; -+ assert_eq!("Desk…".to_string(), trim_file_label(label, 5)); -+ } -+ -+ #[test] -+ fn if_the_extension_doesnt_fit_just_an_ellipses_is_shown() { -+ let label = "foo.ext"; -+ assert_eq!("…".to_string(), trim_file_label(label, 2)); -+ } -+ -+ #[test] -+ fn if_just_the_extension_fits_its_shown_with_an_ellipsis_instead_of_a_dot() { -+ let left = "foo.ext"; -+ assert_eq!("…ext".to_string(), trim_file_label(left, 4)); -+ } -+ -+ #[test] -+ fn if_the_extension_fits_the_stem_is_truncated_with_an_appended_ellipsis_1() { -+ let left = "foo.ext"; -+ assert_eq!("….ext".to_string(), trim_file_label(left, 5)); -+ } -+ -+ #[test] -+ fn if_the_extension_fits_the_stem_is_truncated_with_an_appended_ellipsis_2() { -+ let left = "foo.ext"; -+ assert_eq!("f….ext".to_string(), trim_file_label(left, 6)); -+ } -+ -+ #[test] -+ fn if_the_name_is_truncated_after_a_full_width_character_the_ellipsis_is_shown_correctly() { -+ let left = "🌕🌕🌕"; -+ assert_eq!("🌕…".to_string(), trim_file_label(left, 4)); -+ } -+ -+ #[test] -+ fn if_the_name_is_truncated_within_a_full_width_character_the_ellipsis_is_shown_correctly() { -+ let left = "🌕🌕🌕"; -+ assert_eq!("🌕🌕…".to_string(), trim_file_label(left, 5)); -+ } -+} -diff -ur a/src/ui/widgets/tui_dirlist.rs b/src/ui/widgets/tui_dirlist.rs ---- a/src/ui/widgets/tui_dirlist.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/ui/widgets/tui_dirlist.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -4,11 +4,10 @@ - use tui::widgets::Widget; - use unicode_width::UnicodeWidthStr; - --use crate::fs::{FileType, JoshutoDirEntry, JoshutoDirList}; -+use crate::fs::{JoshutoDirEntry, JoshutoDirList}; -+use crate::ui::widgets::trim_file_label; - use crate::util::style; - --const ELLIPSIS: &str = "…"; -- - pub struct TuiDirList<'a> { - dirlist: &'a JoshutoDirList, - } -@@ -37,7 +36,7 @@ - } - - let curr_index = self.dirlist.index.unwrap(); -- let skip_dist = curr_index / area.height as usize * area.height as usize; -+ let skip_dist = self.dirlist.first_index_for_viewport(area.height as usize); - - let drawing_width = area.width as usize; - -@@ -79,54 +78,10 @@ - ) { - let name = entry.label(); - let name_width = name.width(); -- -- match entry.metadata.file_type() { -- FileType::Directory => { -- // print filename -- buf.set_stringn(x, y, name, drawing_width, style); -- if name_width > drawing_width { -- buf.set_string(x + drawing_width as u16 - 1, y, ELLIPSIS, style); -- } -- } -- _ => { -- let file_drawing_width = drawing_width; -- let (stem, extension) = match name.rfind('.') { -- None => (name, ""), -- Some(i) => name.split_at(i), -- }; -- if stem.is_empty() { -- let ext_width = extension.width(); -- buf.set_stringn(x, y, extension, file_drawing_width, style); -- if ext_width > drawing_width { -- buf.set_string(x + drawing_width as u16 - 1, y, ELLIPSIS, style); -- } -- } else if extension.is_empty() { -- let stem_width = stem.width(); -- buf.set_stringn(x, y, stem, file_drawing_width, style); -- if stem_width > file_drawing_width { -- buf.set_string(x + file_drawing_width as u16 - 1, y, ELLIPSIS, style); -- } -- } else { -- let stem_width = stem.width(); -- let ext_width = extension.width(); -- buf.set_stringn(x, y, stem, file_drawing_width, style); -- if stem_width + ext_width > file_drawing_width { -- let ext_start_idx = if file_drawing_width < ext_width { -- 0 -- } else { -- (file_drawing_width - ext_width) as u16 -- }; -- buf.set_string(x + ext_start_idx, y, extension, style); -- let ext_start_idx = if ext_start_idx > 0 { -- ext_start_idx - 1 -- } else { -- 0 -- }; -- buf.set_string(x + ext_start_idx, y, ELLIPSIS, style); -- } else { -- buf.set_string(x + stem_width as u16, y, extension, style); -- } -- } -- } -- } -+ let label = if name_width > drawing_width { -+ trim_file_label(name, drawing_width) -+ } else { -+ name.to_string() -+ }; -+ buf.set_string(x, y, label, style); - } -diff -ur a/src/ui/widgets/tui_footer.rs b/src/ui/widgets/tui_footer.rs ---- a/src/ui/widgets/tui_footer.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/ui/widgets/tui_footer.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -4,7 +4,7 @@ - use tui::text::{Span, Spans}; - use tui::widgets::{Paragraph, Widget}; - --use crate::fs::{FileType, JoshutoDirList}; -+use crate::fs::{JoshutoDirList, LinkType}; - use crate::util::format; - use crate::util::unix; - -@@ -41,7 +41,7 @@ - Span::raw(size_str), - ]; - -- if let FileType::Symlink(s) = entry.metadata.file_type() { -+ if let LinkType::Symlink(s) = entry.metadata.link_type() { - text.push(Span::styled(" -> ", mode_style)); - text.push(Span::styled(s, mode_style)); - } -diff -ur a/src/ui/widgets/tui_menu.rs b/src/ui/widgets/tui_menu.rs ---- a/src/ui/widgets/tui_menu.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/ui/widgets/tui_menu.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -19,18 +19,18 @@ - - impl<'a> Widget for TuiMenu<'a> { - fn render(self, area: Rect, buf: &mut Buffer) { -- let text_iter = self.options.iter().chain(&[" "]); - let style = Style::default().fg(Color::Reset).bg(Color::Reset); -- let area_x = area.x + 1; -- let area_y = area.y + 1; - - Block::default() - .style(style) - .borders(Borders::TOP) - .render(area, buf); - -- for (i, text) in text_iter.enumerate() { -- buf.set_string(area_x, area_y + i as u16, text, style); -+ let text_iter = self.options.iter().chain(&[" "]); -+ let area_x = area.x + 1; -+ -+ for (y, text) in (area.y + 1..area.y + area.height).zip(text_iter) { -+ buf.set_string(area_x, y, text, style); - } - } - } -diff -ur a/src/ui/widgets/tui_prompt.rs b/src/ui/widgets/tui_prompt.rs ---- a/src/ui/widgets/tui_prompt.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/ui/widgets/tui_prompt.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -5,9 +5,9 @@ - use tui::widgets::{Clear, Paragraph, Wrap}; - - use crate::context::AppContext; -+use crate::event::AppEvent; - use crate::ui::views::TuiView; - use crate::ui::TuiBackend; --use crate::util::event::AppEvent; - use crate::util::input; - - pub struct TuiPrompt<'a> { -diff -ur a/src/ui/widgets/tui_topbar.rs b/src/ui/widgets/tui_topbar.rs ---- a/src/ui/widgets/tui_topbar.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/ui/widgets/tui_topbar.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -22,10 +22,6 @@ - - impl<'a> Widget for TuiTopBar<'a> { - fn render(self, area: Rect, buf: &mut Buffer) { -- let username_style = Style::default() -- .fg(Color::LightGreen) -- .add_modifier(Modifier::BOLD); -- - let path_style = Style::default() - .fg(Color::LightBlue) - .add_modifier(Modifier::BOLD); -@@ -34,12 +30,9 @@ - let mut curr_path_str = self.path.to_string_lossy().into_owned(); - - if curr_path_str.len() > area.width as usize { -- match self.path.file_name() { -- Some(s) => { -- curr_path_str = s.to_string_lossy().into_owned(); -- ellipses = Some(Span::styled("…", path_style)); -- } -- None => {} -+ if let Some(s) = self.path.file_name() { -+ curr_path_str = s.to_string_lossy().into_owned(); -+ ellipses = Some(Span::styled("…", path_style)); - } - } - if self -@@ -54,6 +47,14 @@ - } - } - -+ let username_style = if USERNAME.as_str() == "root" { -+ Style::default().fg(Color::Red).add_modifier(Modifier::BOLD) -+ } else { -+ Style::default() -+ .fg(Color::LightGreen) -+ .add_modifier(Modifier::BOLD) -+ }; -+ - let text = match ellipses { - Some(s) => Spans::from(vec![ - Span::styled(USERNAME.as_str(), username_style), -diff -ur a/src/ui/widgets/tui_worker.rs b/src/ui/widgets/tui_worker.rs ---- a/src/ui/widgets/tui_worker.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/ui/widgets/tui_worker.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -5,6 +5,7 @@ - - use crate::context::AppContext; - use crate::io::FileOp; -+use crate::util::format; - - pub struct TuiWorker<'a> { - pub context: &'a AppContext, -@@ -25,19 +26,28 @@ - FileOp::Copy => "Copying", - FileOp::Cut => "Moving", - }; -+ -+ let processed_size = format::file_size_to_string(progress.bytes_processed()); -+ let total_size = format::file_size_to_string(progress.total_bytes()); -+ - let msg = format!( -- "{} ({}/{}) {:?}", -+ "{} ({}/{}) ({}/{}) {:?}", - op_str, -- progress.completed() + 1, -- progress.len(), -+ progress.files_processed() + 1, -+ progress.total_files(), -+ processed_size, -+ total_size, - io_obs.dest_path() - ); -+ - let style = Style::default(); - buf.set_stringn(0, 2, msg, area.width as usize, style); - - // draw a progress bar -- let progress_bar_width = (progress.completed() as f32 / progress.len() as f32 -+ let progress_bar_width = (progress.files_processed() as f32 -+ / progress.total_files() as f32 - * area.width as f32) as usize; -+ - let progress_bar_space = " ".repeat(progress_bar_width); - let style = Style::default().bg(Color::Blue); - buf.set_stringn(0, 3, progress_bar_space, area.width as usize, style); -diff -ur a/src/util/display.rs b/src/util/display.rs ---- a/src/util/display.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/util/display.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -106,14 +106,11 @@ - - fn filter_hidden(result: &Result) -> bool { - match result { -- Err(_) => false, -+ Err(_) => true, - Ok(entry) => { - let file_name = entry.file_name(); -- if let Some(file_name) = file_name.to_str() { -- !file_name.starts_with('.') -- } else { -- false -- } -+ let lossy_string = file_name.as_os_str().to_string_lossy(); -+ !lossy_string.starts_with('.') - } - } - } -Только в a/src/util: event.rs -diff -ur a/src/util/input.rs b/src/util/input.rs ---- a/src/util/input.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/util/input.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -4,10 +4,10 @@ - - use crate::commands::{cursor_move, parent_cursor_move, AppExecute, KeyCommand}; - use crate::context::AppContext; -+use crate::event::AppEvent; - use crate::history::DirectoryHistory; - use crate::io::{FileOp, IoWorkerProgress}; - use crate::ui; --use crate::util::event::AppEvent; - use crate::util::format; - - pub fn process_mouse(event: MouseEvent, context: &mut AppContext, backend: &mut ui::TuiBackend) { -@@ -16,7 +16,13 @@ - let constraints: &[Constraint; 3] = &context.config_ref().display_options_ref().default_layout; - let layout_rect = Layout::default() - .direction(Direction::Horizontal) -- .vertical_margin(1) -+ .vertical_margin( -+ if context.config_ref().display_options_ref().show_borders() { -+ 2 -+ } else { -+ 1 -+ }, -+ ) - .constraints(constraints.as_ref()) - .split(f_size); - -@@ -54,28 +60,28 @@ - MouseEvent::Press(MouseButton::Left, x, y) - if y > layout_rect[1].y && y <= layout_rect[1].y + layout_rect[1].height => - { -- if x < layout_rect[1].x { -- if let Some(dirlist) = context.tab_context_ref().curr_tab_ref().curr_list_ref() { -- if let Some(curr_index) = dirlist.index { -- let skip_dist = curr_index / layout_rect[1].height as usize -- * layout_rect[1].height as usize; -- -- let new_index = skip_dist + (y - layout_rect[1].y - 1) as usize; -- if let Err(e) = parent_cursor_move::parent_cursor_move(new_index, context) { -- context.push_msg(e.to_string()); -- } -- } -- } -- } else if x < layout_rect[2].x { -- if let Some(dirlist) = context.tab_context_ref().curr_tab_ref().curr_list_ref() { -- if let Some(curr_index) = dirlist.index { -- let skip_dist = curr_index / layout_rect[1].height as usize -- * layout_rect[1].height as usize; -- -- let new_index = skip_dist + (y - layout_rect[1].y - 1) as usize; -- if let Err(e) = cursor_move::cursor_move(new_index, context) { -- context.push_msg(e.to_string()); -- } -+ if x < layout_rect[2].x { -+ let (dirlist, is_parent) = if x < layout_rect[1].x { -+ ( -+ context.tab_context_ref().curr_tab_ref().parent_list_ref(), -+ true, -+ ) -+ } else { -+ ( -+ context.tab_context_ref().curr_tab_ref().curr_list_ref(), -+ false, -+ ) -+ }; -+ if let Some(dirlist) = dirlist { -+ let skip_dist = -+ dirlist.first_index_for_viewport(layout_rect[1].height as usize); -+ let new_index = skip_dist + (y - layout_rect[1].y - 1) as usize; -+ if let Err(e) = if is_parent { -+ parent_cursor_move::parent_cursor_move(new_index, context) -+ } else { -+ cursor_move::cursor_move(new_index, context) -+ } { -+ context.push_msg(e.to_string()); - } - } - } else { -@@ -118,12 +124,14 @@ - FileOp::Copy => "copied", - FileOp::Cut => "moved", - }; -- let size_str = format::file_size_to_string(progress.bytes_processed()); -+ let processed_size = format::file_size_to_string(progress.bytes_processed()); -+ let total_size = format::file_size_to_string(progress.total_bytes()); - let msg = format!( -- "successfully {} {} items ({})", -+ "successfully {} {} items ({}/{})", - op, -- progress.len(), -- size_str -+ progress.total_files(), -+ processed_size, -+ total_size, - ); - context.push_msg(msg); - } -Только в a/src/util: load_child.rs -diff -ur a/src/util/mod.rs b/src/util/mod.rs ---- a/src/util/mod.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/util/mod.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -2,14 +2,13 @@ - pub mod devicons; - - pub mod display; --pub mod event; - pub mod format; - pub mod input; --pub mod load_child; - pub mod name_resolution; - pub mod search; - pub mod select; - pub mod sort; -+pub mod string; - pub mod style; - pub mod to_string; - pub mod unix; -diff -ur a/src/util/sort.rs b/src/util/sort.rs ---- a/src/util/sort.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/util/sort.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -1,4 +1,5 @@ - use std::cmp; -+use std::collections::VecDeque; - use std::fs; - use std::time; - -@@ -6,12 +7,13 @@ - - use crate::fs::JoshutoDirEntry; - --#[derive(Clone, Copy, Debug, Deserialize)] -+#[derive(Clone, Copy, Debug, Deserialize, PartialEq)] - pub enum SortType { - Lexical, - Mtime, - Natural, - Size, -+ Ext, - } - - impl SortType { -@@ -21,6 +23,7 @@ - "mtime" => Some(SortType::Mtime), - "natural" => Some(SortType::Natural), - "size" => Some(SortType::Size), -+ "ext" => Some(SortType::Ext), - _ => None, - } - } -@@ -30,6 +33,21 @@ - SortType::Mtime => "mtime", - SortType::Natural => "natural", - SortType::Size => "size", -+ SortType::Ext => "ext", -+ } -+ } -+ pub fn cmp( -+ &self, -+ f1: &JoshutoDirEntry, -+ f2: &JoshutoDirEntry, -+ sort_option: &SortOption, -+ ) -> cmp::Ordering { -+ match &self { -+ SortType::Natural => natural_sort(f1, f2, sort_option), -+ SortType::Lexical => lexical_sort(f1, f2, sort_option), -+ SortType::Size => size_sort(f1, f2), -+ SortType::Mtime => mtime_sort(f1, f2), -+ SortType::Ext => ext_sort(f1, f2), - } - } - } -@@ -41,14 +59,61 @@ - } - - #[derive(Clone, Debug)] -+pub struct SortTypes { -+ pub list: VecDeque, -+} -+ -+impl SortTypes { -+ pub fn reorganize(&mut self, st: SortType) { -+ self.list.push_front(st); -+ self.list.pop_back(); -+ } -+ -+ pub fn cmp( -+ &self, -+ f1: &JoshutoDirEntry, -+ f2: &JoshutoDirEntry, -+ sort_option: &SortOption, -+ ) -> cmp::Ordering { -+ for st in &self.list { -+ let res = st.cmp(f1, f2, sort_option); -+ if res != cmp::Ordering::Equal { -+ return res; -+ } -+ } -+ cmp::Ordering::Equal -+ } -+} -+ -+impl std::default::Default for SortTypes { -+ fn default() -> Self { -+ let list: VecDeque = vec![ -+ SortType::Natural, -+ SortType::Lexical, -+ SortType::Size, -+ SortType::Ext, -+ SortType::Mtime, -+ ] -+ .into_iter() -+ .collect(); -+ -+ Self { list } -+ } -+} -+ -+#[derive(Clone, Debug)] - pub struct SortOption { - pub directories_first: bool, - pub case_sensitive: bool, - pub reverse: bool, -- pub sort_method: SortType, -+ pub sort_methods: SortTypes, - } - - impl SortOption { -+ pub fn set_sort_method(&mut self, method: SortType) { -+ self.sort_methods.reorganize(method); -+ } -+ - pub fn compare(&self, f1: &JoshutoDirEntry, f2: &JoshutoDirEntry) -> cmp::Ordering { - if self.directories_first { - let f1_isdir = f1.file_path().is_dir(); -@@ -61,40 +126,15 @@ - } - } - -- let mut res = match self.sort_method { -- SortType::Lexical => { -- let f1_name = f1.file_name(); -- let f2_name = f2.file_name(); -- if self.case_sensitive { -- f1_name.cmp(&f2_name) -- } else { -- let f1_name = f1_name.to_lowercase(); -- let f2_name = f2_name.to_lowercase(); -- f1_name.cmp(&f2_name) -- } -- } -- SortType::Natural => { -- let f1_name = f1.file_name(); -- let f2_name = f2.file_name(); -- if self.case_sensitive { -- alphanumeric_sort::compare_str(&f1_name, &f2_name) -- } else { -- let f1_name = f1_name.to_lowercase(); -- let f2_name = f2_name.to_lowercase(); -- alphanumeric_sort::compare_str(&f1_name, &f2_name) -- } -- } -- SortType::Mtime => mtime_sort(f1, f2), -- SortType::Size => size_sort(f1, f2), -- }; -- -+ // let mut res = self.sort_method.cmp(f1, f2, &self); -+ let mut res = self.sort_methods.cmp(f1, f2, &self); - if self.reverse { - res = match res { - cmp::Ordering::Less => cmp::Ordering::Greater, - cmp::Ordering::Greater => cmp::Ordering::Less, - s => s, - }; -- } -+ }; - res - } - } -@@ -105,7 +145,7 @@ - directories_first: true, - case_sensitive: false, - reverse: false, -- sort_method: SortType::Natural, -+ sort_methods: SortTypes::default(), - } - } - } -@@ -120,16 +160,49 @@ - - let f1_mtime: time::SystemTime = f1_meta.modified()?; - let f2_mtime: time::SystemTime = f2_meta.modified()?; -- -- Ok(if f1_mtime >= f2_mtime { -- cmp::Ordering::Less -- } else { -- cmp::Ordering::Greater -- }) -+ Ok(f1_mtime.cmp(&f2_mtime)) - } -- compare(&file1, &file2).unwrap_or(cmp::Ordering::Less) -+ compare(&file1, &file2).unwrap_or(cmp::Ordering::Equal) - } - - fn size_sort(file1: &JoshutoDirEntry, file2: &JoshutoDirEntry) -> cmp::Ordering { - file1.metadata.len().cmp(&file2.metadata.len()) - } -+ -+fn ext_sort(file1: &JoshutoDirEntry, file2: &JoshutoDirEntry) -> cmp::Ordering { -+ let f1_ext = file1.get_ext(); -+ let f2_ext = file2.get_ext(); -+ alphanumeric_sort::compare_str(&f1_ext, &f2_ext) -+} -+ -+fn lexical_sort( -+ f1: &JoshutoDirEntry, -+ f2: &JoshutoDirEntry, -+ sort_option: &SortOption, -+) -> cmp::Ordering { -+ let f1_name = f1.file_name(); -+ let f2_name = f2.file_name(); -+ if sort_option.case_sensitive { -+ f1_name.cmp(&f2_name) -+ } else { -+ let f1_name = f1_name.to_lowercase(); -+ let f2_name = f2_name.to_lowercase(); -+ f1_name.cmp(&f2_name) -+ } -+} -+ -+fn natural_sort( -+ f1: &JoshutoDirEntry, -+ f2: &JoshutoDirEntry, -+ sort_option: &SortOption, -+) -> cmp::Ordering { -+ let f1_name = f1.file_name(); -+ let f2_name = f2.file_name(); -+ if sort_option.case_sensitive { -+ alphanumeric_sort::compare_str(&f1_name, &f2_name) -+ } else { -+ let f1_name = f1_name.to_lowercase(); -+ let f2_name = f2_name.to_lowercase(); -+ alphanumeric_sort::compare_str(&f1_name, &f2_name) -+ } -+} -Только в b/src/util: string.rs -diff -ur a/src/util/style.rs b/src/util/style.rs ---- a/src/util/style.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/util/style.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -1,6 +1,6 @@ - use tui::style::Style; - --use crate::fs::{FileType, JoshutoDirEntry}; -+use crate::fs::{FileType, JoshutoDirEntry, LinkType}; - use crate::util::unix; - - use crate::THEME_T; -@@ -8,25 +8,39 @@ - pub fn entry_style(entry: &JoshutoDirEntry) -> Style { - let metadata = &entry.metadata; - let filetype = &metadata.file_type(); -+ let linktype = &metadata.link_type(); - -- match filetype { -- _ if entry.is_selected() => Style::default() -+ if entry.is_selected() { -+ Style::default() - .fg(THEME_T.selection.fg) - .bg(THEME_T.selection.bg) -- .add_modifier(THEME_T.selection.modifier), -- FileType::Directory => Style::default() -- .fg(THEME_T.directory.fg) -- .bg(THEME_T.directory.bg) -- .add_modifier(THEME_T.directory.modifier), -- FileType::Symlink(_) => Style::default() -- .fg(THEME_T.link.fg) -- .bg(THEME_T.link.bg) -- .add_modifier(THEME_T.link.modifier), -- _ if unix::is_executable(metadata.mode) => Style::default() -+ .add_modifier(THEME_T.selection.modifier) -+ } else { -+ match linktype { -+ LinkType::Symlink(_) => Style::default() -+ .fg(THEME_T.link.fg) -+ .bg(THEME_T.link.bg) -+ .add_modifier(THEME_T.link.modifier), -+ LinkType::Normal => match filetype { -+ FileType::Directory => Style::default() -+ .fg(THEME_T.directory.fg) -+ .bg(THEME_T.directory.bg) -+ .add_modifier(THEME_T.directory.modifier), -+ FileType::File => file_style(entry), -+ }, -+ } -+ } -+} -+ -+fn file_style(entry: &JoshutoDirEntry) -> Style { -+ let metadata = &entry.metadata; -+ if unix::is_executable(metadata.mode) { -+ Style::default() - .fg(THEME_T.executable.fg) - .bg(THEME_T.executable.bg) -- .add_modifier(THEME_T.executable.modifier), -- _ => match entry.file_path().extension() { -+ .add_modifier(THEME_T.executable.modifier) -+ } else { -+ match entry.file_path().extension() { - None => Style::default(), - Some(os_str) => match os_str.to_str() { - None => Style::default(), -@@ -35,6 +49,6 @@ - Some(t) => Style::default().fg(t.fg).bg(t.bg).add_modifier(t.modifier), - }, - }, -- }, -+ } - } - } -diff -ur a/src/util/to_string.rs b/src/util/to_string.rs ---- a/src/util/to_string.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/util/to_string.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -30,9 +30,8 @@ - - impl ToString for MouseEvent { - fn to_string(&self) -> String { -- match *self { -- k => format!("{:?}", k), -- } -+ let k = *self; -+ format!("{:?}", k) - } - } - -diff -ur a/src/util/unix.rs b/src/util/unix.rs ---- a/src/util/unix.rs 2021-05-08 03:04:44.000000000 +0300 -+++ b/src/util/unix.rs 2021-08-07 11:25:14.715474131 +0300 -@@ -1,5 +1,3 @@ --use std::path::Path; -- - pub fn is_executable(mode: u32) -> bool { - const LIBC_PERMISSION_VALS: [libc::mode_t; 3] = [libc::S_IXUSR, libc::S_IXGRP, libc::S_IXOTH]; - -@@ -51,13 +49,3 @@ - } - mode_str - } -- --pub fn set_mode(path: &Path, mode: u32) { -- let os_path = path.as_os_str(); -- if let Some(s) = os_path.to_str() { -- let svec: Vec = s.bytes().map(|ch| ch as libc::c_char).collect(); -- unsafe { -- libc::chmod(svec.as_ptr(), mode as libc::mode_t); -- } -- } --} diff --git a/app-misc/joshuto/joshuto-0.9.0.ebuild b/app-misc/joshuto/joshuto-0.9.0.ebuild index 44e1dca..68b6b61 100644 --- a/app-misc/joshuto/joshuto-0.9.0.ebuild +++ b/app-misc/joshuto/joshuto-0.9.0.ebuild @@ -11,69 +11,36 @@ arrayref-0.3.6 arrayvec-0.5.2 atty-0.2.14 autocfg-1.0.1 -base-x-0.2.8 base64-0.13.0 -beef-0.5.0 bitflags-1.2.1 blake2b_simd-0.5.11 bstr-0.2.16 -bumpalo-3.6.1 cassowary-0.3.0 cc-1.0.67 cfg-if-0.1.10 cfg-if-1.0.0 chrono-0.4.19 clap-2.33.3 -colors-transform-0.2.11 -const_fn-0.4.8 constant_time_eq-0.1.5 -crossbeam-0.8.0 -crossbeam-channel-0.4.4 -crossbeam-channel-0.5.1 -crossbeam-deque-0.8.0 -crossbeam-epoch-0.9.4 -crossbeam-queue-0.3.1 -crossbeam-utils-0.7.2 crossbeam-utils-0.8.4 -darling-0.10.2 -darling_core-0.10.2 -darling_macro-0.10.2 -defer-drop-1.0.1 -derive_builder-0.9.0 -derive_builder_core-0.9.0 dirs-1.0.5 -dirs-2.0.2 dirs-next-2.0.0 -dirs-sys-0.3.6 dirs-sys-next-0.1.2 -discard-1.0.4 either-1.6.1 -env_logger-0.8.3 -filetime-0.2.14 fnv-1.0.7 -fuzzy-matcher-0.3.7 getrandom-0.1.16 getrandom-0.2.2 globset-0.4.6 heck-0.3.2 hermit-abi-0.1.18 -humantime-2.1.0 -ident_case-1.0.1 -itoa-0.4.7 lazy_static-1.4.0 libc-0.2.94 log-0.4.14 -maybe-uninit-2.0.0 memchr-2.4.0 -memoffset-0.6.3 nix-0.13.1 -nix-0.14.1 -nix-0.19.1 num-integer-0.1.44 num-traits-0.2.14 -num_cpus-1.13.0 numtoa-0.1.0 -once_cell-1.7.2 open-1.7.0 phf-0.8.0 phf_generator-0.8.0 @@ -90,8 +57,6 @@ rand_chacha-0.2.2 rand_core-0.5.1 rand_hc-0.2.0 rand_pcg-0.2.1 -rayon-1.5.1 -rayon-core-1.9.1 redox_syscall-0.1.57 redox_syscall-0.2.8 redox_termios-0.1.2 @@ -100,70 +65,38 @@ redox_users-0.4.0 regex-1.5.4 regex-syntax-0.6.25 rust-argon2-0.8.3 -rustc_version-0.2.3 rustyline-4.1.0 -ryu-1.0.5 -scopeguard-1.1.0 -semver-0.9.0 -semver-parser-0.7.0 serde-1.0.125 serde_derive-1.0.125 -serde_json-1.0.64 -sha1-0.6.0 shell-words-1.0.0 shellexpand-2.1.0 -shlex-0.1.1 signal-hook-0.3.8 signal-hook-registry-1.3.0 siphasher-0.3.5 -skim-0.9.4 -standback-0.2.17 -stdweb-0.4.20 -stdweb-derive-0.5.3 -stdweb-internal-macros-0.2.9 -stdweb-internal-runtime-0.1.5 strsim-0.8.0 -strsim-0.9.3 structopt-0.3.21 structopt-derive-0.4.14 syn-1.0.72 -term-0.6.1 -termcolor-1.1.2 termion-1.5.6 textwrap-0.11.0 -thread_local-1.1.3 time-0.1.43 -time-0.2.26 -time-macros-0.1.1 -time-macros-impl-0.1.1 -timer-0.2.0 toml-0.5.8 trash-1.3.0 tui-0.15.0 -tuikit-0.4.5 unicode-segmentation-1.7.1 unicode-width-0.1.8 unicode-xid-0.2.2 users-0.11.0 utf8parse-0.1.1 -utf8parse-0.2.0 vec_map-0.8.2 version_check-0.9.3 void-1.0.2 -vte-0.9.0 -vte_generate_state_changes-0.1.1 wasi-0.10.2+wasi-snapshot-preview1 wasi-0.9.0+wasi-snapshot-preview1 -wasm-bindgen-0.2.74 -wasm-bindgen-backend-0.2.74 -wasm-bindgen-macro-0.2.74 -wasm-bindgen-macro-support-0.2.74 -wasm-bindgen-shared-0.2.74 which-4.1.0 whoami-0.9.0 winapi-0.3.9 winapi-i686-pc-windows-gnu-0.4.0 -winapi-util-0.1.5 winapi-x86_64-pc-windows-gnu-0.4.0 xdg-2.2.0 " @@ -185,7 +118,7 @@ RDEPEND="wayland? ( gui-apps/wl-clipboard ) X? ( x11-misc/xclip )" PATCHES=( - ${FILESDIR}/72aaf0c5d10db0004d48e27c58d18d8f2c568f8f.patch + ${FILESDIR}/0001-add-additional-configuration-directories.patch ) src_install() {