mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: add list_meta() method to archive plugin (#1638)
This commit is contained in:
parent
bc68d1eb01
commit
2453539fb5
9 changed files with 135 additions and 51 deletions
|
|
@ -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
21
yazi-config/src/macros.rs
Normal 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"
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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()?;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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()?;
|
||||||
|
|
|
||||||
|
|
@ -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).+) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue