From 555727e007656151c67583ed5da4ea9abeab8ddf Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Wed, 10 Mar 2021 03:44:31 -0600 Subject: [PATCH] colon prompt YES --- Cargo.lock | 636 +++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 7 +- imap/src/lib.rs | 7 - src/lib.rs | 1 + src/script.rs | 11 + src/ui/colon_prompt.rs | 47 +++ src/ui/input.rs | 54 ++++ src/ui/keybinds.rs | 1 + src/ui/mod.rs | 96 +++++-- 9 files changed, 807 insertions(+), 53 deletions(-) create mode 100644 src/script.rs create mode 100644 src/ui/colon_prompt.rs create mode 100644 src/ui/input.rs create mode 100644 src/ui/keybinds.rs diff --git a/Cargo.lock b/Cargo.lock index e3387ec..4653771 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,6 +6,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217" + [[package]] name = "aho-corasick" version = "0.7.15" @@ -30,6 +36,15 @@ version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" +[[package]] +name = "archery" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d308d8fa3f687f7a7588fccc4812ed6914be09518232f00454693a7417273ad2" +dependencies = [ + "static_assertions", +] + [[package]] name = "arrayref" version = "0.3.6" @@ -42,6 +57,15 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "ascii-canvas" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff8eb72df928aafb99fe5d37b383f2fe25bd2a765e3e5f7c365916b6f2463a29" +dependencies = [ + "term", +] + [[package]] name = "assert_matches" version = "1.5.0" @@ -102,6 +126,21 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "bit-set" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitflags" version = "0.9.1" @@ -170,6 +209,12 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" +[[package]] +name = "bytes" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" + [[package]] name = "bytes" version = "1.0.1" @@ -201,7 +246,7 @@ dependencies = [ "clap", "core-foundation", "crates-io", - "crossbeam-utils", + "crossbeam-utils 0.8.3", "crypto-hash", "curl", "curl-sys", @@ -321,6 +366,31 @@ dependencies = [ "vec_map", ] +[[package]] +name = "codespan" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ebaf6bb6a863ad6aa3a18729e9710c53d75df03306714d9cc1f7357a00cd789" +dependencies = [ + "codespan-reporting", +] + +[[package]] +name = "codespan-reporting" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e0762455306b1ed42bc651ef6a2197aabda5e1d4a43c34d5eab5c1a3634e81d" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "collect-mac" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f168712e49987bd2f51cb855c4585999e12b1a0abdff60fea4b81b41f2010264" + [[package]] name = "colored" version = "1.9.3" @@ -411,6 +481,17 @@ dependencies = [ "cfg-if 1.0.0", ] +[[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.3" @@ -472,6 +553,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-hash" version = "0.3.4" @@ -586,6 +673,12 @@ dependencies = [ "syn 1.0.62", ] +[[package]] +name = "diff" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499" + [[package]] name = "digest" version = "0.9.0" @@ -606,6 +699,27 @@ dependencies = [ "winapi", ] +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "ena" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7402b94a93c24e742487327a7cd839dc9d36fec9de9fb25b09f2dae459f36c3" +dependencies = [ + "log", +] + [[package]] name = "enumflags2" version = "0.6.4" @@ -671,6 +785,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "fixedbitset" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" + [[package]] name = "flate2" version = "1.0.20" @@ -737,6 +857,18 @@ dependencies = [ "syn 1.0.62", ] +[[package]] +name = "frunk_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e04cda45add94e71c2990de778ae13059897d77b773130a9bc225e2970c413e" + +[[package]] +name = "futures" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" + [[package]] name = "futures" version = "0.3.13" @@ -796,7 +928,7 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite", + "pin-project-lite 0.2.6", "waker-fn", ] @@ -830,6 +962,7 @@ version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1" dependencies = [ + "futures 0.1.31", "futures-channel", "futures-core", "futures-io", @@ -837,7 +970,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite", + "pin-project-lite 0.2.6", "pin-utils", "proc-macro-hack", "proc-macro-nested", @@ -932,6 +1065,199 @@ dependencies = [ "regex", ] +[[package]] +name = "gluon" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "268e1d6205e87e79bd9d6f18f85e55d892c354395f3a00e600fc98fd4f5da584" +dependencies = [ + "async-trait", + "codespan", + "codespan-reporting", + "collect-mac", + "either", + "futures 0.3.13", + "gluon-salsa", + "gluon_base", + "gluon_check", + "gluon_codegen", + "gluon_format", + "gluon_parser", + "gluon_vm", + "itertools 0.9.0", + "log", + "quick-error", + "rand 0.7.3", + "rand_xorshift", + "regex", + "tokio 0.2.25", + "walkdir", +] + +[[package]] +name = "gluon-salsa" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4644d498c04e71e60947f837bf9729379bd922e5b745c36bea5a4ce03e551fe5" +dependencies = [ + "crossbeam-utils 0.7.2", + "futures-channel", + "futures-util", + "gluon-salsa-macros", + "indexmap", + "lock_api", + "log", + "oorandom", + "parking_lot", + "rustc-hash", + "smallvec", +] + +[[package]] +name = "gluon-salsa-macros" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "807a2b17a92e21080379cf696063642c70caea95c04b547320d37fd6844b8e0f" +dependencies = [ + "heck", + "proc-macro2", + "quote 1.0.9", + "syn 1.0.62", +] + +[[package]] +name = "gluon_base" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60e22691ead91365f5b1641eee9c21d5b794a5ff0cb6671272a844ced44e30de" +dependencies = [ + "bitflags 1.2.1", + "codespan", + "codespan-reporting", + "collect-mac", + "either", + "fnv", + "gluon_codegen", + "hashbrown 0.8.2", + "itertools 0.9.0", + "log", + "ordered-float", + "pretty", + "quick-error", + "smallvec", + "typed-arena", + "vec_map", +] + +[[package]] +name = "gluon_check" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e005ef6f8085599dc3edaa3f2ae97945312c230fd3937998816802e62216d229" +dependencies = [ + "codespan", + "codespan-reporting", + "collect-mac", + "ena", + "gluon_base", + "gluon_codegen", + "itertools 0.9.0", + "log", + "pretty", + "quick-error", + "rpds", + "smallvec", + "strsim 0.10.0", +] + +[[package]] +name = "gluon_codegen" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ad77fad378e1a0156134c1fefdc8692cdb31ffa6c5bf40e30bed8aee1de53a2" +dependencies = [ + "proc-macro2", + "quote 1.0.9", + "syn 1.0.62", +] + +[[package]] +name = "gluon_format" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dda2b7cece2002340bcd47de0b945019c4030f40a9d4a10ebe3a65d0d4319fb1" +dependencies = [ + "codespan", + "gluon_base", + "itertools 0.9.0", + "log", + "pretty", +] + +[[package]] +name = "gluon_parser" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8060f7e81f98391ecc7d045923be48f1d06235f3500bc359b59b3220086cb6c4" +dependencies = [ + "codespan", + "codespan-reporting", + "collect-mac", + "gluon_base", + "itertools 0.9.0", + "lalrpop", + "lalrpop-util", + "log", + "ordered-float", + "quick-error", +] + +[[package]] +name = "gluon_vm" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14bed68cb204682626f56a4728759fc1feb7fd9b3af3173496b70e8bd690a8ef" +dependencies = [ + "async-trait", + "bitflags 1.2.1", + "codespan", + "codespan-reporting", + "collect-mac", + "crossbeam-utils 0.7.2", + "downcast-rs", + "frunk_core", + "futures 0.3.13", + "gluon_base", + "gluon_check", + "gluon_codegen", + "itertools 0.9.0", + "log", + "ordered-float", + "parking_lot", + "petgraph", + "pretty", + "quick-error", + "slab", + "smallvec", + "typed-arena", +] + +[[package]] +name = "hashbrown" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25" +dependencies = [ + "ahash", + "autocfg", +] + +[[package]] +name = "hashbrown" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" + [[package]] name = "heck" version = "0.3.2" @@ -1000,7 +1326,7 @@ version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b287fb45c60bb826a0dc68ff08742b9d88a2fea13d6e0c286b3172065aaf878c" dependencies = [ - "crossbeam-utils", + "crossbeam-utils 0.8.3", "globset", "lazy_static", "log", @@ -1026,6 +1352,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "indexmap" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" +dependencies = [ + "autocfg", + "hashbrown 0.9.1", +] + [[package]] name = "inotify" version = "0.9.2" @@ -1036,7 +1372,7 @@ dependencies = [ "futures-core", "inotify-sys", "libc", - "tokio", + "tokio 1.2.0", ] [[package]] @@ -1057,6 +1393,24 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "itertools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.7" @@ -1081,6 +1435,38 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lalrpop" +version = "0.19.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46962a8c71b91c3524b117dfdd70844d4265a173c4c9109f98171aebdcf1195f" +dependencies = [ + "ascii-canvas", + "atty", + "bit-set", + "diff", + "ena", + "itertools 0.10.0", + "lalrpop-util", + "petgraph", + "pico-args", + "regex", + "regex-syntax", + "string_cache", + "term", + "tiny-keccak", + "unicode-xid 0.2.1", +] + +[[package]] +name = "lalrpop-util" +version = "0.19.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a708007b751af124d09e9c5d97515257902bc6b486a56b40bcafd939e8ff467" +dependencies = [ + "regex", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -1249,6 +1635,12 @@ dependencies = [ "socket2", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + [[package]] name = "nix" version = "0.17.0" @@ -1349,6 +1741,12 @@ version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + [[package]] name = "opaque-debug" version = "0.3.0" @@ -1397,6 +1795,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "ordered-float" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "766f840da25490628d8e63e529cd21c014f6600c6b8517add12a6fa6167a6218" +dependencies = [ + "num-traits", +] + [[package]] name = "panorama" version = "0.0.1" @@ -1407,9 +1814,11 @@ dependencies = [ "chrono", "chrono-humanize", "crossterm 0.19.0", + "downcast-rs", "fern", "format-bytes", - "futures", + "futures 0.3.13", + "gluon", "inotify", "log", "notify-rust", @@ -1418,7 +1827,7 @@ dependencies = [ "parking_lot", "serde", "structopt", - "tokio", + "tokio 1.2.0", "tokio-rustls", "tokio-stream", "tokio-util", @@ -1435,15 +1844,15 @@ dependencies = [ "anyhow", "assert_matches", "async-trait", - "bytes", + "bytes 1.0.1", "chrono", "derive_builder", - "futures", + "futures 0.3.13", "log", "parking_lot", "pest", "pest_derive", - "tokio", + "tokio 1.2.0", "tokio-rustls", "tokio-util", "webpki-roots", @@ -1531,6 +1940,37 @@ dependencies = [ "sha-1", ] +[[package]] +name = "petgraph" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pico-args" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d70072c20945e1ab871c472a285fc772aefd4f5407723c206242f2c6f94595d6" + +[[package]] +name = "pin-project-lite" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" + [[package]] name = "pin-project-lite" version = "0.2.6" @@ -1568,6 +2008,22 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "pretty" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad9940b913ee56ddd94aec2d3cd179dd47068236f42a1a6415ccf9d880ce2a61" +dependencies = [ + "arrayvec", + "typed-arena", +] + [[package]] name = "proc-macro-crate" version = "0.1.5" @@ -1622,6 +2078,12 @@ dependencies = [ "unicode-xid 0.2.1", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "0.3.15" @@ -1637,6 +2099,19 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", +] + [[package]] name = "rand" version = "0.8.3" @@ -1644,9 +2119,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" dependencies = [ "libc", - "rand_chacha", + "rand_chacha 0.3.0", "rand_core 0.6.2", - "rand_hc", + "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]] @@ -1664,6 +2149,9 @@ name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] [[package]] name = "rand_core" @@ -1674,6 +2162,15 @@ dependencies = [ "getrandom 0.2.2", ] +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + [[package]] name = "rand_hc" version = "0.3.0" @@ -1683,6 +2180,15 @@ dependencies = [ "rand_core 0.6.2", ] +[[package]] +name = "rand_xorshift" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8" +dependencies = [ + "rand_core 0.5.1", +] + [[package]] name = "rand_xoshiro" version = "0.4.0" @@ -1760,6 +2266,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "rpds" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1196a0a2f52d343bd32179834273eaac7d8739f7e3f8b700227d2fa06b9a423b" +dependencies = [ + "archery", +] + [[package]] name = "rust-argon2" version = "0.8.3" @@ -1769,9 +2284,15 @@ dependencies = [ "base64", "blake2b_simd", "constant_time_eq", - "crossbeam-utils", + "crossbeam-utils 0.8.3", ] +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc-workspace-hack" version = "1.0.0" @@ -1956,6 +2477,12 @@ dependencies = [ "libc", ] +[[package]] +name = "siphasher" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7" + [[package]] name = "sized-chunks" version = "0.6.4" @@ -1995,6 +2522,24 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "static_assertions" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3" + +[[package]] +name = "string_cache" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ddb1139b5353f96e429e1a5e19fbaf663bddedaa06d1dbd49f82e352601209a" +dependencies = [ + "lazy_static", + "new_debug_unreachable", + "phf_shared", + "precomputed-hash", +] + [[package]] name = "strip-ansi-escapes" version = "0.1.0" @@ -2016,6 +2561,12 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "structopt" version = "0.3.21" @@ -2105,12 +2656,23 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ "cfg-if 1.0.0", "libc", - "rand", + "rand 0.8.3", "redox_syscall 0.2.5", "remove_dir_all", "winapi", ] +[[package]] +name = "term" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" +dependencies = [ + "byteorder", + "dirs", + "winapi", +] + [[package]] name = "termcolor" version = "1.1.2" @@ -2149,6 +2711,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "tinyvec" version = "1.1.1" @@ -2164,6 +2735,19 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +[[package]] +name = "tokio" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" +dependencies = [ + "bytes 0.5.6", + "fnv", + "futures-core", + "pin-project-lite 0.1.12", + "slab", +] + [[package]] name = "tokio" version = "1.2.0" @@ -2171,14 +2755,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8190d04c665ea9e6b6a0dc45523ade572c088d2e6566244c1122671dbf4ae3a" dependencies = [ "autocfg", - "bytes", + "bytes 1.0.1", "libc", "memchr", "mio", "num_cpus", "once_cell", "parking_lot", - "pin-project-lite", + "pin-project-lite 0.2.6", "signal-hook-registry", "tokio-macros", "winapi", @@ -2202,7 +2786,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" dependencies = [ "rustls", - "tokio", + "tokio 1.2.0", "webpki", ] @@ -2213,8 +2797,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1981ad97df782ab506a1f43bf82c967326960d278acf3bf8279809648c3ff3ea" dependencies = [ "futures-core", - "pin-project-lite", - "tokio", + "pin-project-lite 0.2.6", + "tokio 1.2.0", "tokio-util", ] @@ -2224,14 +2808,14 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebb7cb2f00c5ae8df755b252306272cd1790d39728363936e01827e11f0b017b" dependencies = [ - "bytes", + "bytes 1.0.1", "futures-core", "futures-io", "futures-sink", "log", - "pin-project-lite", + "pin-project-lite 0.2.6", "slab", - "tokio", + "tokio 1.2.0", ] [[package]] @@ -2256,6 +2840,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "typed-arena" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae" + [[package]] name = "typenum" version = "1.12.0" @@ -2573,7 +3163,7 @@ dependencies = [ "derivative", "enumflags2", "fastrand", - "futures", + "futures 0.3.13", "nb-connect", "nix", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index eddec5a..cc322ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,19 +12,20 @@ license = "GPL-3.0-or-later" members = ["imap", "smtp"] [dependencies] -crossterm = "0.19.0" anyhow = "1.0.38" async-trait = "0.1.48" cfg-if = "1.0.0" chrono = "0.4.19" +chrono-humanize = "0.1.2" +crossterm = "0.19.0" fern = { version = "0.6.0", features = ["colored"] } format-bytes = "0.2.2" futures = "0.3.13" +gluon = "0.17.2" inotify = { version = "0.9.2", features = ["stream"] } log = "0.4.14" notify-rust = { version = "4.3.0", default-features = false, features = ["z"] } parking_lot = "0.11.1" -# pgp = "0.7.1" serde = { version = "1.0.124", features = ["derive"] } structopt = "0.3.21" tokio = { version = "1.2.0", features = ["full"] } @@ -35,7 +36,7 @@ toml = "0.5.8" tui = { version = "0.14.0", default-features = false, features = ["crossterm"] } webpki-roots = "0.21.0" xdg = "2.2.0" -chrono-humanize = "0.1.2" +downcast-rs = "1.2.0" [dependencies.panorama-imap] path = "imap" diff --git a/imap/src/lib.rs b/imap/src/lib.rs index edb58d5..119f681 100644 --- a/imap/src/lib.rs +++ b/imap/src/lib.rs @@ -24,10 +24,3 @@ pub mod codec; pub mod command; pub mod parser; pub mod response; - -// pub mod builders; -// pub mod oldparser; -// pub mod types; - -// pub use crate::oldparser::ParseResult; -// pub use crate::types::*; diff --git a/src/lib.rs b/src/lib.rs index e231bc0..7f84cf2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,7 @@ extern crate log; pub mod config; pub mod mail; +pub mod script; pub mod ui; /// A cloneable type that allows sending an exit-"signal" to stop the application. diff --git a/src/script.rs b/src/script.rs new file mode 100644 index 0000000..e8b4e0c --- /dev/null +++ b/src/script.rs @@ -0,0 +1,11 @@ +//! Everything dealing with scripting + +use anyhow::Result; +use gluon::{import::add_extern_module, ThreadExt}; + +/// Creates a VM for running scripts +pub async fn create_script_vm() -> Result<()> { + let vm = gluon::new_vm_async().await; + + Ok(()) +} diff --git a/src/ui/colon_prompt.rs b/src/ui/colon_prompt.rs new file mode 100644 index 0000000..00155fb --- /dev/null +++ b/src/ui/colon_prompt.rs @@ -0,0 +1,47 @@ +use anyhow::Result; +use crossterm::event::{KeyCode, KeyEvent}; + +use super::input::{HandlesInput, InputResult}; +use super::TermType; + +#[derive(Clone, Default, Debug)] +pub struct ColonPrompt { + pub value: String, +} + +impl ColonPrompt { + pub fn init(term: TermType) -> Self { + let s = term.size().unwrap(); + term.set_cursor(1, s.height - 1); + term.show_cursor(); + ColonPrompt::default() + } +} + +impl Drop for ColonPrompt { + fn drop(&mut self) {} +} + +impl HandlesInput for ColonPrompt { + fn handle_key(&mut self, term: TermType, evt: KeyEvent) -> Result { + let KeyEvent { code, .. } = evt; + match code { + KeyCode::Esc => return Ok(InputResult::Pop), + // KeyCode::Char('q') => return Ok(InputResult::Pop), + KeyCode::Char(c) => { + let mut b = [0; 2]; + self.value += c.encode_utf8(&mut b); + } + KeyCode::Backspace => { + let mut new_len = self.value.len(); + if new_len > 0 { + new_len -= 1; + } + self.value.truncate(new_len); + } + _ => {} + } + + Ok(InputResult::Ok) + } +} diff --git a/src/ui/input.rs b/src/ui/input.rs new file mode 100644 index 0000000..b0962ea --- /dev/null +++ b/src/ui/input.rs @@ -0,0 +1,54 @@ +use std::any::Any; +use std::fmt::Debug; +use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, +}; + +use anyhow::Result; +use crossterm::event::{self, Event, KeyCode, KeyEvent}; +use downcast_rs::Downcast; + +use super::colon_prompt::ColonPrompt; +use super::TermType; + +pub trait HandlesInput: Any + Debug + Downcast { + fn handle_key(&mut self, term: TermType, evt: KeyEvent) -> Result { + Ok(InputResult::Ok) + } +} + +downcast_rs::impl_downcast!(HandlesInput); + +pub enum InputResult { + Ok, + + /// Push a new state + Push(Box), + + /// Pops a state from the stack + Pop, +} + +#[derive(Debug)] +pub struct BaseInputHandler(pub Arc); + +impl HandlesInput for BaseInputHandler { + fn handle_key(&mut self, term: TermType, evt: KeyEvent) -> Result { + let KeyEvent { code, .. } = evt; + match code { + KeyCode::Char('q') => self.0.store(true, Ordering::Relaxed), + KeyCode::Char(':') => { + let colon_prompt = Box::new(ColonPrompt::init(term)); + return Ok(InputResult::Push(colon_prompt)); + // let rect = term.size()?; + // term.set_cursor(1, rect.height - 1)?; + // term.show_cursor()?; + // colon_prompt = Some(ColonPrompt::default()); + } + _ => {} + } + + Ok(InputResult::Ok) + } +} diff --git a/src/ui/keybinds.rs b/src/ui/keybinds.rs new file mode 100644 index 0000000..ab07d49 --- /dev/null +++ b/src/ui/keybinds.rs @@ -0,0 +1 @@ +pub struct Keybinds {} diff --git a/src/ui/mod.rs b/src/ui/mod.rs index d602771..83d4348 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1,9 +1,17 @@ //! UI library +mod colon_prompt; +mod input; +mod keybinds; mod mail_tab; +use std::any::Any; use std::io::Stdout; use std::mem; +use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, +}; use std::time::Duration; use anyhow::Result; @@ -13,6 +21,7 @@ use crossterm::{ event::{self, Event, KeyCode, KeyEvent}, style, terminal, }; +use downcast_rs::Downcast; use futures::{future::FutureExt, select, stream::StreamExt}; use panorama_imap::response::{AttributeValue, Envelope}; use tokio::{sync::mpsc, time}; @@ -20,16 +29,19 @@ use tui::{ backend::CrosstermBackend, layout::{Constraint, Direction, Layout}, style::{Color, Modifier, Style}, - text::Spans, + text::{Span, Spans}, widgets::*, Frame, Terminal, }; use crate::mail::MailEvent; +use self::colon_prompt::ColonPrompt; +use self::input::{BaseInputHandler, HandlesInput, InputResult}; use self::mail_tab::{EmailMetadata, MailTabState}; pub(crate) type FrameType<'a, 'b> = Frame<'a, CrosstermBackend<&'b mut Stdout>>; +pub(crate) type TermType<'a, 'b> = &'b mut Terminal>; const FRAME_DURATION: Duration = Duration::from_millis(17); @@ -44,10 +56,14 @@ pub async fn run_ui( let backend = CrosstermBackend::new(&mut stdout); let mut term = Terminal::new(backend)?; - let mut mail_tab = MailTabState::default(); - loop { + // state stack for handling inputs + let should_exit = Arc::new(AtomicBool::new(false)); + let mut input_states: Vec> = + vec![Box::new(BaseInputHandler(should_exit.clone()))]; + + while !should_exit.load(Ordering::Relaxed) { term.draw(|f| { let chunks = Layout::default() .direction(Direction::Vertical) @@ -64,25 +80,71 @@ pub async fn run_ui( let tabs = Tabs::new(titles); f.render_widget(tabs, chunks[0]); + // this is the main mail tab mail_tab.render(f, chunks[1]); - let status = Paragraph::new("hellosu"); - f.render_widget(status, chunks[2]); + // this is the status bar + if let Some(last_state) = input_states.last() { + let downcasted = last_state.downcast_ref::(); + match downcasted { + Some(colon_prompt) => { + let status = Block::default().title(vec![ + Span::styled(":", Style::default().fg(Color::Gray)), + Span::raw(&colon_prompt.value), + ]); + f.render_widget(status, chunks[2]); + f.set_cursor(colon_prompt.value.len() as u16 + 1, chunks[2].y); + } + None => { + let status = Paragraph::new("hellosu"); + f.render_widget(status, chunks[2]); + } + }; + } })?; let event = if event::poll(FRAME_DURATION)? { let event = event::read()?; // table.update(&event); - if let Event::Key(KeyEvent { code, .. }) = event { - match code { - KeyCode::Char('q') => break, - KeyCode::Char('j') => mail_tab.move_down(), - KeyCode::Char('k') => mail_tab.move_up(), - _ => {} + if let Event::Key(evt) = event { + // handle states in the state stack + // although this is written in a for loop, every case except one should break + let mut should_pop = false; + for input_state in input_states.iter_mut().rev() { + match input_state.handle_key(&mut term, evt)? { + InputResult::Ok => break, + InputResult::Push(state) => { + input_states.push(state); + break; + } + InputResult::Pop => { + should_pop = true; + break; + } + } + } + + if should_pop { + input_states.pop(); } } + // if let Event::Key(KeyEvent { code, .. }) = event { + // match code { + // // KeyCode::Char('q') => break, + // KeyCode::Char('j') => mail_tab.move_down(), + // KeyCode::Char('k') => mail_tab.move_up(), + // KeyCode::Char(':') => { + // let rect = term.size()?; + // term.set_cursor(1, rect.height - 1)?; + // term.show_cursor()?; + // colon_prompt = Some(ColonPrompt::default()); + // } + // _ => {} + // } + // } + Some(event) } else { None @@ -95,15 +157,9 @@ pub async fn run_ui( let mail_evt = mail_evt.unwrap(); match mail_evt { - MailEvent::FolderList(new_folders) => { - mail_tab.folders = new_folders; - } - MailEvent::MessageList(new_messages) => { - mail_tab.messages = new_messages; - } - MailEvent::MessageUids(new_uids) => { - mail_tab.message_uids = new_uids; - } + MailEvent::FolderList(new_folders) => mail_tab.folders = new_folders, + MailEvent::MessageList(new_messages) => mail_tab.messages = new_messages, + MailEvent::MessageUids(new_uids) => mail_tab.message_uids = new_uids, MailEvent::UpdateUid(_, attrs) => { let mut uid = None;