From 1a0753367e21fdd081eb1adda35606dabd39d5bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20=C2=B7=20Misaki=20Masa?= Date: Sun, 12 Nov 2023 03:31:21 +0800 Subject: [PATCH] fix: Rust panics instead of returning an error when file times are invalid (#357) --- Cargo.lock | 68 ++++++++++++++++++----- yazi-core/src/completion/commands/show.rs | 2 +- yazi-fm/Cargo.toml | 1 + yazi-fm/src/app.rs | 13 ++++- yazi-fm/src/main.rs | 2 + yazi-fm/src/panic.rs | 17 ++++++ yazi-shared/src/cha.rs | 3 +- yazi-shared/src/term/term.rs | 42 +++++++++----- 8 files changed, 113 insertions(+), 35 deletions(-) create mode 100644 yazi-fm/src/panic.rs diff --git a/Cargo.lock b/Cargo.lock index c4749290..ae0e4a53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,7 +105,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]] @@ -115,7 +115,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -162,6 +162,16 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +[[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 = "bincode" version = "1.3.3" @@ -267,9 +277,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.7" +version = "4.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64" dependencies = [ "clap_builder", "clap_derive", @@ -277,9 +287,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.7" +version = "4.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc" dependencies = [ "anstream", "anstyle", @@ -366,6 +376,18 @@ dependencies = [ "crossbeam-utils", ] +[[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" @@ -503,7 +525,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -512,6 +534,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 = "equivalent" version = "1.0.1" @@ -534,7 +562,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -597,7 +625,7 @@ dependencies = [ "cfg-if", "libc", "redox_syscall 0.3.5", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -812,7 +840,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]] @@ -1109,7 +1137,7 @@ dependencies = [ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1166,7 +1194,7 @@ dependencies = [ "log", "mio", "walkdir", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1556,7 +1584,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1727,7 +1755,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1916,7 +1944,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2307,6 +2335,15 @@ dependencies = [ "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]] name = "windows-sys" version = "0.48.0" @@ -2513,6 +2550,7 @@ version = "0.1.5" dependencies = [ "ansi-to-tui", "anyhow", + "better-panic", "crossterm", "fdlimit", "futures", diff --git a/yazi-core/src/completion/commands/show.rs b/yazi-core/src/completion/commands/show.rs index e65ab28f..102df4bf 100644 --- a/yazi-core/src/completion/commands/show.rs +++ b/yazi-core/src/completion/commands/show.rs @@ -25,7 +25,7 @@ impl<'a> From<&'a Exec> for Opt<'a> { } impl Completion { - fn match_candidates(word: &str, cache: &Vec) -> Vec { + fn match_candidates(word: &str, cache: &[String]) -> Vec { let flow = cache.iter().try_fold( (Vec::with_capacity(LIMIT), Vec::with_capacity(LIMIT)), |(mut prefixed, mut fuzzy), s| { diff --git a/yazi-fm/Cargo.toml b/yazi-fm/Cargo.toml index b3fc37e3..55ab098c 100644 --- a/yazi-fm/Cargo.toml +++ b/yazi-fm/Cargo.toml @@ -18,6 +18,7 @@ yazi-shared = { path = "../yazi-shared", version = "0.1.5" } # External dependencies ansi-to-tui = "^3" anyhow = "^1" +better-panic = "^0" crossterm = { version = "^0", features = [ "event-stream" ] } fdlimit = "^0" futures = "^0" diff --git a/yazi-fm/src/app.rs b/yazi-fm/src/app.rs index a0b4759f..843cdc77 100644 --- a/yazi-fm/src/app.rs +++ b/yazi-fm/src/app.rs @@ -2,12 +2,13 @@ use std::ffi::OsString; use anyhow::{Ok, Result}; use crossterm::event::KeyEvent; +use ratatui::prelude::Rect; use tokio::sync::oneshot; use yazi_config::{keymap::{Exec, Key, KeymapLayer}, BOOT}; use yazi_core::{emit, files::FilesOp, input::InputMode, Ctx, Event}; use yazi_shared::Term; -use crate::{Executor, Logs, Root, Signals}; +use crate::{Executor, Logs, Panic, Root, Signals}; pub(super) struct App { cx: Ctx, @@ -17,6 +18,7 @@ pub(super) struct App { impl App { pub(super) async fn run() -> Result<()> { + Panic::install(); let _log = Logs::init()?; let term = Term::start()?; @@ -32,7 +34,7 @@ impl App { Event::Key(key) => app.dispatch_key(key), Event::Paste(str) => app.dispatch_paste(str), Event::Render(_) => app.dispatch_render(), - Event::Resize(..) => app.dispatch_resize(), + Event::Resize(cols, rows) => app.dispatch_resize(cols, rows), Event::Stop(state, tx) => app.dispatch_stop(state, tx), Event::Call(exec, layer) => app.dispatch_call(exec, layer), event => app.dispatch_module(event), @@ -55,6 +57,7 @@ impl App { std::fs::write(p, cwd.as_bytes()).ok(); } } + Term::goodbye(|| false).unwrap(); } fn dispatch_key(&mut self, key: KeyEvent) { @@ -87,7 +90,11 @@ impl App { } } - fn dispatch_resize(&mut self) { + fn dispatch_resize(&mut self, cols: u16, rows: u16) { + if let Some(term) = &mut self.term { + term.resize(Rect::new(0, 0, cols, rows)).ok(); + } + self.cx.manager.current_mut().set_page(true); self.cx.manager.active_mut().preview.reset(|_| true); self.cx.manager.peek(true, self.cx.image_layer()); diff --git a/yazi-fm/src/main.rs b/yazi-fm/src/main.rs index 3ac38515..dcf86b74 100644 --- a/yazi-fm/src/main.rs +++ b/yazi-fm/src/main.rs @@ -6,6 +6,7 @@ mod executor; mod help; mod input; mod logs; +mod panic; mod root; mod select; mod signals; @@ -15,6 +16,7 @@ mod which; use app::*; use executor::*; use logs::*; +use panic::*; use root::*; use signals::*; diff --git a/yazi-fm/src/panic.rs b/yazi-fm/src/panic.rs new file mode 100644 index 00000000..dc870f6f --- /dev/null +++ b/yazi-fm/src/panic.rs @@ -0,0 +1,17 @@ +use yazi_shared::Term; + +pub(super) struct Panic; + +impl Panic { + pub(super) fn install() { + better_panic::install(); + + let hook = std::panic::take_hook(); + std::panic::set_hook(Box::new(move |info| { + _ = Term::goodbye(|| { + hook(info); + true + }); + })); + } +} diff --git a/yazi-shared/src/cha.rs b/yazi-shared/src/cha.rs index e2170598..e15e6469 100644 --- a/yazi-shared/src/cha.rs +++ b/yazi-shared/src/cha.rs @@ -57,7 +57,8 @@ impl From for Cha { meta: cm, len: m.len(), accessed: m.accessed().ok(), - created: m.created().ok(), + // TODO: remove this once https://github.com/rust-lang/rust/issues/108277 is fixed. + created: None, modified: m.modified().ok(), #[cfg(unix)] diff --git a/yazi-shared/src/term/term.rs b/yazi-shared/src/term/term.rs index a37aa207..1098c4b1 100644 --- a/yazi-shared/src/term/term.rs +++ b/yazi-shared/src/term/term.rs @@ -32,6 +32,32 @@ impl Term { Ok(term) } + fn stop(&mut self) -> Result<()> { + if self.csi_u { + execute!(stdout(), PopKeyboardEnhancementFlags)?; + } + + execute!(stdout(), DisableFocusChange, DisableBracketedPaste, LeaveAlternateScreen)?; + + Self::set_cursor_default()?; + self.show_cursor()?; + Ok(disable_raw_mode()?) + } + + pub fn goodbye(f: impl FnOnce() -> bool) -> Result<()> { + execute!( + stdout(), + PopKeyboardEnhancementFlags, + DisableFocusChange, + DisableBracketedPaste, + LeaveAlternateScreen, + crossterm::cursor::SetCursorStyle::DefaultUserShape, + crossterm::cursor::Show, + )?; + disable_raw_mode()?; + std::process::exit(f() as i32); + } + pub fn size() -> WindowSize { let mut size = WindowSize { rows: 0, columns: 0, width: 0, height: 0 }; if let Ok(s) = crossterm::terminal::window_size() { @@ -69,21 +95,7 @@ impl Term { } impl Drop for Term { - fn drop(&mut self) { - let mut f = || -> Result<()> { - if self.csi_u { - execute!(stdout(), PopKeyboardEnhancementFlags)?; - } - - execute!(stdout(), DisableFocusChange, DisableBracketedPaste, LeaveAlternateScreen)?; - - Self::set_cursor_default()?; - self.show_cursor()?; - Ok(disable_raw_mode()?) - }; - - f().ok(); - } + fn drop(&mut self) { self.stop().ok(); } } impl Deref for Term {