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;
mod layout;
mod log;
mod macros;
pub mod manager;
pub mod open;
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 toml::{Table, Value};
use crate::theme::Flavor;
use crate::{preset, theme::Flavor};
pub(crate) struct Preset;
impl Preset {
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>> {
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>> {
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 {
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 flavor =
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]
@ -48,13 +48,13 @@ impl Preset {
}
#[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();
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) {

View File

@ -81,9 +81,9 @@ end
---@param args table
---@param skip integer
---@param limit integer
---@return table
---@return integer
---@return integer
---@return table files
---@return integer bound
---@return integer code
--- 0: success
--- 1: failed to spawn
--- 2: wrong password
@ -137,6 +137,47 @@ function M:list_files(args, skip, limit)
return files, i, code
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
return M

View File

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

View File

@ -1,6 +1,6 @@
use mlua::Lua;
use crate::{elements, runtime::Runtime};
use crate::{elements, preset, runtime::Runtime};
pub fn slim_lua(name: &str) -> mlua::Result<Lua> {
let lua = Lua::new();
@ -17,7 +17,7 @@ pub fn slim_lua(name: &str) -> mlua::Result<Lua> {
crate::process::install(&lua)?;
crate::utils::install_isolate(&lua)?;
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
let ui = lua.create_table()?;

View File

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

View File

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