From 264cd5f94b4aa34c732691878099a0f7ee320a3d Mon Sep 17 00:00:00 2001 From: FliegendeWurst <2012gdwu+github@posteo.de> Date: Sat, 3 Apr 2021 19:52:15 +0200 Subject: [PATCH] browse: initial TUI list interface --- Cargo.lock | 336 ++++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 2 + src/bin/browse.rs | 29 +++- 3 files changed, 350 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d499b3c..9ca81ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,17 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" +[[package]] +name = "ahash" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "796540673305a66d127804eef19ad696f1f204b8c1025aaca4958c17eab32877" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "0.7.15" @@ -23,6 +34,12 @@ version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" +[[package]] +name = "array-macro" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e97b4e522f9e55523001238ac59d13a8603af57f69980de5d8de4bbbe8ada6" + [[package]] name = "arrayvec" version = "0.5.2" @@ -140,6 +157,124 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" +[[package]] +name = "crossbeam-channel" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" +dependencies = [ + "autocfg", + "cfg-if", + "lazy_static", +] + +[[package]] +name = "cursive" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6593c3409eb794bf22090bec60dda1e19d1def284478bec7e5a92da3cf977c52" +dependencies = [ + "ahash 0.6.3", + "cfg-if", + "crossbeam-channel", + "cursive_core", + "lazy_static", + "libc", + "log", + "signal-hook", + "termion", + "unicode-segmentation", + "unicode-width", + "wasmer_enumset", +] + +[[package]] +name = "cursive_core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "025ac0bcd21ced752d27b70e6aa2285a3513d07b5a0c7f89e71121d20ca1429d" +dependencies = [ + "ahash 0.6.3", + "chrono", + "crossbeam-channel", + "enum-map", + "lazy_static", + "libc", + "log", + "num", + "owning_ref", + "syn 1.0.67", + "unicode-segmentation", + "unicode-width", + "wasmer_enumset", + "xi-unicode", +] + +[[package]] +name = "cursive_tree_view" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd59affc6d600a69df27972fb5fe7f38a743aeb0710299e3324022c7d80717a0" +dependencies = [ + "cursive_core", + "debug_stub_derive", +] + +[[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 1.0.9", + "strsim", + "syn 1.0.67", +] + +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core", + "quote 1.0.9", + "syn 1.0.67", +] + +[[package]] +name = "debug_stub_derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "496b7f8a2f853313c3ca370641d7ff3e42c32974fdccda8f0684599ed0a3ff6b" +dependencies = [ + "quote 0.3.15", + "syn 0.11.11", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -182,6 +317,27 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" +[[package]] +name = "enum-map" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4187999839f4ae8be35cf185d1381aa8dc32d2f5951349cc37ae49ebc4781855" +dependencies = [ + "array-macro", + "enum-map-derive", +] + +[[package]] +name = "enum-map-derive" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5c450cf304c9e18d45db562025a14fb1ca0f5c769b6f609309f81d4c31de455" +dependencies = [ + "proc-macro2", + "quote 1.0.9", + "syn 1.0.67", +] + [[package]] name = "fallible-iterator" version = "0.2.0" @@ -200,6 +356,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "fs2" version = "0.4.3" @@ -237,7 +399,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" dependencies = [ - "ahash", + "ahash 0.4.7", ] [[package]] @@ -249,6 +411,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "imap" version = "2.4.1" @@ -280,6 +448,8 @@ dependencies = [ "anyhow", "ascii_table", "chrono", + "cursive", + "cursive_tree_view", "imap", "itertools", "maildir", @@ -473,6 +643,28 @@ dependencies = [ "version_check", ] +[[package]] +name = "num" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f" +dependencies = [ + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5" +dependencies = [ + "num-traits", +] + [[package]] name = "num-integer" version = "0.1.44" @@ -483,6 +675,28 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.14" @@ -510,6 +724,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" +[[package]] +name = "owning_ref" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ff55baddef9e4ad00f88b6c743a2a8062d4c6ade126c2a528644b8e444d52ce" +dependencies = [ + "stable_deref_trait", +] + [[package]] name = "petgraph" version = "0.5.1" @@ -532,9 +755,15 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ - "unicode-xid", + "unicode-xid 0.2.1", ] +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" + [[package]] name = "quote" version = "1.0.9" @@ -765,8 +994,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.9", + "syn 1.0.67", ] [[package]] @@ -780,6 +1009,25 @@ dependencies = [ "serde", ] +[[package]] +name = "signal-hook" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef33d6d0cd06e0840fba9985aab098c147e67e05cee14d412d3345ed14ff30ac" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" +dependencies = [ + "libc", +] + [[package]] name = "smallvec" version = "1.6.1" @@ -792,12 +1040,24 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + [[package]] name = "subprocess" version = "0.2.6" @@ -808,6 +1068,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "syn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" +dependencies = [ + "quote 0.3.15", + "synom", + "unicode-xid 0.0.4", +] + [[package]] name = "syn" version = "1.0.67" @@ -815,8 +1086,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702" dependencies = [ "proc-macro2", - "quote", - "unicode-xid", + "quote 1.0.9", + "unicode-xid 0.2.1", +] + +[[package]] +name = "synom" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +dependencies = [ + "unicode-xid 0.0.4", ] [[package]] @@ -863,6 +1143,12 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" + [[package]] name = "unicode-xid" version = "0.2.1" @@ -919,8 +1205,8 @@ dependencies = [ "lazy_static", "log", "proc-macro2", - "quote", - "syn", + "quote 1.0.9", + "syn 1.0.67", "wasm-bindgen-shared", ] @@ -930,7 +1216,7 @@ version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f" dependencies = [ - "quote", + "quote 1.0.9", "wasm-bindgen-macro-support", ] @@ -941,8 +1227,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.9", + "syn 1.0.67", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -953,6 +1239,28 @@ version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489" +[[package]] +name = "wasmer_enumset" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf088cc1f7d247fd96dff0df46fb1bbb747d8a69ae1ecd71aed55c55e354b2d8" +dependencies = [ + "num-traits", + "wasmer_enumset_derive", +] + +[[package]] +name = "wasmer_enumset_derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1b32d98e11194200baf6d3f85eb2d6cfe56f6d9af0dd617f90ca48f958a88" +dependencies = [ + "darling", + "proc-macro2", + "quote 1.0.9", + "syn 1.0.67", +] + [[package]] name = "web-sys" version = "0.3.50" @@ -994,3 +1302,9 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "xi-unicode" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a" diff --git a/Cargo.toml b/Cargo.toml index 538ee46..7ae0f79 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,3 +24,5 @@ mailproc = { git = "https://github.com/FliegendeWurst/mailproc.git", branch = "m subprocess = "0.2.6" mime2ext = "0.1.2" petgraph = "0.5.1" +cursive = { version = "0.16.3", default-features = false, features = ["termion-backend"] } +cursive_tree_view = "0.7.0" diff --git a/src/bin/browse.rs b/src/bin/browse.rs index a844831..ccb0f8d 100644 --- a/src/bin/browse.rs +++ b/src/bin/browse.rs @@ -1,5 +1,8 @@ use std::{array::IntoIter, cell::RefCell, cmp, collections::{HashMap, HashSet}, env}; +use cursive::{Cursive, CursiveExt}; +use cursive::views::{ListView, TextView}; +use cursive_tree_view::{Placement, TreeView}; use inboxid::*; use itertools::Itertools; use mailparse::ParsedMail; @@ -93,16 +96,21 @@ fn show_listing(mailbox: &str) -> Result<()> { roots.sort_unstable_by_key(|x| x.1.date); let mails_printed = RefCell::new(HashSet::new()); + let mut siv = Cursive::new(); + + let tree = RefCell::new(TreeView::new()); // recursive lambda struct PrintThread<'a> { - f: &'a dyn Fn(&PrintThread, NodeIndex, usize) + f: &'a dyn Fn(&PrintThread, NodeIndex, Placement, usize) } - let print_thread = |this: &PrintThread, node, depth| { + let print_thread = |this: &PrintThread, node, placement, parent| { let mail = nodes_inv[&node]; - if mails_printed.borrow().contains(mail) && depth == 0 { + if mails_printed.borrow().contains(mail) && placement == Placement::After { return; } - println!("{}{}", " ".repeat(depth), mail.subject); + //println!("{}{}", " ".repeat(depth), mail.subject); + let line = mail.subject.clone(); + let entry = tree.borrow_mut().insert_item(line, placement, parent); mails_printed.borrow_mut().insert(mail); let mut replies = graph.neighbors_directed(node, EdgeDirection::Outgoing).collect_vec(); replies.sort_unstable_by_key(|&idx| { @@ -115,14 +123,23 @@ fn show_listing(mailbox: &str) -> Result<()> { maximum }); for r in replies { - (this.f)(this, r, depth + 1); + (this.f)(this, r, Placement::LastChild, entry.unwrap()); } }; let print_thread = PrintThread { f: &print_thread }; + let mut x = tree.borrow().len(); for root in roots { - (print_thread.f)(&print_thread, root.0, 0); + let y = tree.borrow().len(); + (print_thread.f)(&print_thread, root.0, Placement::After, x); + x = y } + siv.add_layer(tree.into_inner()); + + siv.add_global_callback('q', |s| s.quit()); + + siv.run(); + Ok(()) }