diff --git a/Cargo.lock b/Cargo.lock index fd09daaa..b5a64cd6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,7 +76,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -86,7 +86,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -116,6 +116,16 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "better-panic" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fa9e1d11a268684cbd90ed36370d7577afb6c62d912ddff5c15fc34343e5036" +dependencies = [ + "backtrace", + "console", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -137,12 +147,6 @@ version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - [[package]] name = "bytes" version = "1.4.0" @@ -182,7 +186,7 @@ dependencies = [ "num-traits", "time", "wasm-bindgen", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -261,6 +265,7 @@ dependencies = [ "once_cell", "owo-colors", "tracing-error", + "url", ] [[package]] @@ -281,6 +286,18 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "console" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "windows-sys 0.45.0", +] + [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -413,7 +430,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -422,6 +439,12 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "endian-type" version = "0.1.2" @@ -442,7 +465,7 @@ checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" dependencies = [ "errno-dragonfly", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -483,7 +506,7 @@ checksum = "ef033ed5e9bad94e55838ca0ca906db0e043f517adda0c8b79c7a8c66c93c1b5" dependencies = [ "cfg-if", "rustix 0.38.8", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -506,6 +529,15 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + [[package]] name = "futures" version = "0.3.28" @@ -595,15 +627,6 @@ dependencies = [ "slab", ] -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - [[package]] name = "getrandom" version = "0.2.10" @@ -645,7 +668,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -693,6 +716,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "indenter" version = "0.3.3" @@ -729,7 +762,7 @@ checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -835,7 +868,7 @@ dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -962,7 +995,7 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -1000,6 +1033,12 @@ dependencies = [ "syn 2.0.29", ] +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + [[package]] name = "pin-project-lite" version = "0.2.12" @@ -1099,20 +1138,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "ratatui" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8285baa38bdc9f879d92c0e37cb562ef38aa3aeefca22b3200186bc39242d3d5" -dependencies = [ - "bitflags 2.4.0", - "cassowary", - "indoc", - "paste", - "unicode-segmentation", - "unicode-width", -] - [[package]] name = "ratatui" version = "0.23.0" @@ -1220,7 +1245,7 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys 0.3.8", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1233,7 +1258,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.5", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1405,7 +1430,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1498,6 +1523,7 @@ dependencies = [ name = "taskwarrior-tui" version = "0.25.4" dependencies = [ + "better-panic", "cassowary", "chrono", "clap", @@ -1515,7 +1541,7 @@ dependencies = [ "path-clean", "pretty_assertions", "rand", - "ratatui 0.23.0", + "ratatui", "regex", "rustyline", "serde", @@ -1533,7 +1559,6 @@ dependencies = [ "tracing-error", "tracing-subscriber", "tui-input", - "tui-logger", "unicode-segmentation", "unicode-truncate", "unicode-width", @@ -1548,7 +1573,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" dependencies = [ "rustix 0.37.23", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1592,6 +1617,21 @@ dependencies = [ "winapi", ] +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.32.0" @@ -1608,7 +1648,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1751,22 +1791,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "tui-logger" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9b303440de7c259d03e113a808f2f8ca3cd9097840663dc484b12f19c6f44a6" -dependencies = [ - "chrono", - "fxhash", - "lazy_static", - "log", - "parking_lot", - "ratatui 0.22.0", - "tracing", - "tracing-subscriber", -] - [[package]] name = "uncased" version = "0.9.9" @@ -1785,12 +1809,27 @@ dependencies = [ "version_check", ] +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + [[package]] name = "unicode-ident" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-segmentation" version = "1.10.1" @@ -1812,6 +1851,17 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "utf8parse" version = "0.2.1" @@ -1964,7 +2014,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", ] [[package]] @@ -1973,7 +2032,22 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -1982,51 +2056,93 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 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", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" diff --git a/Cargo.toml b/Cargo.toml index 584246d4..4012fd92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,10 +13,11 @@ categories = ["command-line-utilities"] [dependencies] +better-panic = "0.3.0" cassowary = "0.3.0" chrono = "0.4.28" clap = { version = "4.4.2", features = ["std", "color", "help", "usage", "error-context", "suggestions", "derive", "cargo", "wrap_help", "unicode", "string", "unstable-styles"] } -color-eyre = "0.6.2" +color-eyre = { version = "0.6.2", features = ["issue-url"] } crossterm = { version = "0.27.0", features = ["event-stream", "serde"] } directories = "5.0.1" figment = { version = "0.10.10", features = ["toml", "env"] } @@ -47,7 +48,6 @@ tracing = "0.1.37" tracing-error = "0.2.0" tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } tui-input = "0.8.0" -tui-logger = { version = "0.9.5", default-features = false, features = ["ratatui-support", "tracing-support"] } unicode-segmentation = "1.10.1" unicode-truncate = "0.2.0" unicode-width = "0.1.10" diff --git a/src/app.rs b/src/app.rs index f03503bc..950fee42 100644 --- a/src/app.rs +++ b/src/app.rs @@ -330,7 +330,8 @@ impl TaskwarriorTui { } pub async fn run(&mut self) -> Result<()> { - let mut tui = tui::Tui::new(self.tick_rate as usize)?; + let mut tui = tui::Tui::new()?; + tui.tick_rate((self.tick_rate as usize, self.tick_rate as usize)); tui.enter()?; let mut events: Vec = Vec::new(); @@ -342,9 +343,7 @@ impl TaskwarriorTui { tui.resize(s)?; self.requires_redraw = false; } - tui.draw(|f| self.draw(f))?; if let Some(event) = tui.next().await { - trace_dbg!(event); let mut maybe_action = match event { Event::Quit => Some(Action::Quit), Event::Error => Some(Action::Error("Received event error".into())), @@ -359,6 +358,13 @@ impl TaskwarriorTui { } Event::Mouse(_) => None, Event::Resize(x, y) => None, + Event::Render => { + tui.draw(|f| self.draw(f))?; + None + } + Event::FocusGained => None, + Event::FocusLost => None, + Event::Paste(s) => None, }; while let Some(action) = maybe_action { maybe_action = self.update(action)?; diff --git a/src/main.rs b/src/main.rs index ad60a853..cd9ece41 100644 --- a/src/main.rs +++ b/src/main.rs @@ -92,7 +92,7 @@ async fn main() -> Result<()> { } } - initialize_logging(data_dir)?; + initialize_logging()?; initialize_panic_handler()?; log::info!("getting matches from clap..."); diff --git a/src/tui.rs b/src/tui.rs index 1e263036..a60a1497 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -1,4 +1,8 @@ -use std::ops::{Deref, DerefMut}; + +use std::{ + ops::{Deref, DerefMut}, + time::Duration, +}; use color_eyre::eyre::Result; use crossterm::{ @@ -15,14 +19,18 @@ use tokio::{ }; use tokio_util::sync::CancellationToken; -pub type CrosstermFrame<'a> = ratatui::Frame<'a, Backend>; +pub type Frame<'a> = ratatui::Frame<'a, Backend>; -#[derive(Clone, Copy, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub enum Event { Quit, Error, Closed, Tick, + Render, + FocusGained, + FocusLost, + Paste(String), Key(KeyEvent), Mouse(MouseEvent), Resize(u16, u16), @@ -34,36 +42,37 @@ pub struct Tui { pub cancellation_token: CancellationToken, pub event_rx: UnboundedReceiver, pub event_tx: UnboundedSender, - pub tick_rate: usize, + pub tick_rate: (usize, usize), } impl Tui { - pub fn new(tick_rate: usize) -> Result { + pub fn new() -> Result { + let tick_rate = (1000, 100); let terminal = ratatui::Terminal::new(Backend::new(std::io::stderr()))?; let (event_tx, event_rx) = mpsc::unbounded_channel(); let cancellation_token = CancellationToken::new(); let task = tokio::spawn(async {}); - Ok(Self { - terminal, - task, - cancellation_token, - event_rx, - event_tx, - tick_rate, - }) + Ok(Self { terminal, task, cancellation_token, event_rx, event_tx, tick_rate }) + } + + pub fn tick_rate(&mut self, tick_rate: (usize, usize)) { + self.tick_rate = tick_rate; } pub fn start(&mut self) { - let tick_rate = std::time::Duration::from_millis(self.tick_rate as u64); - self.cancellation_token.cancel(); + let tick_rate = std::time::Duration::from_millis(self.tick_rate.0 as u64); + let render_tick_rate = std::time::Duration::from_millis(self.tick_rate.1 as u64); + self.cancel(); self.cancellation_token = CancellationToken::new(); let _cancellation_token = self.cancellation_token.clone(); let _event_tx = self.event_tx.clone(); self.task = tokio::spawn(async move { let mut reader = crossterm::event::EventStream::new(); let mut interval = tokio::time::interval(tick_rate); + let mut render_interval = tokio::time::interval(render_tick_rate); loop { let delay = interval.tick(); + let render_delay = render_interval.tick(); let crossterm_event = reader.next().fuse(); tokio::select! { _ = _cancellation_token.cancelled() => { @@ -78,10 +87,21 @@ impl Tui { _event_tx.send(Event::Key(key)).unwrap(); } }, + CrosstermEvent::Mouse(mouse) => { + _event_tx.send(Event::Mouse(mouse)).unwrap(); + }, CrosstermEvent::Resize(x, y) => { _event_tx.send(Event::Resize(x, y)).unwrap(); }, - _ => {}, + CrosstermEvent::FocusLost => { + _event_tx.send(Event::FocusLost).unwrap(); + }, + CrosstermEvent::FocusGained => { + _event_tx.send(Event::FocusGained).unwrap(); + }, + CrosstermEvent::Paste(s) => { + _event_tx.send(Event::Paste(s)).unwrap(); + }, } } Some(Err(_)) => { @@ -93,11 +113,31 @@ impl Tui { _ = delay => { _event_tx.send(Event::Tick).unwrap(); }, + _ = render_delay => { + _event_tx.send(Event::Render).unwrap(); + }, } } }); } + pub fn stop(&self) -> Result<()> { + self.cancel(); + let mut counter = 0; + while !self.task.is_finished() { + std::thread::sleep(Duration::from_millis(1)); + counter += 1; + if counter > 50 { + self.task.abort(); + } + if counter > 100 { + log::error!("Failed to abort task in 100 milliseconds for unknown reason"); + return Err(color_eyre::eyre::eyre!("Unable to abort task")); + } + } + Ok(()) + } + pub fn enter(&mut self) -> Result<()> { crossterm::terminal::enable_raw_mode()?; crossterm::execute!(std::io::stderr(), EnterAlternateScreen, cursor::Hide)?; @@ -106,12 +146,16 @@ impl Tui { } pub fn exit(&self) -> Result<()> { + self.stop()?; crossterm::execute!(std::io::stderr(), LeaveAlternateScreen, cursor::Show)?; crossterm::terminal::disable_raw_mode()?; - self.cancellation_token.cancel(); Ok(()) } + pub fn cancel(&self) { + self.cancellation_token.cancel(); + } + pub fn suspend(&self) -> Result<()> { self.exit()?; #[cfg(not(windows))] diff --git a/src/utils.rs b/src/utils.rs index b3f00c3d..46d626aa 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -19,7 +19,7 @@ impl ChangeListener for Changeset { use std::path::{Path, PathBuf}; -use color_eyre::eyre::{anyhow, Context, Result}; +use color_eyre::eyre::Result; use directories::ProjectDirs; use lazy_static::lazy_static; use tracing::error; @@ -31,33 +31,48 @@ use tracing_subscriber::{ use crate::tui::Tui; lazy_static! { - pub static ref CRATE_NAME: String = env!("CARGO_CRATE_NAME").to_uppercase().to_string(); - pub static ref DATA_FOLDER: Option = std::env::var(format!("{}_DATA", CRATE_NAME.clone())) + pub static ref PROJECT_NAME: String = env!("CARGO_CRATE_NAME").to_uppercase().to_string(); + pub static ref DATA_FOLDER: Option = std::env::var(format!("{}_DATA", PROJECT_NAME.clone())) .ok() .map(PathBuf::from); - pub static ref CONFIG_FOLDER: Option = std::env::var(format!("{}_CONFIG", CRATE_NAME.clone())) + pub static ref CONFIG_FOLDER: Option = std::env::var(format!("{}_CONFIG", PROJECT_NAME.clone())) .ok() .map(PathBuf::from); pub static ref GIT_COMMIT_HASH: String = - std::env::var(format!("{}_GIT_INFO", CRATE_NAME.clone())).unwrap_or_else(|_| String::from("Unknown")); - pub static ref LOG_FILE: String = format!("{}.log", CRATE_NAME.to_lowercase()); + std::env::var(format!("{}_GIT_INFO", PROJECT_NAME.clone())).unwrap_or_else(|_| String::from("Unknown")); + pub static ref LOG_LEVEL: String = std::env::var(format!("{}_LOG_LEVEL", PROJECT_NAME.clone())).unwrap_or_default(); + pub static ref LOG_FILE: String = format!("{}.log", env!("CARGO_PKG_NAME").to_lowercase()); } fn project_directory() -> Option { - ProjectDirs::from("com", "kdheepak", CRATE_NAME.clone().to_lowercase().as_str()) + ProjectDirs::from("com", "kdheepak", PROJECT_NAME.clone().to_lowercase().as_str()) } pub fn initialize_panic_handler() -> Result<()> { - let (panic_hook, eyre_hook) = color_eyre::config::HookBuilder::default().into_hooks(); + let (panic_hook, eyre_hook) = color_eyre::config::HookBuilder::default() + .panic_section(format!( + "This is a bug. Consider reporting it at {}", + env!("CARGO_PKG_REPOSITORY") + )) + .display_location_section(true) + .display_env_section(true) + .issue_url(concat!(env!("CARGO_PKG_REPOSITORY"), "/issues/new")) + .add_issue_metadata("version", env!("CARGO_PKG_VERSION")) + .add_issue_metadata("os", std::env::consts::OS) + .add_issue_metadata("arch", std::env::consts::ARCH) + .into_hooks(); eyre_hook.install()?; std::panic::set_hook(Box::new(move |panic_info| { - if let Ok(t) = Tui::new(0) { + if let Ok(t) = Tui::new() { if let Err(r) = t.exit() { error!("Unable to exit Terminal: {:?}", r); } } + let msg = format!("{}", panic_hook.panic_report(panic_info)); - tracing::error!("{}", strip_ansi_escapes::strip_str(&msg)); + eprintln!("{}", msg); + log::error!("Error: {}", strip_ansi_escapes::strip_str(msg)); + use human_panic::{handle_dump, print_msg, Metadata}; let meta = Metadata { version: env!("CARGO_PKG_VERSION").into(), @@ -65,9 +80,20 @@ pub fn initialize_panic_handler() -> Result<()> { authors: env!("CARGO_PKG_AUTHORS").replace(':', ", ").into(), homepage: env!("CARGO_PKG_HOMEPAGE").into(), }; + let file_path = handle_dump(&meta, panic_info); print_msg(file_path, &meta).expect("human-panic: printing error message to console failed"); - eprintln!("{}", msg); + + // Better Panic. Only enabled *when* debugging. + #[cfg(debug_assertions)] + { + better_panic::Settings::auto() + .most_recent_first(false) + .lineno_suffix(true) + .verbosity(better_panic::Verbosity::Full) + .create_panic_handler()(panic_info); + } + std::process::exit(libc::EXIT_FAILURE); })); Ok(()) @@ -95,7 +121,8 @@ pub fn get_config_dir() -> PathBuf { directory } -pub fn initialize_logging(directory: PathBuf) -> Result<()> { +pub fn initialize_logging() -> Result<()> { + let directory = get_data_dir(); std::fs::create_dir_all(directory.clone())?; let log_path = directory.join(LOG_FILE.clone()); let log_file = std::fs::File::create(log_path)?; @@ -106,23 +133,22 @@ pub fn initialize_logging(directory: PathBuf) -> Result<()> { .with_target(false) .with_ansi(false) .with_filter(EnvFilter::from_default_env()); - tracing_subscriber::registry() .with(file_subscriber) - .with(tui_logger::tracing_subscriber_layer()) + // .with(tui_logger::tracing_subscriber_layer()) .with(ErrorLayer::default()) .init(); - let default_level = - std::env::var("RUST_LOG").map_or(log::LevelFilter::Info, |val| match val.to_lowercase().as_str() { - "off" => log::LevelFilter::Off, - "error" => log::LevelFilter::Error, - "warn" => log::LevelFilter::Warn, - "info" => log::LevelFilter::Info, - "debug" => log::LevelFilter::Debug, - "trace" => log::LevelFilter::Trace, - _ => log::LevelFilter::Info, - }); - tui_logger::set_default_level(default_level); + + // let default_level = match LOG_LEVEL.clone().to_lowercase().as_str() { + // "off" => log::LevelFilter::Off, + // "error" => log::LevelFilter::Error, + // "warn" => log::LevelFilter::Warn, + // "info" => log::LevelFilter::Info, + // "debug" => log::LevelFilter::Debug, + // "trace" => log::LevelFilter::Trace, + // _ => log::LevelFilter::Info, + // }; + // tui_logger::set_default_level(default_level); Ok(()) }