Skip to content

Commit

Permalink
feat: new @since plugin annotation to specify the minimum supported…
Browse files Browse the repository at this point in the history
… Yazi version (#2290)
  • Loading branch information
sxyazi authored Feb 5, 2025
1 parent 4e96341 commit b236f34
Show file tree
Hide file tree
Showing 15 changed files with 81 additions and 46 deletions.
28 changes: 14 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ ansi-to-tui = "7.0.0"
anyhow = "1.0.95"
base64 = "0.22.1"
bitflags = "2.8.0"
clap = { version = "4.5.27", features = [ "derive" ] }
clap = { version = "4.5.28", features = [ "derive" ] }
core-foundation-sys = "0.8.7"
crossterm = { version = "0.28.1", features = [ "event-stream" ] }
dirs = "6.0.0"
Expand Down
2 changes: 1 addition & 1 deletion yazi-boot/src/actions/actions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::process;

pub(crate) struct Actions;
pub struct Actions;

impl Actions {
pub(crate) fn act(args: &crate::Args) {
Expand Down
2 changes: 1 addition & 1 deletion yazi-boot/src/actions/version.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::Actions;

impl Actions {
pub(super) fn version() -> &'static str {
pub fn version() -> &'static str {
concat!(
env!("CARGO_PKG_VERSION"),
" (",
Expand Down
2 changes: 1 addition & 1 deletion yazi-codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ proc-macro = true

[dependencies]
# External dependencies
syn = { version = "2.0.96", features = [ "full" ] }
syn = { version = "2.0.98", features = [ "full" ] }
quote = "1.0.38"
2 changes: 1 addition & 1 deletion yazi-core/src/manager/commands/quit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl Manager {
_ = time::sleep(Duration::from_millis(50)) => {
i += 1;
if i > 40 { break }
else if ongoing.lock().len() == 0 {
else if ongoing.lock().is_empty() {
emit!(Quit(opt));
return;
}
Expand Down
6 changes: 4 additions & 2 deletions yazi-core/src/notify/commands/push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ impl Notify {

let instant = Instant::now();
msg.timeout += instant - self.messages.first().map_or(instant, |m| m.instant);
self.messages.push(msg);

emit!(Call(Cmd::args("update_notify", &[0]), Layer::App));
if self.messages.iter().all(|m| m != &msg) {
self.messages.push(msg);
emit!(Call(Cmd::args("update_notify", &[0]), Layer::App));
}
}
}
17 changes: 9 additions & 8 deletions yazi-core/src/notify/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,16 @@ impl From<NotifyOpt> for Message {
impl Message {
#[inline]
pub fn height(&self, width: u16) -> usize {
if width == 0 {
return 0; // In case we can't get the width of the terminal
}

let mut lines = 0;
for line in self.content.lines() {
lines += (line.width() + 1).div_ceil(width as usize)
}
let lines = ratatui::widgets::Paragraph::new(self.content.as_str())
.wrap(ratatui::widgets::Wrap { trim: false })
.line_count(width);

lines + NOTIFY_BORDER as usize
}
}

impl PartialEq for Message {
fn eq(&self, other: &Self) -> bool {
self.level == other.level && self.content == other.content && self.title == other.title
}
}
13 changes: 9 additions & 4 deletions yazi-fm/src/app/commands/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use mlua::ObjectLike;
use scopeguard::defer;
use tracing::{error, warn};
use yazi_dds::Sendable;
use yazi_plugin::{LUA, RtRefMut, loader::LOADER};
use yazi_plugin::{LUA, RtRefMut, loader::{LOADER, Loader}};
use yazi_proxy::{AppProxy, options::{PluginMode, PluginOpt}};

use crate::{app::App, lives::Lives};
Expand All @@ -29,8 +29,9 @@ impl App {
}

tokio::spawn(async move {
if LOADER.ensure(&opt.id).await.is_ok() {
AppProxy::plugin_do(opt);
match LOADER.ensure(&opt.id).await {
Ok(()) => AppProxy::plugin_do(opt),
Err(e) => AppProxy::notify_error("Plugin load failed", e),
}
});
}
Expand All @@ -46,6 +47,10 @@ impl App {
return warn!("plugin `{}` not found", opt.id);
};

if let Err(e) = Loader::compatible_or_error(&opt.id, chunk) {
return AppProxy::notify_error("Incompatible plugin", e);
}

if opt.mode.auto_then(chunk.sync_entry) != PluginMode::Sync {
return self.cx.tasks.plugin_micro(opt);
}
Expand All @@ -57,7 +62,7 @@ impl App {
defer! { _ = LUA.named_registry_value::<RtRefMut>("rt").map(|mut r| r.pop()) }

let plugin = match LOADER.load_with(&LUA, &opt.id, chunk) {
Ok(plugin) => plugin,
Ok(t) => t,
Err(e) => return warn!("{e}"),
};
drop(loader);
Expand Down
2 changes: 1 addition & 1 deletion yazi-fm/src/term.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ mod cursor {
fn write_ansi(&self, f: &mut impl std::fmt::Write) -> std::fmt::Result {
let (shape, shape_blink) = match SHAPE.load(Ordering::Relaxed) {
u8::MAX => (0, false),
n => ((n.max(1) + 1) / 2, n.max(1) & 1 == 1),
n => (n.max(1).div_ceil(2), n.max(1) & 1 == 1),
};

let blink = BLINK.load(Ordering::Relaxed) ^ shape_blink;
Expand Down
15 changes: 14 additions & 1 deletion yazi-plugin/src/loader/chunk.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
use std::borrow::Cow;

use yazi_shared::natsort;

pub struct Chunk {
pub bytes: Cow<'static, [u8]>,
pub since: String,
pub sync_entry: bool,
}

impl Chunk {
#[inline]
pub fn as_bytes(&self) -> &[u8] { &self.bytes }

#[inline]
pub fn compatible(&self) -> bool {
let s = yazi_boot::actions::Actions::version();
natsort(s.as_bytes(), self.since.as_bytes(), false) != std::cmp::Ordering::Less
}

fn analyze(&mut self) {
for line in self.bytes.split(|&b| b == b'\n') {
if line.trim_ascii().is_empty() {
Expand All @@ -21,6 +30,10 @@ impl Chunk {
let Some(i) = rest.iter().position(|&b| b == b' ' || b == b'\t') else { break };
match (rest[..i].trim_ascii(), rest[i..].trim_ascii()) {
(b"@sync", b"entry") => self.sync_entry = true,

(b"@since", b"") => continue,
(b"@since", b) => self.since = String::from_utf8_lossy(b).to_string(),

(_, []) => break,
(b, _) if b.strip_prefix(b"@").unwrap_or(b"").is_empty() => break,
_ => continue,
Expand All @@ -31,7 +44,7 @@ impl Chunk {

impl From<Cow<'static, [u8]>> for Chunk {
fn from(b: Cow<'static, [u8]>) -> Self {
let mut chunk = Self { bytes: b, sync_entry: false };
let mut chunk = Self { bytes: b, since: String::new(), sync_entry: false };
chunk.analyze();
chunk
}
Expand Down
30 changes: 21 additions & 9 deletions yazi-plugin/src/loader/loader.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{collections::HashMap, ops::Deref};

use anyhow::{Context, Result};
use anyhow::{Context, Result, bail};
use mlua::{ExternalError, Lua, Table};
use parking_lot::RwLock;
use tokio::fs;
Expand Down Expand Up @@ -51,8 +51,8 @@ impl Default for Loader {

impl Loader {
pub async fn ensure(&self, name: &str) -> Result<()> {
if self.cache.read().contains_key(name) {
return Ok(());
if let Some(chunk) = self.cache.read().get(name) {
return Self::compatible_or_error(name, chunk);
}

// TODO: remove this
Expand Down Expand Up @@ -80,13 +80,14 @@ Please run `ya pack -m` to automatically migrate all plugins, or manually rename
Err(e) => Err(e).with_context(|| format!("Failed to load plugin from {p:?}"))?,
};

self.cache.write().insert(name.to_owned(), chunk.into());
Ok(())
let mut cache = self.cache.write();
cache.insert(name.to_owned(), chunk.into());
Self::compatible_or_error(name, cache.get(name).unwrap())
}

pub fn load(&self, lua: &Lua, id: &str) -> mlua::Result<Table> {
let loaded: Table = lua.globals().raw_get::<Table>("package")?.raw_get("loaded")?;
if let Ok(t) = loaded.raw_get::<Table>(id) {
if let Ok(t) = loaded.raw_get(id) {
return Ok(t);
}

Expand All @@ -101,13 +102,12 @@ Please run `ya pack -m` to automatically migrate all plugins, or manually rename
}

pub fn try_load(&self, lua: &Lua, id: &str) -> mlua::Result<Table> {
let loaded: Table = lua.globals().raw_get::<Table>("package")?.raw_get("loaded")?;
loaded.raw_get(id)
lua.globals().raw_get::<Table>("package")?.raw_get::<Table>("loaded")?.raw_get(id)
}

pub fn load_with(&self, lua: &Lua, id: &str, chunk: &Chunk) -> mlua::Result<Table> {
let loaded: Table = lua.globals().raw_get::<Table>("package")?.raw_get("loaded")?;
if let Ok(t) = loaded.raw_get::<Table>(id) {
if let Ok(t) = loaded.raw_get(id) {
return Ok(t);
}

Expand All @@ -117,4 +117,16 @@ Please run `ya pack -m` to automatically migrate all plugins, or manually rename
loaded.raw_set(id, t.clone())?;
Ok(t)
}

pub fn compatible_or_error(name: &str, chunk: &Chunk) -> Result<()> {
if chunk.compatible() {
return Ok(());
}

bail!(
"Plugin `{name}` requires at least Yazi {}, but your current version is Yazi {}.",
chunk.since,
yazi_boot::actions::Actions::version()
);
}
}
2 changes: 2 additions & 0 deletions yazi-plugin/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ macro_rules! impl_file_methods {
($methods:ident) => {
use mlua::UserDataMethods;

$methods.add_method("hash", |_, me, ()| Ok(me.hash()));

$methods.add_method("icon", |_, me, ()| {
use yazi_shared::theme::IconCache;
use $crate::bindings::Icon;
Expand Down
2 changes: 1 addition & 1 deletion yazi-proxy/src/options/notify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl TryFrom<mlua::Table> for NotifyOpt {
}
}

#[derive(Clone, Copy, Default)]
#[derive(Clone, Copy, Default, Eq, PartialEq)]
pub enum NotifyLevel {
#[default]
Info,
Expand Down
2 changes: 1 addition & 1 deletion yazi-scheduler/src/plugin/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl Plugin {
self.prog.send(TaskProg::New(task.id, 0))?;

if let Err(e) = isolate::entry(task.opt).await {
self.fail(task.id, format!("Micro plugin failed:\n{e}"))?;
self.fail(task.id, format!("Failed to run the plugin:\n{e}"))?;
return Ok(());
}

Expand Down

0 comments on commit b236f34

Please sign in to comment.