feat: add list_meta() method to archive plugin (#1638)

This commit is contained in:
三咲雅 · Misaki Masa 2024-09-14 18:46:38 +08:00 committed by sxyazi
parent bc68d1eb01
commit 2453539fb5
No known key found for this signature in database
9 changed files with 135 additions and 51 deletions

View file

@ -7,6 +7,7 @@ use yazi_shared::{RoCell, Xdg};
pub mod keymap; pub mod keymap;
mod layout; mod layout;
mod log; mod log;
mod macros;
pub mod manager; pub mod manager;
pub mod open; pub mod open;
mod pattern; mod pattern;

21
yazi-config/src/macros.rs Normal file
View file

@ -0,0 +1,21 @@
#[macro_export]
macro_rules! preset {
($name:literal) => {{
#[cfg(debug_assertions)]
{
std::borrow::Cow::Owned(
std::fs::read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/preset/", $name, ".toml"))
.expect(concat!("Failed to read 'yazi-config/preset/", $name, ".toml'")),
)
}
#[cfg(not(debug_assertions))]
{
std::borrow::Cow::Borrowed(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/preset/",
$name,
".toml"
)))
}
}};
}

View file

@ -3,32 +3,32 @@ use std::{borrow::Cow, path::{Path, PathBuf}};
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use toml::{Table, Value}; use toml::{Table, Value};
use crate::theme::Flavor; use crate::{preset, theme::Flavor};
pub(crate) struct Preset; pub(crate) struct Preset;
impl Preset { impl Preset {
pub(crate) fn yazi(p: &Path) -> Result<Cow<str>> { pub(crate) fn yazi(p: &Path) -> Result<Cow<str>> {
Self::merge_path(p.join("yazi.toml"), include_str!("../preset/yazi.toml")) Self::merge_path(p.join("yazi.toml"), preset!("yazi"))
} }
pub(crate) fn keymap(p: &Path) -> Result<Cow<str>> { pub(crate) fn keymap(p: &Path) -> Result<Cow<str>> {
Self::merge_path(p.join("keymap.toml"), include_str!("../preset/keymap.toml")) Self::merge_path(p.join("keymap.toml"), preset!("keymap"))
} }
pub(crate) fn theme(p: &Path) -> Result<Cow<str>> { pub(crate) fn theme(p: &Path) -> Result<Cow<str>> {
let Ok(user) = std::fs::read_to_string(p.join("theme.toml")) else { let Ok(user) = std::fs::read_to_string(p.join("theme.toml")) else {
return Ok(include_str!("../preset/theme.toml").into()); return Ok(preset!("theme"));
}; };
let Some(use_) = Flavor::parse_use(&user) else { let Some(use_) = Flavor::parse_use(&user) else {
return Self::merge_str(&user, include_str!("../preset/theme.toml")); return Self::merge_str(&user, &preset!("theme"));
}; };
let p = p.join(format!("flavors/{use_}.yazi/flavor.toml")); let p = p.join(format!("flavors/{use_}.yazi/flavor.toml"));
let flavor = let flavor =
std::fs::read_to_string(&p).with_context(|| anyhow!("Failed to load flavor {p:?}"))?; std::fs::read_to_string(&p).with_context(|| anyhow!("Failed to load flavor {p:?}"))?;
Self::merge_str(&user, &Self::merge_str(&flavor, include_str!("../preset/theme.toml"))?) Self::merge_str(&user, &Self::merge_str(&flavor, &preset!("theme"))?)
} }
#[inline] #[inline]
@ -48,13 +48,13 @@ impl Preset {
} }
#[inline] #[inline]
fn merge_path(user: PathBuf, base: &str) -> Result<Cow<str>> { fn merge_path(user: PathBuf, base: Cow<str>) -> Result<Cow<str>> {
let s = std::fs::read_to_string(&user).unwrap_or_default(); let s = std::fs::read_to_string(&user).unwrap_or_default();
if s.is_empty() { if s.is_empty() {
return Ok(base.into()); return Ok(base);
} }
Self::merge_str(&s, base).with_context(|| anyhow!("Loading {user:?}")) Self::merge_str(&s, &base).with_context(|| anyhow!("Loading {user:?}"))
} }
fn merge(a: &mut Table, b: Table, max: u8) { fn merge(a: &mut Table, b: Table, max: u8) {

View file

@ -81,9 +81,9 @@ end
---@param args table ---@param args table
---@param skip integer ---@param skip integer
---@param limit integer ---@param limit integer
---@return table ---@return table files
---@return integer ---@return integer bound
---@return integer ---@return integer code
--- 0: success --- 0: success
--- 1: failed to spawn --- 1: failed to spawn
--- 2: wrong password --- 2: wrong password
@ -137,6 +137,47 @@ function M:list_files(args, skip, limit)
return files, i, code return files, i, code
end end
---List metadata of an archive
---@param args table
---@return string|nil type
---@return integer code
--- 0: success
--- 1: failed to spawn
--- 2: wrong password
--- 3: partial success
function M:list_meta(args)
local child = self:spawn_7z { "l", "-slt", table.unpack(args) }
if not child then
return nil, 1
end
local i, head = 0, ""
local typ, code = nil, 0
while i < 500 do
i = i + 1
local next, event = child:read_line()
if event == 1 and self:is_encrypted(next) then
code = 2
break
elseif event == 1 then
code = 3
elseif event == 0 then
head = head .. next
else
break
end
typ = head:gmatch("--[\r\n]+Path = .-[\r\n]+Type = (.-)[\r\n]+")()
if typ then
break
end
end
child:start_kill()
return typ ~= "" and typ or nil, code
end
function M:is_encrypted(s) return s:find(" Wrong password", 1, true) end function M:is_encrypted(s) return s:find(" Wrong password", 1, true) end
return M return M

View file

@ -56,7 +56,7 @@ function M:try_with(url, pwd)
local output, err = child:wait_with_output() local output, err = child:wait_with_output()
if output and output.status.code == 2 and archive:is_encrypted(output.stderr) then if output and output.status.code == 2 and archive:is_encrypted(output.stderr) then
fs.remove("dir_clean", tmp) fs.remove("dir_clean", tmp)
return true -- Needs retry return true -- Need to retry
end end
self:tidy(url, tmp) self:tidy(url, tmp)

View file

@ -1,6 +1,6 @@
use mlua::Lua; use mlua::Lua;
use crate::{elements, runtime::Runtime}; use crate::{elements, preset, runtime::Runtime};
pub fn slim_lua(name: &str) -> mlua::Result<Lua> { pub fn slim_lua(name: &str) -> mlua::Result<Lua> {
let lua = Lua::new(); let lua = Lua::new();
@ -17,7 +17,7 @@ pub fn slim_lua(name: &str) -> mlua::Result<Lua> {
crate::process::install(&lua)?; crate::process::install(&lua)?;
crate::utils::install_isolate(&lua)?; crate::utils::install_isolate(&lua)?;
crate::Config::new(&lua).install_preview()?; crate::Config::new(&lua).install_preview()?;
lua.load(include_str!("../../preset/ya.lua")).set_name("ya.lua").exec()?; lua.load(preset!("ya")).set_name("ya.lua").exec()?;
// Elements // Elements
let ui = lua.create_table()?; let ui = lua.create_table()?;

View file

@ -7,6 +7,8 @@ use tokio::fs;
use yazi_boot::BOOT; use yazi_boot::BOOT;
use yazi_shared::RoCell; use yazi_shared::RoCell;
use crate::preset;
pub static LOADER: RoCell<Loader> = RoCell::new(); pub static LOADER: RoCell<Loader> = RoCell::new();
#[derive(Default)] #[derive(Default)]
@ -21,32 +23,32 @@ impl Loader {
} }
let preset = match name { let preset = match name {
"archive" => &include_bytes!("../../preset/plugins/archive.lua")[..], "archive" => preset!("plugins/archive"),
"code" => include_bytes!("../../preset/plugins/code.lua"), "code" => preset!("plugins/code"),
"dds" => include_bytes!("../../preset/plugins/dds.lua"), "dds" => preset!("plugins/dds"),
"empty" => include_bytes!("../../preset/plugins/empty.lua"), "empty" => preset!("plugins/empty"),
"extract" => include_bytes!("../../preset/plugins/extract.lua"), "extract" => preset!("plugins/extract"),
"file" => include_bytes!("../../preset/plugins/file.lua"), "file" => preset!("plugins/file"),
"folder" => include_bytes!("../../preset/plugins/folder.lua"), "folder" => preset!("plugins/folder"),
"font" => include_bytes!("../../preset/plugins/font.lua"), "font" => preset!("plugins/font"),
"fzf" => include_bytes!("../../preset/plugins/fzf.lua"), "fzf" => preset!("plugins/fzf"),
"image" => include_bytes!("../../preset/plugins/image.lua"), "image" => preset!("plugins/image"),
"json" => include_bytes!("../../preset/plugins/json.lua"), "json" => preset!("plugins/json"),
"magick" => include_bytes!("../../preset/plugins/magick.lua"), "magick" => preset!("plugins/magick"),
"mime" => include_bytes!("../../preset/plugins/mime.lua"), "mime" => preset!("plugins/mime"),
"noop" => include_bytes!("../../preset/plugins/noop.lua"), "noop" => preset!("plugins/noop"),
"pdf" => include_bytes!("../../preset/plugins/pdf.lua"), "pdf" => preset!("plugins/pdf"),
"session" => include_bytes!("../../preset/plugins/session.lua"), "session" => preset!("plugins/session"),
"video" => include_bytes!("../../preset/plugins/video.lua"), "video" => preset!("plugins/video"),
"zoxide" => include_bytes!("../../preset/plugins/zoxide.lua"), "zoxide" => preset!("plugins/zoxide"),
_ => b"", _ => Default::default(),
}; };
let b = if preset.is_empty() { let b = if preset.is_empty() {
let p = BOOT.plugin_dir.join(format!("{name}.yazi/init.lua")); let p = BOOT.plugin_dir.join(format!("{name}.yazi/init.lua"));
Cow::Owned(fs::read(&p).await.with_context(|| format!("failed to load plugin from {p:?}"))?) Cow::Owned(fs::read(&p).await.with_context(|| format!("failed to load plugin from {p:?}"))?)
} else { } else {
Cow::Borrowed(preset) preset.into()
}; };
self.cache.write().insert(name.to_owned(), b); self.cache.write().insert(name.to_owned(), b);

View file

@ -3,7 +3,7 @@ use mlua::Lua;
use yazi_boot::BOOT; use yazi_boot::BOOT;
use yazi_shared::RoCell; use yazi_shared::RoCell;
use crate::runtime::Runtime; use crate::{preset, runtime::Runtime};
pub static LUA: RoCell<Lua> = RoCell::new(); pub static LUA: RoCell<Lua> = RoCell::new();
@ -21,7 +21,7 @@ fn stage_1(lua: &'static Lua) -> Result<()> {
// Base // Base
lua.set_named_registry_value("rt", Runtime::default())?; lua.set_named_registry_value("rt", Runtime::default())?;
lua.load(include_str!("../preset/ya.lua")).set_name("ya.lua").exec()?; lua.load(preset!("ya")).set_name("ya.lua").exec()?;
crate::bindings::Icon::register(lua)?; crate::bindings::Icon::register(lua)?;
crate::bindings::MouseEvent::register(lua)?; crate::bindings::MouseEvent::register(lua)?;
crate::elements::pour(lua)?; crate::elements::pour(lua)?;
@ -32,25 +32,26 @@ fn stage_1(lua: &'static Lua) -> Result<()> {
crate::url::pour(lua)?; crate::url::pour(lua)?;
// Components // Components
lua.load(include_str!("../preset/components/current.lua")).set_name("current.lua").exec()?; lua.load(preset!("components/current")).set_name("current.lua").exec()?;
lua.load(include_str!("../preset/components/entity.lua")).set_name("entity.lua").exec()?; lua.load(preset!("components/entity")).set_name("entity.lua").exec()?;
lua.load(include_str!("../preset/components/header.lua")).set_name("header.lua").exec()?; lua.load(preset!("components/header")).set_name("header.lua").exec()?;
lua.load(include_str!("../preset/components/linemode.lua")).set_name("linemode.lua").exec()?; lua.load(preset!("components/linemode")).set_name("linemode.lua").exec()?;
lua.load(include_str!("../preset/components/marker.lua")).set_name("marker.lua").exec()?;
lua.load(include_str!("../preset/components/parent.lua")).set_name("parent.lua").exec()?; lua.load(preset!("components/marker")).set_name("marker.lua").exec()?;
lua.load(include_str!("../preset/components/preview.lua")).set_name("preview.lua").exec()?; lua.load(preset!("components/parent")).set_name("parent.lua").exec()?;
lua.load(include_str!("../preset/components/progress.lua")).set_name("progress.lua").exec()?; lua.load(preset!("components/preview")).set_name("preview.lua").exec()?;
lua.load(include_str!("../preset/components/rail.lua")).set_name("rail.lua").exec()?; lua.load(preset!("components/progress")).set_name("progress.lua").exec()?;
lua.load(include_str!("../preset/components/root.lua")).set_name("root.lua").exec()?; lua.load(preset!("components/rail")).set_name("rail.lua").exec()?;
lua.load(include_str!("../preset/components/status.lua")).set_name("status.lua").exec()?; lua.load(preset!("components/root")).set_name("root.lua").exec()?;
lua.load(include_str!("../preset/components/tab.lua")).set_name("tab.lua").exec()?; lua.load(preset!("components/status")).set_name("status.lua").exec()?;
lua.load(preset!("components/tab")).set_name("tab.lua").exec()?;
Ok(()) Ok(())
} }
fn stage_2(lua: &'static Lua) -> mlua::Result<()> { fn stage_2(lua: &'static Lua) -> mlua::Result<()> {
lua.load(include_str!("../preset/setup.lua")).set_name("setup.lua").exec()?; lua.load(preset!("setup")).set_name("setup.lua").exec()?;
lua.load(include_str!("../preset/compat.lua")).set_name("compat.lua").exec()?; lua.load(preset!("compat")).set_name("compat.lua").exec()?;
if let Ok(b) = std::fs::read(BOOT.config_dir.join("init.lua")) { if let Ok(b) = std::fs::read(BOOT.config_dir.join("init.lua")) {
lua.load(b).set_name("init.lua").exec()?; lua.load(b).set_name("init.lua").exec()?;

View file

@ -1,3 +1,21 @@
#[macro_export]
macro_rules! preset {
($name:literal) => {{
#[cfg(debug_assertions)]
{
std::fs::read(concat!(env!("CARGO_MANIFEST_DIR"), "/preset/", $name, ".lua")).expect(concat!(
"Failed to read 'yazi-plugin/preset/",
$name,
".lua'"
))
}
#[cfg(not(debug_assertions))]
{
&include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/preset/", $name, ".lua"))[..]
}
}};
}
#[macro_export] #[macro_export]
macro_rules! impl_style_method { macro_rules! impl_style_method {
($methods:ident, $($field:tt).+) => { ($methods:ident, $($field:tt).+) => {