mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: make the builtin code previewer handle invalid carriage return chars and binary streams better (#1550)
This commit is contained in:
parent
69c20d4dd3
commit
9cf85c09d2
13 changed files with 94 additions and 115 deletions
|
|
@ -70,7 +70,7 @@ function Entity:symlink()
|
|||
end
|
||||
|
||||
local to = self._file.link_to
|
||||
return ui.Line(to and { ui.Span(" -> " .. tostring(to)):italic() } or {})
|
||||
return to and ui.Line(" -> " .. tostring(to)):italic() or ui.Line {}
|
||||
end
|
||||
|
||||
function Entity:render()
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
local M = {}
|
||||
|
||||
function M:peek()
|
||||
local _, bound = ya.preview_code(self)
|
||||
local err, bound = ya.preview_code(self)
|
||||
if bound then
|
||||
ya.manager_emit("peek", { bound, only_if = self.file.url, upper_bound = true })
|
||||
elseif err then
|
||||
ya.preview_widgets(self, {
|
||||
ui.Paragraph(self.area, { ui.Line(err):reverse() }),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ local M = {}
|
|||
|
||||
function M:msg(s)
|
||||
local p = ui.Paragraph(self.area, {
|
||||
ui.Line { ui.Span(s):reverse() },
|
||||
ui.Line(s):reverse(),
|
||||
})
|
||||
ya.preview_widgets(self, { p:wrap(ui.Paragraph.WRAP) })
|
||||
end
|
||||
|
|
|
|||
|
|
@ -53,9 +53,13 @@ function M:seek(units)
|
|||
end
|
||||
|
||||
function M:fallback_to_builtin()
|
||||
local _, bound = ya.preview_code(self)
|
||||
local err, bound = ya.preview_code(self)
|
||||
if bound then
|
||||
ya.manager_emit("peek", { bound, only_if = self.file.url, upper_bound = true })
|
||||
elseif err then
|
||||
ya.preview_widgets(self, {
|
||||
ui.Paragraph(self.area, { ui.Line(err):reverse() }),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@ impl Line {
|
|||
|
||||
impl UserData for Line {
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
crate::impl_style_shorthands!(methods, 0.style);
|
||||
|
||||
methods.add_function("width", |_, ud: AnyUserData| Ok(ud.borrow_mut::<Self>()?.0.width()));
|
||||
methods.add_function("style", |_, (ud, value): (AnyUserData, Value)| {
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ pub struct Paragraph {
|
|||
pub area: ratatui::layout::Rect,
|
||||
|
||||
pub text: ratatui::text::Text<'static>,
|
||||
pub style: Option<ratatui::style::Style>,
|
||||
pub style: ratatui::style::Style,
|
||||
pub alignment: ratatui::layout::Alignment,
|
||||
pub wrap: u8,
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ impl Paragraph {
|
|||
let new = lua.create_function(|_, (_, area, lines): (Table, RectRef, Vec<Line>)| {
|
||||
Ok(Paragraph {
|
||||
area: *area,
|
||||
text: lines.into_iter().map(|s| s.0).collect::<Vec<_>>().into(),
|
||||
text: lines.into_iter().map(|s| s.0).collect(),
|
||||
..Default::default()
|
||||
})
|
||||
})?;
|
||||
|
|
@ -58,13 +58,15 @@ impl Paragraph {
|
|||
|
||||
impl UserData for Paragraph {
|
||||
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
crate::impl_style_shorthands!(methods, style);
|
||||
|
||||
methods.add_function("style", |_, (ud, value): (AnyUserData, Value)| {
|
||||
{
|
||||
let mut me = ud.borrow_mut::<Self>()?;
|
||||
match value {
|
||||
Value::Nil => me.style = None,
|
||||
Value::Table(tb) => me.style = Some(Style::try_from(tb)?.0),
|
||||
Value::UserData(ud) => me.style = Some(ud.borrow::<Style>()?.0),
|
||||
Value::Nil => me.style = ratatui::style::Style::default(),
|
||||
Value::Table(tb) => me.style = Style::try_from(tb)?.0,
|
||||
Value::UserData(ud) => me.style = ud.borrow::<Style>()?.0,
|
||||
_ => return Err("expected a Style or Table or nil".into_lua_err()),
|
||||
}
|
||||
}
|
||||
|
|
@ -92,10 +94,7 @@ impl Renderable for Paragraph {
|
|||
fn area(&self) -> ratatui::layout::Rect { self.area }
|
||||
|
||||
fn render(self: Box<Self>, buf: &mut ratatui::buffer::Buffer) {
|
||||
let mut p = ratatui::widgets::Paragraph::new(self.text);
|
||||
if let Some(style) = self.style {
|
||||
p = p.style(style);
|
||||
}
|
||||
let mut p = ratatui::widgets::Paragraph::new(self.text).style(self.style);
|
||||
|
||||
if self.wrap != WRAP_NO {
|
||||
p = p.wrap(ratatui::widgets::Wrap { trim: self.wrap == WRAP_TRIM });
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use mlua::{AnyUserData, ExternalError, FromLua, Lua, Table, UserData, UserDataMethods, Value};
|
||||
use yazi_shared::theme::Color;
|
||||
|
||||
use super::Style;
|
||||
|
||||
|
|
@ -19,54 +18,7 @@ impl Span {
|
|||
|
||||
impl UserData for Span {
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_function("fg", |_, (ud, color): (AnyUserData, String)| {
|
||||
ud.borrow_mut::<Self>()?.0.style.fg = Color::try_from(color).ok().map(Into::into);
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("bg", |_, (ud, color): (AnyUserData, String)| {
|
||||
ud.borrow_mut::<Self>()?.0.style.bg = Color::try_from(color).ok().map(Into::into);
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("bold", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.style.add_modifier |= ratatui::style::Modifier::BOLD;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("dim", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.style.add_modifier |= ratatui::style::Modifier::DIM;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("italic", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.style.add_modifier |= ratatui::style::Modifier::ITALIC;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("underline", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.style.add_modifier |= ratatui::style::Modifier::UNDERLINED;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("blink", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.style.add_modifier |= ratatui::style::Modifier::SLOW_BLINK;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("blink_rapid", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.style.add_modifier |= ratatui::style::Modifier::RAPID_BLINK;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("reverse", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.style.add_modifier |= ratatui::style::Modifier::REVERSED;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("hidden", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.style.add_modifier |= ratatui::style::Modifier::HIDDEN;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("crossed", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.style.add_modifier |= ratatui::style::Modifier::CROSSED_OUT;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("reset", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.style.add_modifier = ratatui::style::Modifier::empty();
|
||||
Ok(ud)
|
||||
});
|
||||
crate::impl_style_shorthands!(methods, 0.style);
|
||||
|
||||
methods.add_function("style", |_, (ud, value): (AnyUserData, Value)| {
|
||||
ud.borrow_mut::<Self>()?.0.style = match value {
|
||||
|
|
|
|||
|
|
@ -40,54 +40,8 @@ impl<'a> TryFrom<Table<'a>> for Style {
|
|||
|
||||
impl UserData for Style {
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_function("fg", |_, (ud, color): (AnyUserData, String)| {
|
||||
ud.borrow_mut::<Self>()?.0.fg = Color::try_from(color).ok().map(Into::into);
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("bg", |_, (ud, color): (AnyUserData, String)| {
|
||||
ud.borrow_mut::<Self>()?.0.bg = Color::try_from(color).ok().map(Into::into);
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("bold", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.add_modifier |= ratatui::style::Modifier::BOLD;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("dim", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.add_modifier |= ratatui::style::Modifier::DIM;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("italic", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.add_modifier |= ratatui::style::Modifier::ITALIC;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("underline", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.add_modifier |= ratatui::style::Modifier::UNDERLINED;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("blink", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.add_modifier |= ratatui::style::Modifier::SLOW_BLINK;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("blink_rapid", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.add_modifier |= ratatui::style::Modifier::RAPID_BLINK;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("reverse", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.add_modifier |= ratatui::style::Modifier::REVERSED;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("hidden", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.add_modifier |= ratatui::style::Modifier::HIDDEN;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("crossed", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.add_modifier |= ratatui::style::Modifier::CROSSED_OUT;
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_function("reset", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.0.add_modifier = ratatui::style::Modifier::empty();
|
||||
Ok(ud)
|
||||
});
|
||||
crate::impl_style_shorthands!(methods, 0);
|
||||
|
||||
methods.add_function("patch", |_, (ud, value): (AnyUserData, Value)| {
|
||||
{
|
||||
let mut me = ud.borrow_mut::<Self>()?;
|
||||
|
|
|
|||
8
yazi-plugin/src/external/highlighter.rs
vendored
8
yazi-plugin/src/external/highlighter.rs
vendored
|
|
@ -84,6 +84,14 @@ impl Highlighter {
|
|||
buf.push(b'\n');
|
||||
}
|
||||
|
||||
for b in &mut buf {
|
||||
match *b {
|
||||
b'\0' => return Err("Binary file".into()),
|
||||
b'\r' => *b = b'\n', // '\r' occurs in the middle of a line
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if i > skip {
|
||||
after.push(String::from_utf8_lossy(&buf).into_owned());
|
||||
} else if !plain {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ pub mod fs;
|
|||
pub mod isolate;
|
||||
pub mod loader;
|
||||
mod lua;
|
||||
mod macros;
|
||||
mod opt;
|
||||
pub mod process;
|
||||
pub mod pubsub;
|
||||
|
|
|
|||
53
yazi-plugin/src/macros.rs
Normal file
53
yazi-plugin/src/macros.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#[macro_export]
|
||||
macro_rules! impl_style_shorthands {
|
||||
($methods:ident, $($field:tt).+) => {
|
||||
$methods.add_function("fg", |_, (ud, color): (AnyUserData, String)| {
|
||||
ud.borrow_mut::<Self>()?.$($field).+.fg = yazi_shared::theme::Color::try_from(color).ok().map(Into::into);
|
||||
Ok(ud)
|
||||
});
|
||||
$methods.add_function("bg", |_, (ud, color): (AnyUserData, String)| {
|
||||
ud.borrow_mut::<Self>()?.$($field).+.bg = yazi_shared::theme::Color::try_from(color).ok().map(Into::into);
|
||||
Ok(ud)
|
||||
});
|
||||
$methods.add_function("bold", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::BOLD;
|
||||
Ok(ud)
|
||||
});
|
||||
$methods.add_function("dim", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::DIM;
|
||||
Ok(ud)
|
||||
});
|
||||
$methods.add_function("italic", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::ITALIC;
|
||||
Ok(ud)
|
||||
});
|
||||
$methods.add_function("underline", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::UNDERLINED;
|
||||
Ok(ud)
|
||||
});
|
||||
$methods.add_function("blink", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::SLOW_BLINK;
|
||||
Ok(ud)
|
||||
});
|
||||
$methods.add_function("blink_rapid", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::RAPID_BLINK;
|
||||
Ok(ud)
|
||||
});
|
||||
$methods.add_function("reverse", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::REVERSED;
|
||||
Ok(ud)
|
||||
});
|
||||
$methods.add_function("hidden", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::HIDDEN;
|
||||
Ok(ud)
|
||||
});
|
||||
$methods.add_function("crossed", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::CROSSED_OUT;
|
||||
Ok(ud)
|
||||
});
|
||||
$methods.add_function("reset", |_, ud: AnyUserData| {
|
||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier = ratatui::style::Modifier::empty();
|
||||
Ok(ud)
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
@ -39,13 +39,15 @@ impl Utils {
|
|||
let text =
|
||||
match Highlighter::new(&lock.url).highlight(lock.skip, area.height as usize).await {
|
||||
Ok(text) => text,
|
||||
Err(PeekError::Exceed(max)) => return (false, max).into_lua_multi(lua),
|
||||
Err(_) => return (false, Value::Nil).into_lua_multi(lua),
|
||||
Err(e @ PeekError::Exceed(max)) => return (e.to_string(), max).into_lua_multi(lua),
|
||||
Err(e @ PeekError::Unexpected(_)) => {
|
||||
return (e.to_string(), Value::Nil).into_lua_multi(lua);
|
||||
}
|
||||
};
|
||||
lock.data = vec![Box::new(Paragraph { area: *area, text, ..Default::default() })];
|
||||
|
||||
emit!(Call(Cmd::new("preview").with_any("lock", lock), Layer::Manager));
|
||||
(true, Value::Nil).into_lua_multi(lua)
|
||||
(Value::Nil, Value::Nil).into_lua_multi(lua)
|
||||
})?,
|
||||
)?;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ pub enum PeekError {
|
|||
impl Display for PeekError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Exceed(lines) => write!(f, "Exceed: {lines}"),
|
||||
Self::Unexpected(msg) => write!(f, "Unexpected error: {msg}"),
|
||||
Self::Exceed(lines) => write!(f, "Exceed maximum lines {lines}"),
|
||||
Self::Unexpected(msg) => write!(f, "{msg}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue