mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: experimental module-level async support (#3594)
This commit is contained in:
parent
e6d995710f
commit
d17e7e14cd
13 changed files with 41 additions and 39 deletions
|
|
@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
|||
- Tree view for the preset archive previewer ([#3525])
|
||||
- Support compressed tarballs (`.tar.gz`, `.tar.bz2`, etc.) in the preset archive previewer ([#3518])
|
||||
- Check and refresh the file list when the terminal gains focus ([#3561])
|
||||
- Experimental module-level async support ([#3594])
|
||||
- Disable ANSI escape sequences in `ya pkg` when stdout is not a TTY ([#3566])
|
||||
- New `Path.os()` API creates an OS-native `Path` ([#3541])
|
||||
|
||||
|
|
@ -1607,3 +1608,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
|||
[#3561]: https://github.com/sxyazi/yazi/pull/3561
|
||||
[#3566]: https://github.com/sxyazi/yazi/pull/3566
|
||||
[#3582]: https://github.com/sxyazi/yazi/pull/3582
|
||||
[#3594]: https://github.com/sxyazi/yazi/pull/3594
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ use mlua::Function;
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct Runtime {
|
||||
frames: VecDeque<RuntimeFrame>,
|
||||
blocks: HashMap<String, Vec<Function>>,
|
||||
pub initing: bool,
|
||||
frames: VecDeque<RuntimeFrame>,
|
||||
blocks: HashMap<String, Vec<Function>>,
|
||||
pub blocking: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -17,13 +17,13 @@ struct RuntimeFrame {
|
|||
}
|
||||
|
||||
impl Runtime {
|
||||
pub fn new() -> Self { Self { frames: <_>::default(), blocks: <_>::default(), initing: true } }
|
||||
pub fn new() -> Self { Self { frames: <_>::default(), blocks: <_>::default(), blocking: true } }
|
||||
|
||||
pub fn new_isolate(id: &str) -> Self {
|
||||
Self {
|
||||
frames: VecDeque::from([RuntimeFrame { id: id.to_owned(), calls: 0 }]),
|
||||
blocks: <_>::default(),
|
||||
initing: false,
|
||||
frames: VecDeque::from([RuntimeFrame { id: id.to_owned(), calls: 0 }]),
|
||||
blocks: <_>::default(),
|
||||
blocking: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -48,12 +48,12 @@ impl Runtime {
|
|||
self.blocks.get(id).and_then(|v| v.get(calls)).cloned()
|
||||
}
|
||||
|
||||
pub fn put_block(&mut self, f: Function) -> bool {
|
||||
pub fn put_block(&mut self, f: &Function) -> bool {
|
||||
let Some(cur) = self.frames.back() else { return false };
|
||||
if let Some(v) = self.blocks.get_mut(&cur.id) {
|
||||
v.push(f);
|
||||
v.push(f.clone());
|
||||
} else {
|
||||
self.blocks.insert(cur.id.clone(), vec![f]);
|
||||
self.blocks.insert(cur.id.clone(), vec![f.clone()]);
|
||||
}
|
||||
true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ pub(super) fn area(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
pub(super) fn hide(lua: &Lua) -> mlua::Result<Value> {
|
||||
let f = lua.create_async_function(|lua, ()| async move {
|
||||
if runtime!(lua)?.initing {
|
||||
return Err("Cannot call `ui.hide()` during app initialization".into_lua_err());
|
||||
if runtime!(lua)?.blocking {
|
||||
return Err("Cannot call `ui.hide()` while main thread is blocked".into_lua_err());
|
||||
}
|
||||
|
||||
if lua.named_registry_value::<PermitRef>("HIDE_PERMIT").is_ok_and(|h| h.is_some()) {
|
||||
|
|
|
|||
|
|
@ -11,10 +11,11 @@ pub async fn entry(opt: PluginOpt) -> mlua::Result<()> {
|
|||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let lua = slim_lua(&opt.id)?;
|
||||
let plugin = LOADER.load_once(&lua, &opt.id)?;
|
||||
|
||||
let job = lua.create_table_from([("args", Sendable::args_to_table(&lua, opt.args)?)])?;
|
||||
Handle::current().block_on(plugin.call_async_method("entry", job))
|
||||
|
||||
Handle::current().block_on(async {
|
||||
LOADER.load_once(&lua, &opt.id).await?.call_async_method("entry", job).await
|
||||
})
|
||||
})
|
||||
.await
|
||||
.into_lua_err()?
|
||||
|
|
|
|||
|
|
@ -18,15 +18,14 @@ pub async fn fetch(
|
|||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let lua = slim_lua(&cmd.name)?;
|
||||
let plugin = LOADER.load_once(&lua, &cmd.name)?;
|
||||
let job = lua.create_table_from([
|
||||
("args", Sendable::args_to_table_ref(&lua, &cmd.args)?.into_lua(&lua)?),
|
||||
("files", lua.create_sequence_from(files.into_iter().map(File::new))?.into_lua(&lua)?),
|
||||
])?;
|
||||
|
||||
Handle::current().block_on(plugin.call_async_method(
|
||||
"fetch",
|
||||
lua.create_table_from([
|
||||
("args", Sendable::args_to_table_ref(&lua, &cmd.args)?.into_lua(&lua)?),
|
||||
("files", lua.create_sequence_from(files.into_iter().map(File::new))?.into_lua(&lua)?),
|
||||
])?,
|
||||
))
|
||||
Handle::current().block_on(async {
|
||||
LOADER.load_once(&lua, &cmd.name).await?.call_async_method("fetch", job).await
|
||||
})
|
||||
})
|
||||
.await
|
||||
.into_lua_err()?
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ fn peek_async(
|
|||
},
|
||||
)?;
|
||||
|
||||
let plugin = LOADER.load_once(&lua, &cmd.name)?;
|
||||
let plugin = LOADER.load_once(&lua, &cmd.name).await?;
|
||||
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)?),
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ pub async fn preload(
|
|||
},
|
||||
)?;
|
||||
|
||||
let plugin = LOADER.load_once(&lua, &cmd.name)?;
|
||||
let plugin = LOADER.load_once(&lua, &cmd.name).await?;
|
||||
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)?),
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ pub fn spot(
|
|||
},
|
||||
)?;
|
||||
|
||||
let plugin = LOADER.load_once(&lua, &cmd.name)?;
|
||||
let plugin = LOADER.load_once(&lua, &cmd.name).await?;
|
||||
let job = lua.create_table_from([
|
||||
("id", Id(IDS.next()).into_lua(&lua)?),
|
||||
("args", Sendable::args_to_table_ref(&lua, &cmd.args)?.into_lua(&lua)?),
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ impl Loader {
|
|||
result.map(|_| inspect)
|
||||
}
|
||||
|
||||
pub fn load(&self, lua: &Lua, id: &str) -> mlua::Result<Table> {
|
||||
pub async fn load(&self, lua: &Lua, id: &str) -> mlua::Result<Table> {
|
||||
let (id, ..) = Self::normalize_id(id)?;
|
||||
|
||||
let loaded: Table = lua.globals().raw_get::<Table>("package")?.raw_get("loaded")?;
|
||||
|
|
@ -87,14 +87,14 @@ impl Loader {
|
|||
return Ok(t);
|
||||
}
|
||||
|
||||
let t = self.load_once(lua, id)?;
|
||||
let t = self.load_once(lua, id).await?;
|
||||
t.raw_set("_id", lua.create_string(id)?)?;
|
||||
|
||||
loaded.raw_set(id, t.clone())?;
|
||||
Ok(t)
|
||||
}
|
||||
|
||||
pub fn load_once(&self, lua: &Lua, id: &str) -> mlua::Result<Table> {
|
||||
pub async fn load_once(&self, lua: &Lua, id: &str) -> mlua::Result<Table> {
|
||||
let (id, ..) = Self::normalize_id(id)?;
|
||||
|
||||
let mut mode = ChunkMode::Text;
|
||||
|
|
@ -114,7 +114,7 @@ impl Loader {
|
|||
}
|
||||
}
|
||||
|
||||
f.call(())
|
||||
f.call_async(()).await
|
||||
}
|
||||
|
||||
pub fn try_load(&self, lua: &Lua, id: &str) -> mlua::Result<Table> {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ impl Require {
|
|||
LOADER.ensure(&id, |_| ()).await.into_lua_err()?;
|
||||
|
||||
runtime_mut!(lua)?.push(&id);
|
||||
let mod_ = LOADER.load(&lua, &id);
|
||||
let mod_ = LOADER.load(&lua, &id).await;
|
||||
runtime_mut!(lua)?.pop();
|
||||
|
||||
Self::create_mt(&lua, id.into_owned(), mod_?)
|
||||
|
|
|
|||
|
|
@ -68,6 +68,6 @@ fn stage_2(lua: &'static Lua) -> mlua::Result<()> {
|
|||
block_on(lua.load(b).set_name("init.lua").exec_async())?;
|
||||
}
|
||||
|
||||
runtime_mut!(lua)?.initing = false;
|
||||
runtime_mut!(lua)?.blocking = false;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ use crate::bindings::InputRx;
|
|||
impl Utils {
|
||||
pub(super) fn which(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_async_function(|lua, t: Table| async move {
|
||||
if runtime!(lua)?.initing {
|
||||
return Err("Cannot call `ya.which()` during app initialization".into_lua_err());
|
||||
if runtime!(lua)?.blocking {
|
||||
return Err("Cannot call `ya.which()` while main thread is blocked".into_lua_err());
|
||||
}
|
||||
|
||||
let (tx, mut rx) = mpsc::channel::<usize>(1);
|
||||
|
|
@ -45,8 +45,8 @@ impl Utils {
|
|||
|
||||
pub(super) fn input(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_async_function(|lua, t: Table| async move {
|
||||
if runtime!(lua)?.initing {
|
||||
return Err("Cannot call `ya.input()` during app initialization".into_lua_err());
|
||||
if runtime!(lua)?.blocking {
|
||||
return Err("Cannot call `ya.input()` while main thread is blocked".into_lua_err());
|
||||
}
|
||||
|
||||
let mut pos = t.raw_get::<Value>("pos")?;
|
||||
|
|
@ -92,8 +92,8 @@ impl Utils {
|
|||
}
|
||||
|
||||
lua.create_async_function(|lua, t: Table| async move {
|
||||
if runtime!(lua)?.initing {
|
||||
return Err("Cannot call `ya.confirm()` during app initialization".into_lua_err());
|
||||
if runtime!(lua)?.blocking {
|
||||
return Err("Cannot call `ya.confirm()` while main thread is blocked".into_lua_err());
|
||||
}
|
||||
|
||||
let result = ConfirmProxy::show(ConfirmCfg {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ impl Utils {
|
|||
} else {
|
||||
lua.create_function(|lua, f: Function| {
|
||||
let mut rt = runtime_mut!(lua)?;
|
||||
if !rt.put_block(f.clone()) {
|
||||
if !rt.put_block(&f) {
|
||||
return Err("`ya.sync()` must be called in a plugin").into_lua_err();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue