From e094d0001e1d5a3b620b8a5d70cccecb5ef49b29 Mon Sep 17 00:00:00 2001 From: Luis Alberto Santos Date: Mon, 20 Mar 2023 20:13:18 +0100 Subject: [PATCH] usability imrpovements --- Cargo.lock | 262 +++++++++++++++++++++++------------------- Cargo.toml | 5 +- README.md | 2 +- intelli-shell.sh | 8 +- src/storage.rs | 16 ++- src/widgets/save.rs | 50 ++++++-- src/widgets/search.rs | 52 ++++++++- 7 files changed, 257 insertions(+), 138 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 38f1866..d12480e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,9 +24,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" +checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" [[package]] name = "autocfg" @@ -40,6 +40,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487f1e0fcbe47deb8b0574e646def1c903389d95241dd1bbcc6ce4a715dfc0c1" + [[package]] name = "cassowary" version = "0.3.0" @@ -63,11 +69,11 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.1.6" +version = "4.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0b0588d44d4d63a87dbd75c136c166bbfd9a86a31cb89e09906521c7d3f5e3" +checksum = "42dfd32784433290c51d92c438bb72ea5063797fc3cc9a21a8c4346bebbb2098" dependencies = [ - "bitflags", + "bitflags 2.0.2", "clap_derive", "clap_lex", "is-terminal", @@ -78,31 +84,31 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.1.0" +version = "4.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" +checksum = "fddf67631444a3a3e3e5ac51c36a5e01335302de677bd78759eaa90ab1f46644" dependencies = [ "heck", "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "clap_lex" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade" +checksum = "033f6b7a4acb1f358c742aaca805c939ee73b4c6209ae4318ec7aca81c42e646" dependencies = [ "os_str_bytes", ] [[package]] name = "crossbeam-channel" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c" dependencies = [ "cfg-if", "crossbeam-utils", @@ -110,9 +116,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -121,9 +127,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" dependencies = [ "autocfg", "cfg-if", @@ -134,9 +140,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if", ] @@ -147,7 +153,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" dependencies = [ - "bitflags", + "bitflags 1.3.2", "crossterm_winapi", "libc", "mio", @@ -159,11 +165,11 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.26.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77f67c7faacd4db07a939f55d66a983a5355358a1f17d32cc9a8d01d1266b9ce" +checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13" dependencies = [ - "bitflags", + "bitflags 1.3.2", "crossterm_winapi", "libc", "mio", @@ -184,22 +190,22 @@ dependencies = [ [[package]] name = "directories" -version = "4.0.1" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" +checksum = "74be3be809c18e089de43bdc504652bb2bc473fca8756131f8689db8cf079ba9" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.3.7" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +checksum = "04414300db88f70d74c5ff54e50f9e1d1737d9a5b90f53fcf2e95ca2a9ab554b" dependencies = [ "libc", "redox_users", - "winapi", + "windows-sys 0.45.0", ] [[package]] @@ -276,7 +282,7 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf7f68c2995f392c49fffb4f95ae2c873297830eb25c6bc4c114ce8f4562acc" dependencies = [ - "bitflags", + "bitflags 1.3.2", "libc", "libgit2-sys", "log", @@ -334,6 +340,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "indoc" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f2cb48b81b1dc9f39676bf99f5499babfec7cd8fe14307f7b3d747208fb5690" + [[package]] name = "instant" version = "0.1.12" @@ -345,13 +357,14 @@ dependencies = [ [[package]] name = "intelli-shell" -version = "0.1.2" +version = "0.1.3" dependencies = [ "anyhow", "clap", - "crossterm 0.26.0", + "crossterm 0.26.1", "directories", "git2", + "indoc", "iter-flow", "itertools", "once_cell", @@ -371,24 +384,25 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.5" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" +checksum = "0dd6da19f25979c7270e70fa95ab371ec3b701cd0eefc47667a09785b3c59155" dependencies = [ + "hermit-abi 0.3.1", "libc", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] name = "is-terminal" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef" +checksum = "8687c819457e979cc940d09cb16e42a1bf70aa6b60a549de6d3a62a0ee90c69e" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", "rustix", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -408,24 +422,24 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "jobserver" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" dependencies = [ "libc", ] [[package]] name = "libc" -version = "0.2.139" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" [[package]] name = "libgit2-sys" @@ -496,9 +510,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] @@ -512,7 +526,7 @@ dependencies = [ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -548,9 +562,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.80" +version = "0.9.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23bbbf7854cd45b83958ebe919f0e8e516793727652e27fda10a8384cfc790b7" +checksum = "a95792af3c4e0153c3914df2261bedd30a98476f94dc892b67dfe1d89d433a04" dependencies = [ "autocfg", "cc", @@ -562,9 +576,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.4.1" +version = "6.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" +checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" [[package]] name = "parking_lot" @@ -586,7 +600,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -610,7 +624,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -627,27 +641,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.51" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] [[package]] name = "rayon" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" dependencies = [ "either", "rayon-core", @@ -655,9 +669,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.2" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -671,7 +685,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -702,22 +716,13 @@ version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rusqlite" version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -738,23 +743,23 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.8" +version = "0.36.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" +checksum = "2fe885c3a125aa45213b68cc1472a49880cb5923dc23f522ad2791b882228778" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] name = "ryu" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "scopeguard" @@ -764,29 +769,29 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.152" +version = "1.0.157" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "707de5fcf5df2b5788fca98dd7eab490bc2fd9b7ef1404defc462833b83f25ca" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.152" +version = "1.0.157" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +checksum = "78997f4555c22a7971214540c4a661291970619afd56de19f77e0de86296e1e5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.2", ] [[package]] name = "serde_json" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76" +checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" dependencies = [ "itoa", "ryu", @@ -837,9 +842,20 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.107" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "59d3276aee1fa0c33612917969b5172b5be2db051232a6e4826f1a1a9191b045" dependencies = [ "proc-macro2", "quote", @@ -848,16 +864,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95" dependencies = [ "cfg-if", "fastrand", - "libc", "redox_syscall", - "remove_dir_all", - "winapi", + "rustix", + "windows-sys 0.42.0", ] [[package]] @@ -871,22 +886,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.2", ] [[package]] @@ -910,7 +925,7 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccdd26cbd674007e649a272da4475fb666d3aa0ad0531da7136db6fab0e5bad1" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cassowary", "crossterm 0.25.0", "unicode-segmentation", @@ -919,15 +934,15 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.10" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" +checksum = "7d502c968c6a838ead8e69b2ee18ec708802f99db92a0d156705ec9ef801993b" [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "unicode-normalization" @@ -1026,6 +1041,21 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -1037,9 +1067,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -1052,42 +1082,42 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_i686_gnu" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_x86_64_gnu" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" diff --git a/Cargo.toml b/Cargo.toml index 480504c..e95215a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "intelli-shell" description = "Like IntelliSense, but for shells" -version = "0.1.2" +version = "0.1.3" edition = "2021" license = "Apache-2.0" readme = "README.md" @@ -22,7 +22,8 @@ tldr = ["dep:git2", "dep:tempfile"] anyhow = "1" clap = { version = "4", features = ["derive"] } crossterm = "0.26" -directories = "4" +directories = "5" +indoc = "2" iter-flow = "0.1" itertools = "0.10" once_cell = "1" diff --git a/README.md b/README.md index 94ad983..be5fad2 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ You can customize key bindings using environment variables: `INTELLI_SEARCH_HOTK ## Wishlist - [ ] Labels support to store most used labels and select them using a dedicated UI -- [ ] Pull / Push user bookmarks using some public / private Git repo +- [ ] Sync user bookmarks using some public / private Git repo - [ ] Support for more terminals, like PowerShell ## Alternatives diff --git a/intelli-shell.sh b/intelli-shell.sh index 80a40e4..cfb8820 100755 --- a/intelli-shell.sh +++ b/intelli-shell.sh @@ -42,7 +42,7 @@ elif [[ -n "$BASH" ]]; then # bash # https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html#index-bind - function intelli_search { + function _intelli_search { # Temp file for output tmp_file=$(mktemp -t intelli-shell.XXXXXXXX) # Exec command @@ -55,7 +55,7 @@ elif [[ -n "$BASH" ]]; then READLINE_POINT=${#READLINE_LINE} } - function intelli_save { + function _intelli_save { # Temp file for output tmp_file=$(mktemp -t intelli-shell.XXXXXXXX) # Exec command @@ -69,6 +69,6 @@ elif [[ -n "$BASH" ]]; then } if [[ "${INTELLI_SKIP_ESC_BIND:-0}" == "0" ]]; then bind '"\e": kill-whole-line'; fi - bind -x '"'"$intelli_search_key"'":intelli_search' - bind -x '"'"$intelli_save_key"'":intelli_save' + bind -x '"'"$intelli_search_key"'":_intelli_search' + bind -x '"'"$intelli_save_key"'":_intelli_save' fi diff --git a/src/storage.rs b/src/storage.rs index 6cdeed0..a02d88e 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -218,6 +218,17 @@ impl SqliteStorage { } } + /// Determines if the store is empty (no commands stored) + pub fn is_empty(&self) -> Result { + Ok(self.len()? == 0) + } + + /// Returns the number of stored commands + pub fn len(&self) -> Result { + let mut stmt = self.conn.prepare(r#"SELECT COUNT(*) FROM command"#)?; + Ok(stmt.query_row([], |r| r.get(0))?) + } + /// Get commands matching a category pub fn get_commands(&self, category: impl AsRef) -> Result> { let category = category.as_ref(); @@ -225,7 +236,8 @@ impl SqliteStorage { let mut stmt = self.conn.prepare( r#"SELECT rowid, category, alias, cmd, description, usage FROM command - WHERE category = ?"#, + WHERE category = ? + ORDER BY usage DESC"#, )?; let commands = stmt @@ -241,7 +253,7 @@ impl SqliteStorage { pub fn find_commands(&self, search: impl AsRef) -> Result> { let search = search.as_ref(); if search.is_empty() { - return Ok(Default::default()); + return self.get_commands(USER_CATEGORY); } let flat_search = flatten_str(search); diff --git a/src/widgets/save.rs b/src/widgets/save.rs index 58f0e99..263b230 100644 --- a/src/widgets/save.rs +++ b/src/widgets/save.rs @@ -29,6 +29,8 @@ pub struct SaveCommandWidget<'s> { description: Option, /// Current command description for UI current_description: String, + /// Cursor position + cursor_offset: usize, } impl<'s> SaveCommandWidget<'s> { @@ -38,6 +40,7 @@ impl<'s> SaveCommandWidget<'s> { command, description, current_description: Default::default(), + cursor_offset: 0, } } @@ -62,22 +65,36 @@ impl<'s> Widget for SaveCommandWidget<'s> { } fn peek(&mut self) -> Result> { - match &self.description { - Some(d) => Ok(Some(Self::insert_command(self.storage, &self.command, d)?)), - None => Ok(None), + if self.command.is_empty() { + Ok(Some(WidgetOutput::message("A command must be typed first!"))) + } else { + match &self.description { + Some(d) => Ok(Some(Self::insert_command(self.storage, &self.command, d)?)), + None => Ok(None), + } } } fn render(&mut self, frame: &mut Frame, area: Rect, inline: bool, theme: Theme) { // Display description prompt + let mut description_offset = self.cursor_offset; let max_width = area.width as usize - 1 - (2 * (!inline as usize)); let text_inline = format!("Description: {}", self.current_description); let description_text = if inline { + description_offset += 13; OverflowText::new(max_width, &text_inline) } else { OverflowText::new(max_width, &self.current_description) }; - let description_text_width = description_text.width() as u16; + let description_text_width = description_text.width(); + if text_inline.len() > description_text_width { + let overflow = text_inline.len() as i32 - description_text_width as i32; + if overflow < description_offset as i32 { + description_offset -= overflow as usize; + } else { + description_offset = 0; + } + } let mut description_input = Paragraph::new(description_text).style(Style::default().fg(theme.main)); if !inline { description_input = description_input.block(Block::default().borders(Borders::ALL).title(" Description ")); @@ -87,7 +104,7 @@ impl<'s> Widget for SaveCommandWidget<'s> { // Make the cursor visible and ask tui-rs to put it at the specified coordinates after rendering frame.set_cursor( // Put cursor past the end of the input text - area.x + description_text_width + (!inline as u16), + area.x + description_offset as u16 + (!inline as u16), // Move one line down, from the border to the input line area.y + (!inline as u16), ); @@ -107,10 +124,29 @@ impl<'s> Widget for SaveCommandWidget<'s> { } } KeyCode::Char(c) => { - self.current_description.push(c); + self.current_description.insert(self.cursor_offset, c); + self.cursor_offset += 1; } KeyCode::Backspace => { - self.current_description.pop(); + if !self.current_description.is_empty() { + self.current_description.remove(self.cursor_offset - 1); + self.cursor_offset -= 1; + } + } + KeyCode::Delete => { + if !self.current_description.is_empty() && self.cursor_offset < self.current_description.len() { + self.current_description.remove(self.cursor_offset); + } + } + KeyCode::Right => { + if self.cursor_offset < self.current_description.len() { + self.cursor_offset += 1; + } + } + KeyCode::Left => { + if self.cursor_offset > 0 { + self.cursor_offset -= 1; + } } KeyCode::Esc => { // Exit without saving diff --git a/src/widgets/search.rs b/src/widgets/search.rs index ec4cf50..2ed8e71 100644 --- a/src/widgets/search.rs +++ b/src/widgets/search.rs @@ -23,6 +23,8 @@ pub struct SearchWidget<'s> { storage: &'s mut SqliteStorage, /// Current value of the filter box filter: String, + /// Current cursor offset + cursor_offset: usize, /// Command list of results commands: StatefulList, } @@ -32,6 +34,7 @@ impl<'s> SearchWidget<'s> { let commands = storage.find_commands(&filter)?; Ok(Self { commands: StatefulList::with_items(commands), + cursor_offset: filter.len(), filter, storage, }) @@ -44,7 +47,14 @@ impl<'s> Widget for SearchWidget<'s> { } fn peek(&mut self) -> Result> { - if self.commands.len() == 1 { + if self.storage.is_empty()? { + let message = indoc::indoc! { r#" + There are no stored commands yet! + - Try to bookmark some command with 'Ctrl + B' + - Or execute 'intelli-shell fetch' to download a bunch of tldr's useful commands"# + }; + Ok(Some(WidgetOutput::message(message))) + } else if self.commands.len() == 1 { Ok(self.commands.current().map(|c| c.cmd.clone()).map(WidgetOutput::output)) } else { Ok(None) @@ -70,14 +80,24 @@ impl<'s> Widget for SearchWidget<'s> { let body = chunks[1]; // Display filter + let mut filter_offset = self.cursor_offset; let max_width = header.width as usize - 1 - (2 * (!inline as usize)); let text_inline = format!("(filter): {}", self.filter); let filter_text = if inline { + filter_offset += 10; OverflowText::new(max_width, &text_inline) } else { OverflowText::new(max_width, &self.filter) }; - let filter_text_width = filter_text.width() as u16; + let filter_text_width = filter_text.width(); + if text_inline.len() > filter_text_width { + let overflow = text_inline.len() as i32 - filter_text_width as i32; + if overflow < filter_offset as i32 { + filter_offset -= overflow as usize; + } else { + filter_offset = 0; + } + } let mut filter_input = Paragraph::new(filter_text).style(Style::default().fg(theme.main)); if !inline { filter_input = filter_input.block(Block::default().borders(Borders::ALL).title(" Filter ")); @@ -87,7 +107,7 @@ impl<'s> Widget for SearchWidget<'s> { // Make the cursor visible and ask tui-rs to put it at the specified coordinates after rendering frame.set_cursor( // Put cursor past the end of the input text - header.x + filter_text_width + (!inline as u16), + header.x + filter_offset as u16 + (!inline as u16), // Move one line down, from the border to the input line header.y + (!inline as u16), ); @@ -147,12 +167,32 @@ impl<'s> Widget for SearchWidget<'s> { } } KeyCode::Char(c) => { - self.filter.push(c); + self.filter.insert(self.cursor_offset, c); + self.cursor_offset += 1; self.commands.update_items(self.storage.find_commands(&self.filter)?); } KeyCode::Backspace => { - self.filter.pop(); - self.commands.update_items(self.storage.find_commands(&self.filter)?); + if !self.filter.is_empty() { + self.filter.remove(self.cursor_offset - 1); + self.cursor_offset -= 1; + self.commands.update_items(self.storage.find_commands(&self.filter)?); + } + } + KeyCode::Delete => { + if !self.filter.is_empty() && self.cursor_offset < self.filter.len() { + self.filter.remove(self.cursor_offset); + self.commands.update_items(self.storage.find_commands(&self.filter)?); + } + } + KeyCode::Right => { + if self.cursor_offset < self.filter.len() { + self.cursor_offset += 1; + } + } + KeyCode::Left => { + if self.cursor_offset > 0 { + self.cursor_offset -= 1; + } } KeyCode::Down => { self.commands.next();