diff --git a/yazi-config/preset/yazi.toml b/yazi-config/preset/yazi.toml index e7e5a973..a249d694 100644 --- a/yazi-config/preset/yazi.toml +++ b/yazi-config/preset/yazi.toml @@ -115,6 +115,8 @@ previewers = [ { mime = "application/x-7z-compressed", exec = "archive" }, { mime = "application/x-rar", exec = "archive" }, { mime = "application/xz", exec = "archive" }, + # Fallback + { name = "*", exec = "file" }, ] [input] diff --git a/yazi-fm/src/which/layout.rs b/yazi-fm/src/which/layout.rs index d260709d..e7cdca36 100644 --- a/yazi-fm/src/which/layout.rs +++ b/yazi-fm/src/which/layout.rs @@ -25,13 +25,9 @@ impl Widget for Which<'_> { } } - let height = cands.0.len() as u16 + 2; - let area = Rect { - x: 1, - y: area.height.saturating_sub(height + 2), - width: area.width.saturating_sub(2), - height, - }; + let height = area.height.min(cands.0.len() as u16 + 2); + let y = area.height.saturating_sub(height + 2); + let area = Rect { x: area.width.min(1), y, width: area.width.saturating_sub(2), height }; let chunks = layout::Layout::new(Direction::Horizontal, [ Constraint::Ratio(1, 3), diff --git a/yazi-plugin/preset/plugins/file.lua b/yazi-plugin/preset/plugins/file.lua new file mode 100644 index 00000000..cd334afa --- /dev/null +++ b/yazi-plugin/preset/plugins/file.lua @@ -0,0 +1,28 @@ +local M = {} + +function M:peek() + local output, code = Command("file") + :args({ + "-bL", + tostring(self.file.url), + }) + :stdout(Command.PIPED) + :output() + + local p + if output then + p = ui.Paragraph.parse(self.area, "----- File Type Classification -----\n\n" .. output.stdout) + else + p = ui.Paragraph(self.area, { + ui.Line { + ui.Span("Failed to spawn `file` command, error code: " .. tostring(code)), + }, + }) + end + + ya.preview_widgets(self, { p:wrap(ui.Paragraph.WRAP) }) +end + +function M:seek() end + +return M diff --git a/yazi-plugin/src/elements/paragraph.rs b/yazi-plugin/src/elements/paragraph.rs index 19da0967..cb0f9c52 100644 --- a/yazi-plugin/src/elements/paragraph.rs +++ b/yazi-plugin/src/elements/paragraph.rs @@ -4,10 +4,16 @@ use ratatui::widgets::Widget; use super::{Line, RectRef, Renderable, Style}; +// Alignment const LEFT: u8 = 0; const CENTER: u8 = 1; const RIGHT: u8 = 2; +// Wrap +const WRAP_NO: u8 = 0; +const WRAP: u8 = 1; +const WRAP_TRIM: u8 = 2; + #[derive(Clone, Debug, Default)] pub struct Paragraph { pub area: ratatui::layout::Rect, @@ -15,6 +21,7 @@ pub struct Paragraph { pub text: ratatui::text::Text<'static>, pub style: Option, pub alignment: ratatui::layout::Alignment, + pub wrap: u8, } impl Paragraph { @@ -37,6 +44,10 @@ impl Paragraph { ("LEFT", LEFT.into_lua(lua)?), ("CENTER", CENTER.into_lua(lua)?), ("RIGHT", RIGHT.into_lua(lua)?), + // Wrap + ("WRAP_OFF", WRAP_NO.into_lua(lua)?), + ("WRAP", WRAP.into_lua(lua)?), + ("WRAP_TRIM", WRAP_TRIM.into_lua(lua)?), ])?; paragraph.set_metatable(Some(lua.create_table_from([("__call", new)])?)); @@ -67,6 +78,13 @@ impl UserData for Paragraph { }; Ok(ud) }); + methods.add_function("wrap", |_, (ud, wrap): (AnyUserData, u8)| { + ud.borrow_mut::()?.wrap = match wrap { + w @ (WRAP | WRAP_TRIM | WRAP_NO) => w, + _ => return Err("expected a WRAP or WRAP_TRIM or WRAP_OFF".into_lua_err()), + }; + Ok(ud) + }); } } @@ -79,8 +97,11 @@ impl Renderable for Paragraph { p = p.style(style); } - p = p.alignment(self.alignment); - p.render(self.area, buf) + if self.wrap != WRAP_NO { + p = p.wrap(ratatui::widgets::Wrap { trim: self.wrap == WRAP_TRIM }); + } + + p.alignment(self.alignment).render(self.area, buf); } fn clone_render(&self, buf: &mut ratatui::buffer::Buffer) { Box::new(self.clone()).render(buf) } diff --git a/yazi-plugin/src/loader.rs b/yazi-plugin/src/loader.rs index f9819fb5..e3529563 100644 --- a/yazi-plugin/src/loader.rs +++ b/yazi-plugin/src/loader.rs @@ -25,13 +25,14 @@ impl Loader { let path = BOOT.plugin_dir.join(format!("{name}.yazi/init.lua")); let b = fs::read(path).await.map(|v| v.into()).or_else(|_| { Ok(Cow::from(match name { - "noop" => include_bytes!("../preset/plugins/noop.lua") as &[u8], - "archive" => include_bytes!("../preset/plugins/archive.lua"), + "archive" => include_bytes!("../preset/plugins/archive.lua") as &[u8], "code" => include_bytes!("../preset/plugins/code.lua"), + "file" => include_bytes!("../preset/plugins/file.lua"), "folder" => include_bytes!("../preset/plugins/folder.lua"), "image" => include_bytes!("../preset/plugins/image.lua"), "json" => include_bytes!("../preset/plugins/json.lua"), "mime" => include_bytes!("../preset/plugins/mime.lua"), + "noop" => include_bytes!("../preset/plugins/noop.lua"), "pdf" => include_bytes!("../preset/plugins/pdf.lua"), "video" => include_bytes!("../preset/plugins/video.lua"), _ => bail!("plugin not found: {name}"),