mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat!: new @sync peek annotation for sync previewers (#2487)
This commit is contained in:
parent
324a439c73
commit
8b3ce1838a
18 changed files with 125 additions and 126 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
|
@ -836,9 +836,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foldhash"
|
name = "foldhash"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "form_urlencoded"
|
name = "form_urlencoded"
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ clap = { version = "4.5.32", features = [ "derive" ] }
|
||||||
core-foundation-sys = "0.8.7"
|
core-foundation-sys = "0.8.7"
|
||||||
crossterm = { version = "0.28.1", features = [ "event-stream" ] }
|
crossterm = { version = "0.28.1", features = [ "event-stream" ] }
|
||||||
dirs = "6.0.0"
|
dirs = "6.0.0"
|
||||||
foldhash = "0.1.4"
|
foldhash = "0.1.5"
|
||||||
futures = "0.3.31"
|
futures = "0.3.31"
|
||||||
globset = "0.4.16"
|
globset = "0.4.16"
|
||||||
indexmap = { version = "2.8.0", features = [ "serde" ] }
|
indexmap = { version = "2.8.0", features = [ "serde" ] }
|
||||||
|
|
|
||||||
|
|
@ -30,13 +30,13 @@ keymap = [
|
||||||
{ on = "<PageDown>", run = "arrow 100%", desc = "Move cursor down one page" },
|
{ on = "<PageDown>", run = "arrow 100%", desc = "Move cursor down one page" },
|
||||||
|
|
||||||
{ on = [ "g", "g" ], run = "arrow top", desc = "Move cursor to the top" },
|
{ on = [ "g", "g" ], run = "arrow top", desc = "Move cursor to the top" },
|
||||||
{ on = "G", run = "arrow bot", desc = "Move cursor to the bottom" },
|
{ on = "G", run = "arrow bot", desc = "Move cursor to the bottom" },
|
||||||
|
|
||||||
# Navigation
|
# Navigation
|
||||||
{ on = "h", run = "leave", desc = "Go back to the parent directory" },
|
{ on = "h", run = "leave", desc = "Back to the parent directory" },
|
||||||
{ on = "l", run = "enter", desc = "Enter the child directory" },
|
{ on = "l", run = "enter", desc = "Enter the child directory" },
|
||||||
|
|
||||||
{ on = "<Left>", run = "leave", desc = "Go back to the parent directory" },
|
{ on = "<Left>", run = "leave", desc = "Back to the parent directory" },
|
||||||
{ on = "<Right>", run = "enter", desc = "Enter the child directory" },
|
{ on = "<Right>", run = "enter", desc = "Enter the child directory" },
|
||||||
|
|
||||||
{ on = "H", run = "back", desc = "Back to previous directory" },
|
{ on = "H", run = "back", desc = "Back to previous directory" },
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ preloaders = [
|
||||||
{ mime = "application/ms-opentype", run = "font" },
|
{ mime = "application/ms-opentype", run = "font" },
|
||||||
]
|
]
|
||||||
previewers = [
|
previewers = [
|
||||||
{ name = "*/", run = "folder", sync = true },
|
{ name = "*/", run = "folder" },
|
||||||
# Code
|
# Code
|
||||||
{ mime = "text/*", run = "code" },
|
{ mime = "text/*", run = "code" },
|
||||||
{ mime = "application/{mbox,javascript,wine-extension-ini}", run = "code" },
|
{ mime = "application/{mbox,javascript,wine-extension-ini}", run = "code" },
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,6 @@ pub struct Previewer {
|
||||||
pub name: Option<Pattern>,
|
pub name: Option<Pattern>,
|
||||||
pub mime: Option<Pattern>,
|
pub mime: Option<Pattern>,
|
||||||
pub run: Cmd,
|
pub run: Cmd,
|
||||||
#[serde(default)]
|
|
||||||
pub sync: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Previewer {
|
impl Previewer {
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,7 @@ impl Preview {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.abort();
|
self.abort();
|
||||||
if previewer.sync {
|
self.previewer_ct = isolate::peek(&previewer.run, file, mime, self.skip);
|
||||||
isolate::peek_sync(&previewer.run, file, mime, self.skip);
|
|
||||||
} else {
|
|
||||||
self.previewer_ct = Some(isolate::peek(&previewer.run, file, mime, self.skip));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn go_folder(&mut self, file: File, dir: Option<Cha>, force: bool) {
|
pub fn go_folder(&mut self, file: File, dir: Option<Cha>, force: bool) {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
match LOADER.ensure(&opt.id).await {
|
match LOADER.ensure(&opt.id, |_| ()).await {
|
||||||
Ok(()) => AppProxy::plugin_do(opt),
|
Ok(()) => AppProxy::plugin_do(opt),
|
||||||
Err(e) => AppProxy::notify_error("Plugin load failed", e),
|
Err(e) => AppProxy::notify_error("Plugin load failed", e),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,10 @@ impl Term {
|
||||||
execute!(
|
execute!(
|
||||||
TTY.writer(),
|
TTY.writer(),
|
||||||
screen::SetScreen(true),
|
screen::SetScreen(true),
|
||||||
Print(Mux::csi("\x1bP$q q\x1b\\")), // Request cursor shape (DECRQSS query for DECSCUSR)
|
Print("\x1bP$q q\x1b\\"), // Request cursor shape (DECRQSS query for DECSCUSR)
|
||||||
Print(Mux::csi("\x1b[?12$p")), // Request cursor blink status (DECSET)
|
Print(Mux::csi("\x1b[?12$p")), // Request cursor blink status (DECSET)
|
||||||
Print("\x1b[?u"), // Request keyboard enhancement flags (CSI u)
|
Print("\x1b[?u"), // Request keyboard enhancement flags (CSI u)
|
||||||
Print(Mux::csi("\x1b[0c")), // Request device attributes
|
Print(Mux::csi("\x1b[0c")), // Request device attributes
|
||||||
screen::SetScreen(false),
|
screen::SetScreen(false),
|
||||||
EnableBracketedPaste,
|
EnableBracketedPaste,
|
||||||
mouse::SetMouse(true),
|
mouse::SetMouse(true),
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
--- @sync peek
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
function M:peek(job)
|
function M:peek(job)
|
||||||
|
|
|
||||||
|
|
@ -29,16 +29,11 @@ impl<'a> Runtime<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn args(lua: &Lua) -> mlua::Result<Value> {
|
fn args(lua: &Lua) -> mlua::Result<Value> {
|
||||||
Composer::make(lua, 5, |lua, key| {
|
Composer::make(lua, 5, |lua, key| match key {
|
||||||
match key {
|
b"entries" => lua.create_sequence_from(ARGS.entries.iter().map(Url::from))?.into_lua(lua),
|
||||||
b"entries" => {
|
b"cwd_file" => ARGS.cwd_file.as_ref().map(Url::from).into_lua(lua),
|
||||||
lua.create_sequence_from(ARGS.entries.iter().map(Url::from))?.into_lua(lua)?
|
b"chooser_file" => ARGS.chooser_file.as_ref().map(Url::from).into_lua(lua),
|
||||||
}
|
_ => Ok(Value::Nil),
|
||||||
b"cwd_file" => ARGS.cwd_file.as_ref().map(Url::from).into_lua(lua)?,
|
|
||||||
b"chooser_file" => ARGS.chooser_file.as_ref().map(Url::from).into_lua(lua)?,
|
|
||||||
_ => return Ok(Value::Nil),
|
|
||||||
}
|
|
||||||
.into_lua(lua)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,12 @@ use super::slim_lua;
|
||||||
use crate::loader::LOADER;
|
use crate::loader::LOADER;
|
||||||
|
|
||||||
pub async fn entry(opt: PluginOpt) -> mlua::Result<()> {
|
pub async fn entry(opt: PluginOpt) -> mlua::Result<()> {
|
||||||
LOADER.ensure(&opt.id).await.into_lua_err()?;
|
LOADER.ensure(&opt.id, |_| ()).await.into_lua_err()?;
|
||||||
|
|
||||||
tokio::task::spawn_blocking(move || {
|
tokio::task::spawn_blocking(move || {
|
||||||
let lua = slim_lua(&opt.id)?;
|
let lua = slim_lua(&opt.id)?;
|
||||||
let plugin: Table = if let Some(b) = LOADER.read().get(opt.id.as_ref()) {
|
let plugin: Table = if let Some(c) = LOADER.read().get(opt.id.as_ref()) {
|
||||||
lua.load(b.as_bytes()).set_name(opt.id.as_ref()).call(())?
|
lua.load(c.as_bytes()).set_name(opt.id.as_ref()).call(())?
|
||||||
} else {
|
} else {
|
||||||
return Err("unloaded plugin".into_lua_err());
|
return Err("unloaded plugin".into_lua_err());
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,12 @@ pub async fn fetch(
|
||||||
if files.is_empty() {
|
if files.is_empty() {
|
||||||
return Ok((FetchState::Bool(true), None));
|
return Ok((FetchState::Bool(true), None));
|
||||||
}
|
}
|
||||||
LOADER.ensure(&cmd.name).await.into_lua_err()?;
|
LOADER.ensure(&cmd.name, |_| ()).await.into_lua_err()?;
|
||||||
|
|
||||||
tokio::task::spawn_blocking(move || {
|
tokio::task::spawn_blocking(move || {
|
||||||
let lua = slim_lua(&cmd.name)?;
|
let lua = slim_lua(&cmd.name)?;
|
||||||
let plugin: Table = if let Some(b) = LOADER.read().get(&cmd.name) {
|
let plugin: Table = if let Some(c) = LOADER.read().get(&cmd.name) {
|
||||||
lua.load(b.as_bytes()).set_name(&cmd.name).call(())?
|
lua.load(c.as_bytes()).set_name(&cmd.name).call(())?
|
||||||
} else {
|
} else {
|
||||||
return Err("unloaded plugin".into_lua_err());
|
return Err("unloaded plugin".into_lua_err());
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use mlua::{ExternalError, ExternalResult, HookTriggers, IntoLua, ObjectLike, Table, VmState};
|
use mlua::{ExternalError, HookTriggers, IntoLua, ObjectLike, Table, VmState};
|
||||||
use tokio::{runtime::Handle, select};
|
use tokio::{runtime::Handle, select};
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
@ -17,61 +17,36 @@ pub fn peek(
|
||||||
file: yazi_fs::File,
|
file: yazi_fs::File,
|
||||||
mime: Cow<'static, str>,
|
mime: Cow<'static, str>,
|
||||||
skip: usize,
|
skip: usize,
|
||||||
) -> CancellationToken {
|
) -> Option<CancellationToken> {
|
||||||
let ct = CancellationToken::new();
|
let ct = CancellationToken::new();
|
||||||
let (ct1, ct2) = (ct.clone(), ct.clone());
|
if let Some(c) = LOADER.read().get(&cmd.name) {
|
||||||
|
if c.sync_peek {
|
||||||
|
peek_sync(cmd, file, mime, skip);
|
||||||
|
} else {
|
||||||
|
peek_async(cmd, file, mime, skip, ct.clone());
|
||||||
|
}
|
||||||
|
return Some(ct).filter(|_| !c.sync_peek);
|
||||||
|
}
|
||||||
|
|
||||||
tokio::task::spawn_blocking(move || {
|
let ct_ = ct.clone();
|
||||||
let future = async {
|
tokio::spawn(async move {
|
||||||
LOADER.ensure(&cmd.name).await.into_lua_err()?;
|
select! {
|
||||||
|
_ = ct_.cancelled() => {},
|
||||||
let lua = slim_lua(&cmd.name)?;
|
Ok(b) = LOADER.ensure(&cmd.name, |c| c.sync_peek) => {
|
||||||
lua.set_hook(
|
if b {
|
||||||
HookTriggers::new().on_calls().on_returns().every_nth_instruction(2000),
|
peek_sync(cmd, file, mime, skip);
|
||||||
move |_, dbg| {
|
} else {
|
||||||
if ct1.is_cancelled() && dbg.source().what != "C" {
|
peek_async(cmd, file, mime, skip, ct_);
|
||||||
Err("Peek task cancelled".into_lua_err())
|
}
|
||||||
} else {
|
},
|
||||||
Ok(VmState::Continue)
|
else => {}
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let plugin: Table = if let Some(b) = LOADER.read().get(&cmd.name) {
|
|
||||||
lua.load(b.as_bytes()).set_name(&cmd.name).call(())?
|
|
||||||
} else {
|
|
||||||
return Err("unloaded plugin".into_lua_err());
|
|
||||||
};
|
|
||||||
|
|
||||||
let job = lua.create_table_from([
|
|
||||||
("area", Rect::from(LAYOUT.get().preview).into_lua(&lua)?),
|
|
||||||
("args", Sendable::args_to_table_ref(&lua, &cmd.args)?.into_lua(&lua)?),
|
|
||||||
("file", File(file).into_lua(&lua)?),
|
|
||||||
("mime", mime.into_lua(&lua)?),
|
|
||||||
("skip", skip.into_lua(&lua)?),
|
|
||||||
])?;
|
|
||||||
|
|
||||||
if ct2.is_cancelled() { Ok(()) } else { plugin.call_async_method("peek", job).await }
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = Handle::current().block_on(async {
|
|
||||||
select! {
|
|
||||||
_ = ct2.cancelled() => Ok(()),
|
|
||||||
r = future => r,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Err(e) = result {
|
|
||||||
if !e.to_string().contains("Peek task cancelled") {
|
|
||||||
error!("{e}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ct
|
Some(ct)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn peek_sync(cmd: &'static Cmd, file: yazi_fs::File, mime: Cow<'static, str>, skip: usize) {
|
fn peek_sync(cmd: &'static Cmd, file: yazi_fs::File, mime: Cow<'static, str>, skip: usize) {
|
||||||
let cb: PluginCallback = Box::new(move |lua, plugin| {
|
let cb: PluginCallback = Box::new(move |lua, plugin| {
|
||||||
let job = lua.create_table_from([
|
let job = lua.create_table_from([
|
||||||
("area", Rect::from(LAYOUT.get().preview).into_lua(lua)?),
|
("area", Rect::from(LAYOUT.get().preview).into_lua(lua)?),
|
||||||
|
|
@ -86,3 +61,57 @@ pub fn peek_sync(cmd: &'static Cmd, file: yazi_fs::File, mime: Cow<'static, str>
|
||||||
|
|
||||||
AppProxy::plugin(PluginOpt::new_callback(&cmd.name, cb));
|
AppProxy::plugin(PluginOpt::new_callback(&cmd.name, cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn peek_async(
|
||||||
|
cmd: &'static Cmd,
|
||||||
|
file: yazi_fs::File,
|
||||||
|
mime: Cow<'static, str>,
|
||||||
|
skip: usize,
|
||||||
|
ct: CancellationToken,
|
||||||
|
) {
|
||||||
|
let ct_ = ct.clone();
|
||||||
|
tokio::task::spawn_blocking(move || {
|
||||||
|
let future = async {
|
||||||
|
let lua = slim_lua(&cmd.name)?;
|
||||||
|
lua.set_hook(
|
||||||
|
HookTriggers::new().on_calls().on_returns().every_nth_instruction(2000),
|
||||||
|
move |_, dbg| {
|
||||||
|
if ct.is_cancelled() && dbg.source().what != "C" {
|
||||||
|
Err("Peek task cancelled".into_lua_err())
|
||||||
|
} else {
|
||||||
|
Ok(VmState::Continue)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let plugin: Table = if let Some(c) = LOADER.read().get(&cmd.name) {
|
||||||
|
lua.load(c.as_bytes()).set_name(&cmd.name).call(())?
|
||||||
|
} else {
|
||||||
|
return Err("unloaded plugin".into_lua_err());
|
||||||
|
};
|
||||||
|
|
||||||
|
let job = lua.create_table_from([
|
||||||
|
("area", Rect::from(LAYOUT.get().preview).into_lua(&lua)?),
|
||||||
|
("args", Sendable::args_to_table_ref(&lua, &cmd.args)?.into_lua(&lua)?),
|
||||||
|
("file", File(file).into_lua(&lua)?),
|
||||||
|
("mime", mime.into_lua(&lua)?),
|
||||||
|
("skip", skip.into_lua(&lua)?),
|
||||||
|
])?;
|
||||||
|
|
||||||
|
if ct_.is_cancelled() { Ok(()) } else { plugin.call_async_method("peek", job).await }
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = Handle::current().block_on(async {
|
||||||
|
select! {
|
||||||
|
_ = ct_.cancelled() => Ok(()),
|
||||||
|
r = future => r,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Err(e) = result {
|
||||||
|
if !e.to_string().contains("Peek task cancelled") {
|
||||||
|
error!("{e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ pub async fn preload(
|
||||||
cmd: &'static Cmd,
|
cmd: &'static Cmd,
|
||||||
file: yazi_fs::File,
|
file: yazi_fs::File,
|
||||||
) -> mlua::Result<(bool, Option<Error>)> {
|
) -> mlua::Result<(bool, Option<Error>)> {
|
||||||
LOADER.ensure(&cmd.name).await.into_lua_err()?;
|
LOADER.ensure(&cmd.name, |_| ()).await.into_lua_err()?;
|
||||||
|
|
||||||
tokio::task::spawn_blocking(move || {
|
tokio::task::spawn_blocking(move || {
|
||||||
let lua = slim_lua(&cmd.name)?;
|
let lua = slim_lua(&cmd.name)?;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ pub fn spot(
|
||||||
|
|
||||||
tokio::task::spawn_blocking(move || {
|
tokio::task::spawn_blocking(move || {
|
||||||
let future = async {
|
let future = async {
|
||||||
LOADER.ensure(&cmd.name).await.into_lua_err()?;
|
LOADER.ensure(&cmd.name, |_| ()).await.into_lua_err()?;
|
||||||
|
|
||||||
let lua = slim_lua(&cmd.name)?;
|
let lua = slim_lua(&cmd.name)?;
|
||||||
lua.set_hook(
|
lua.set_hook(
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ use yazi_shared::natsort;
|
||||||
pub struct Chunk {
|
pub struct Chunk {
|
||||||
pub bytes: Cow<'static, [u8]>,
|
pub bytes: Cow<'static, [u8]>,
|
||||||
pub since: String,
|
pub since: String,
|
||||||
|
pub sync_peek: bool,
|
||||||
pub sync_entry: bool,
|
pub sync_entry: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -29,6 +30,7 @@ impl Chunk {
|
||||||
|
|
||||||
let Some(i) = rest.iter().position(|&b| b == b' ' || b == b'\t') else { break };
|
let Some(i) = rest.iter().position(|&b| b == b' ' || b == b'\t') else { break };
|
||||||
match (rest[..i].trim_ascii(), rest[i..].trim_ascii()) {
|
match (rest[..i].trim_ascii(), rest[i..].trim_ascii()) {
|
||||||
|
(b"@sync", b"peek") => self.sync_peek = true,
|
||||||
(b"@sync", b"entry") => self.sync_entry = true,
|
(b"@sync", b"entry") => self.sync_entry = true,
|
||||||
|
|
||||||
(b"@since", b"") => continue,
|
(b"@since", b"") => continue,
|
||||||
|
|
@ -44,7 +46,8 @@ impl Chunk {
|
||||||
|
|
||||||
impl From<Cow<'static, [u8]>> for Chunk {
|
impl From<Cow<'static, [u8]>> for Chunk {
|
||||||
fn from(b: Cow<'static, [u8]>) -> Self {
|
fn from(b: Cow<'static, [u8]>) -> Self {
|
||||||
let mut chunk = Self { bytes: b, since: String::new(), sync_entry: false };
|
let mut chunk =
|
||||||
|
Self { bytes: b, since: String::new(), sync_entry: false, sync_peek: false };
|
||||||
chunk.analyze();
|
chunk.analyze();
|
||||||
chunk
|
chunk
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,47 +50,23 @@ impl Default for Loader {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Loader {
|
impl Loader {
|
||||||
pub async fn ensure(&self, name: &str) -> Result<()> {
|
pub async fn ensure<F, T>(&self, name: &str, f: F) -> Result<T>
|
||||||
if let Some(chunk) = self.cache.read().get(name) {
|
where
|
||||||
return Self::compatible_or_error(name, chunk);
|
F: FnOnce(&Chunk) -> T,
|
||||||
}
|
{
|
||||||
|
if let Some(c) = self.cache.read().get(name) {
|
||||||
// TODO: remove this
|
return Self::compatible_or_error(name, c).map(|_| f(c));
|
||||||
fn warn(name: &str) {
|
|
||||||
static WARNED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
|
|
||||||
if !WARNED.swap(true, std::sync::atomic::Ordering::Relaxed) {
|
|
||||||
yazi_proxy::AppProxy::notify(yazi_proxy::options::NotifyOpt {
|
|
||||||
title: "Deprecated entry file".to_owned(),
|
|
||||||
content: format!(
|
|
||||||
"The plugin's entry file `init.lua` has been deprecated in favor of the new `main.lua` (user's own `init.lua` remains unchanged).
|
|
||||||
|
|
||||||
Please run `ya pack -m` to automatically migrate all plugins, or manually rename your `{name}.yazi/init.lua` to `{name}.yazi/main.lua`."
|
|
||||||
),
|
|
||||||
level: yazi_proxy::options::NotifyLevel::Warn,
|
|
||||||
timeout: std::time::Duration::from_secs(25),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let p = BOOT.plugin_dir.join(format!("{name}.yazi/main.lua"));
|
let p = BOOT.plugin_dir.join(format!("{name}.yazi/main.lua"));
|
||||||
let chunk = match fs::read(&p).await {
|
let chunk =
|
||||||
Ok(b) => b,
|
fs::read(&p).await.with_context(|| format!("Failed to load plugin from {p:?}"))?.into();
|
||||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
|
|
||||||
let p = BOOT.plugin_dir.join(format!("{name}.yazi/init.lua"));
|
|
||||||
match fs::read(&p).await {
|
|
||||||
Ok(b) => {
|
|
||||||
warn(name);
|
|
||||||
b
|
|
||||||
}
|
|
||||||
Err(e) => Err(e).with_context(|| format!("Failed to load plugin from {p:?}"))?,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => Err(e).with_context(|| format!("Failed to load plugin from {p:?}"))?,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut cache = self.cache.write();
|
let result = Self::compatible_or_error(name, &chunk);
|
||||||
cache.insert(name.to_owned(), chunk.into());
|
let inspect = f(&chunk);
|
||||||
Self::compatible_or_error(name, cache.get(name).unwrap())
|
|
||||||
|
self.cache.write().insert(name.to_owned(), chunk);
|
||||||
|
result.map(|_| inspect)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load(&self, lua: &Lua, id: &str) -> mlua::Result<Table> {
|
pub fn load(&self, lua: &Lua, id: &str) -> mlua::Result<Table> {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ impl Require {
|
||||||
"require",
|
"require",
|
||||||
lua.create_function(|lua, id: mlua::String| {
|
lua.create_function(|lua, id: mlua::String| {
|
||||||
let s = &id.to_str()?;
|
let s = &id.to_str()?;
|
||||||
futures::executor::block_on(LOADER.ensure(s)).into_lua_err()?;
|
futures::executor::block_on(LOADER.ensure(s, |_| ())).into_lua_err()?;
|
||||||
|
|
||||||
lua.named_registry_value::<RtRefMut>("ir")?.push(s);
|
lua.named_registry_value::<RtRefMut>("ir")?.push(s);
|
||||||
let mod_ = LOADER.load(lua, s);
|
let mod_ = LOADER.load(lua, s);
|
||||||
|
|
@ -29,7 +29,7 @@ impl Require {
|
||||||
"require",
|
"require",
|
||||||
lua.create_async_function(|lua, id: mlua::String| async move {
|
lua.create_async_function(|lua, id: mlua::String| async move {
|
||||||
let s = &id.to_str()?;
|
let s = &id.to_str()?;
|
||||||
LOADER.ensure(s).await.into_lua_err()?;
|
LOADER.ensure(s, |_| ()).await.into_lua_err()?;
|
||||||
|
|
||||||
lua.named_registry_value::<RtRefMut>("ir")?.push(s);
|
lua.named_registry_value::<RtRefMut>("ir")?.push(s);
|
||||||
let mod_ = LOADER.load(&lua, s);
|
let mod_ = LOADER.load(&lua, s);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue