From 2d3512e965f4bd46d7fd8310424138b0c6cbe103 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: Thu, 28 Dec 2023 03:32:39 +0800 Subject: [PATCH] fix: panic caused by `set_hook` (#459) --- yazi-fm/Cargo.toml | 7 +--- yazi-fm/src/app/app.rs | 56 +++--------------------------- yazi-fm/src/app/commands/mod.rs | 1 + yazi-fm/src/app/commands/render.rs | 51 +++++++++++++++++++++++++++ yazi-fm/src/app/commands/stop.rs | 5 +-- yazi-fm/src/help/layout.rs | 2 +- yazi-fm/src/input/input.rs | 2 +- yazi-fm/src/select/select.rs | 2 +- yazi-fm/src/tasks/layout.rs | 2 +- yazi-fm/src/which/layout.rs | 2 +- yazi-plugin/Cargo.toml | 7 +--- 11 files changed, 67 insertions(+), 70 deletions(-) create mode 100644 yazi-fm/src/app/commands/render.rs diff --git a/yazi-fm/Cargo.toml b/yazi-fm/Cargo.toml index e33abb02..7d065fd2 100644 --- a/yazi-fm/Cargo.toml +++ b/yazi-fm/Cargo.toml @@ -23,6 +23,7 @@ better-panic = "^0" crossterm = { version = "^0", features = [ "event-stream" ] } fdlimit = "^0" futures = "^0" +mlua = { version = "^0", features = [ "lua54", "vendored" ] } ratatui = "^0" tokio = { version = "^1", features = [ "parking_lot" ] } unicode-width = "^0" @@ -36,12 +37,6 @@ tracing-subscriber = "^0" libc = "^0" signal-hook-tokio = { version = "^0", features = [ "futures-v0_3" ] } -[target.'cfg(any(target_arch="riscv64", target_arch="loongarch64"))'.dependencies] -mlua = { version = "^0", features = [ "lua52", "vendored" ] } - -[target.'cfg(not(any(target_arch="riscv64", target_arch="loongarch64")))'.dependencies] -mlua = { version = "^0", features = [ "luajit52", "vendored" ] } - [[bin]] name = "yazi" path = "src/main.rs" diff --git a/yazi-fm/src/app/app.rs b/yazi-fm/src/app/app.rs index 113076bf..bb1ca4c3 100644 --- a/yazi-fm/src/app/app.rs +++ b/yazi-fm/src/app/app.rs @@ -1,13 +1,10 @@ -use std::sync::atomic::Ordering; - use anyhow::{Ok, Result}; use crossterm::event::KeyEvent; -use ratatui::backend::Backend; use yazi_config::{keymap::Key, ARGS}; use yazi_core::input::InputMode; -use yazi_shared::{emit, event::{Event, Exec}, term::Term, Layer, COLLISION}; +use yazi_shared::{emit, event::{Event, Exec}, term::Term, Layer}; -use crate::{lives::Lives, Ctx, Executor, Logs, Panic, Root, Signals}; +use crate::{lives::Lives, Ctx, Executor, Logs, Panic, Signals}; pub(crate) struct App { pub(crate) cx: Ctx, @@ -26,7 +23,7 @@ impl App { Lives::register()?; let mut app = Self { cx: Ctx::make(), term: Some(term), signals }; - app.dispatch_render()?; + app.render()?; while let Some(event) = app.signals.recv().await { match event { Event::Quit(no_cwd_file) => { @@ -35,7 +32,7 @@ impl App { } Event::Key(key) => app.dispatch_key(key), Event::Paste(str) => app.dispatch_paste(str), - Event::Render(_) => app.dispatch_render()?, + Event::Render(_) => app.render()?, Event::Resize(cols, rows) => app.dispatch_resize(cols, rows)?, Event::Call(exec, layer) => app.dispatch_call(exec, layer), event => app.dispatch_module(event), @@ -68,51 +65,9 @@ impl App { } } - fn dispatch_render(&mut self) -> Result<()> { - let Some(term) = &mut self.term else { - return Ok(()); - }; - - let collision = COLLISION.swap(false, Ordering::Relaxed); - let frame = term.draw(|f| { - Lives::scope(&self.cx, |_| { - f.render_widget(Root::new(&self.cx), f.size()); - }); - - if let Some((x, y)) = self.cx.cursor() { - f.set_cursor(x, y); - } - })?; - if !COLLISION.load(Ordering::Relaxed) { - if collision { - // Reload preview if collision is resolved - self.cx.manager.peek(true); - } - return Ok(()); - } - - let mut patches = Vec::new(); - for x in frame.area.left()..frame.area.right() { - for y in frame.area.top()..frame.area.bottom() { - let cell = frame.buffer.get(x, y); - if cell.skip { - patches.push((x, y, cell.clone())); - } - } - } - - term.backend_mut().draw(patches.iter().map(|(x, y, cell)| (*x, *y, cell)))?; - if let Some((x, y)) = self.cx.cursor() { - term.show_cursor()?; - term.set_cursor(x, y)?; - } - term.backend_mut().flush()?; - Ok(()) - } - fn dispatch_resize(&mut self, _: u16, _: u16) -> Result<()> { self.cx.manager.active_mut().preview.reset(); - self.dispatch_render()?; + self.render()?; self.cx.manager.current_mut().set_page(true); self.cx.manager.peek(false); @@ -127,7 +82,6 @@ impl App { } fn dispatch_module(&mut self, event: Event) { - let manager = &mut self.cx.manager; let tasks = &mut self.cx.tasks; match event { Event::Pages(page) => { diff --git a/yazi-fm/src/app/commands/mod.rs b/yazi-fm/src/app/commands/mod.rs index 4fddf53d..c12ef5df 100644 --- a/yazi-fm/src/app/commands/mod.rs +++ b/yazi-fm/src/app/commands/mod.rs @@ -1,2 +1,3 @@ mod plugin; +mod render; mod stop; diff --git a/yazi-fm/src/app/commands/render.rs b/yazi-fm/src/app/commands/render.rs new file mode 100644 index 00000000..02729eba --- /dev/null +++ b/yazi-fm/src/app/commands/render.rs @@ -0,0 +1,51 @@ +use std::sync::atomic::Ordering; + +use anyhow::Result; +use ratatui::backend::Backend; +use yazi_shared::COLLISION; + +use crate::{app::App, lives::Lives, root::Root}; + +impl App { + pub(crate) fn render(&mut self) -> Result<()> { + let Some(term) = &mut self.term else { + return Ok(()); + }; + + let collision = COLLISION.swap(false, Ordering::Relaxed); + let frame = term.draw(|f| { + Lives::scope(&self.cx, |_| { + f.render_widget(Root::new(&self.cx), f.size()); + }); + + if let Some((x, y)) = self.cx.cursor() { + f.set_cursor(x, y); + } + })?; + if !COLLISION.load(Ordering::Relaxed) { + if collision { + // Reload preview if collision is resolved + self.cx.manager.peek(true); + } + return Ok(()); + } + + let mut patches = Vec::new(); + for x in frame.area.left()..frame.area.right() { + for y in frame.area.top()..frame.area.bottom() { + let cell = frame.buffer.get(x, y); + if cell.skip { + patches.push((x, y, cell.clone())); + } + } + } + + term.backend_mut().draw(patches.iter().map(|(x, y, cell)| (*x, *y, cell)))?; + if let Some((x, y)) = self.cx.cursor() { + term.show_cursor()?; + term.set_cursor(x, y)?; + } + term.backend_mut().flush()?; + Ok(()) + } +} diff --git a/yazi-fm/src/app/commands/stop.rs b/yazi-fm/src/app/commands/stop.rs index e5c92bd8..dd78f85e 100644 --- a/yazi-fm/src/app/commands/stop.rs +++ b/yazi-fm/src/app/commands/stop.rs @@ -1,6 +1,6 @@ use anyhow::Result; use tokio::sync::oneshot; -use yazi_shared::{emit, event::Exec, term::Term}; +use yazi_shared::{event::Exec, term::Term}; use crate::app::App; @@ -30,9 +30,10 @@ impl App { } else { self.term = Some(Term::start().unwrap()); self.signals.stop_term(false); + // FIXME: find a better way to handle this + self.render().unwrap(); self.cx.manager.hover(None); self.cx.manager.peek(true); - emit!(Render); } if let Some(tx) = opt.tx { tx.send(()).ok(); diff --git a/yazi-fm/src/help/layout.rs b/yazi-fm/src/help/layout.rs index a34d054f..b52f0208 100644 --- a/yazi-fm/src/help/layout.rs +++ b/yazi-fm/src/help/layout.rs @@ -2,7 +2,7 @@ use ratatui::{buffer::Buffer, layout::{self, Rect}, prelude::{Constraint, Direct use yazi_config::THEME; use super::Bindings; -use crate::{Ctx, widgets}; +use crate::{widgets, Ctx}; pub(crate) struct Layout<'a> { cx: &'a Ctx, diff --git a/yazi-fm/src/input/input.rs b/yazi-fm/src/input/input.rs index 7e551bdb..bfe93743 100644 --- a/yazi-fm/src/input/input.rs +++ b/yazi-fm/src/input/input.rs @@ -6,7 +6,7 @@ use yazi_config::THEME; use yazi_core::input::InputMode; use yazi_shared::term::Term; -use crate::{Ctx, widgets}; +use crate::{widgets, Ctx}; pub(crate) struct Input<'a> { cx: &'a Ctx, diff --git a/yazi-fm/src/select/select.rs b/yazi-fm/src/select/select.rs index 19983d0f..a15e633d 100644 --- a/yazi-fm/src/select/select.rs +++ b/yazi-fm/src/select/select.rs @@ -1,7 +1,7 @@ use ratatui::{buffer::Buffer, layout::Rect, widgets::{Block, BorderType, Borders, List, ListItem, Widget}}; use yazi_config::THEME; -use crate::{Ctx, widgets}; +use crate::{widgets, Ctx}; pub(crate) struct Select<'a> { cx: &'a Ctx, diff --git a/yazi-fm/src/tasks/layout.rs b/yazi-fm/src/tasks/layout.rs index 82e68ee7..14b39885 100644 --- a/yazi-fm/src/tasks/layout.rs +++ b/yazi-fm/src/tasks/layout.rs @@ -2,7 +2,7 @@ use ratatui::{buffer::Buffer, layout::{self, Alignment, Constraint, Direction, R use yazi_config::THEME; use yazi_core::tasks::TASKS_PERCENT; -use crate::{Ctx, widgets}; +use crate::{widgets, Ctx}; pub(crate) struct Layout<'a> { cx: &'a Ctx, diff --git a/yazi-fm/src/which/layout.rs b/yazi-fm/src/which/layout.rs index 14a20687..b3aa4b9e 100644 --- a/yazi-fm/src/which/layout.rs +++ b/yazi-fm/src/which/layout.rs @@ -2,7 +2,7 @@ use ratatui::{layout, prelude::{Buffer, Constraint, Direction, Rect}, widgets::{ use yazi_config::THEME; use super::Side; -use crate::{Ctx, widgets}; +use crate::{widgets, Ctx}; pub(crate) struct Which<'a> { cx: &'a Ctx, diff --git a/yazi-plugin/Cargo.toml b/yazi-plugin/Cargo.toml index 38517200..75c47a63 100644 --- a/yazi-plugin/Cargo.toml +++ b/yazi-plugin/Cargo.toml @@ -20,6 +20,7 @@ crossterm = "^0" futures = "^0" libc = "^0" md-5 = "^0" +mlua = { version = "^0", features = [ "lua54", "vendored", "serialize", "macros", "async" ] } parking_lot = "^0" ratatui = "^0" serde = "^1" @@ -30,9 +31,3 @@ tokio-util = "^0" tracing = { version = "^0", features = [ "max_level_debug", "release_max_level_warn" ] } unicode-width = "^0" yazi-prebuild = "^0" - -[target.'cfg(any(target_arch="riscv64", target_arch="loongarch64"))'.dependencies] -mlua = { version = "^0", features = [ "lua52", "vendored", "serialize", "macros", "async" ] } - -[target.'cfg(not(any(target_arch="riscv64", target_arch="loongarch64")))'.dependencies] -mlua = { version = "^0", features = [ "luajit52", "vendored", "serialize", "macros", "async" ] }