mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
fix: panic caused by set_hook
This commit is contained in:
parent
82bab0f24a
commit
f0535ef824
11 changed files with 74 additions and 66 deletions
|
|
@ -1,4 +1,4 @@
|
|||
use std::{env, path::Path, sync::{atomic::Ordering, Arc}};
|
||||
use std::{env, path::Path, sync::Arc};
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use ratatui::prelude::Rect;
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
mod plugin;
|
||||
mod render;
|
||||
mod stop;
|
||||
|
|
|
|||
51
yazi-fm/src/app/commands/render.rs
Normal file
51
yazi-fm/src/app/commands/render.rs
Normal file
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -12,18 +12,19 @@ pub fn peek(exec: &Exec, file: yazi_shared::fs::File, skip: usize) -> Cancellati
|
|||
let ct = CancellationToken::new();
|
||||
|
||||
let cmd = exec.cmd.to_owned();
|
||||
let (ct1, ct2) = (ct.clone(), ct.clone());
|
||||
let ct2 = ct.clone();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let future = async {
|
||||
LOADED.ensure(&cmd).await.into_lua_err()?;
|
||||
|
||||
let lua = slim_lua()?;
|
||||
lua.set_hook(
|
||||
HookTriggers::new().on_calls().on_returns().every_nth_instruction(2000),
|
||||
move |_, _| {
|
||||
if ct1.is_cancelled() { Err("cancelled".into_lua_err()) } else { Ok(()) }
|
||||
},
|
||||
);
|
||||
// FIXME: this will cause a panic
|
||||
// lua.set_hook(
|
||||
// HookTriggers::new().on_calls().on_returns().every_nth_instruction(2000),
|
||||
// move |_, _| {
|
||||
// if ct1.is_cancelled() { Err("cancelled".into_lua_err()) } else { Ok(()) }
|
||||
// },
|
||||
// );
|
||||
|
||||
let plugin: Table = if let Some(b) = LOADED.read().get(&cmd) {
|
||||
lua.load(b).call(())?
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue