diff --git a/cspell.json b/cspell.json index 5631c351..d70d4760 100644 --- a/cspell.json +++ b/cspell.json @@ -1 +1 @@ -{"version":"0.2","flagWords":[],"language":"en","words":["Punct","KEYMAP","splitn","crossterm","YAZI","peekable","ratatui","syntect","pbpaste","pbcopy","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","Konsole","Überzug","pkgs","pdftoppm","poppler","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK","btime","nsec","codegen","gethostname","fchmod","fdfind","Rustc","rustc","ffprobe","vframes","luma","obase","outln","errln","tmtheme","twox","cfgs","fstype","objc","rdev","runloop","exfat","rclone","DECRQSS","DECSCUSR","libvterm","Uninit","lockin","rposition","resvg","foldhash","tilded","futs","chdir","hashbrown","JEMALLOC","RUSTFLAGS","RDONLY","GETPATH","fcntl","casefold","inodes","Splatable","casefied","thiserror","memchr","memmem","russh","deadpool","keepalive","nodelay","publickey","deadpool"]} \ No newline at end of file +{"flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","peekable","ratatui","syntect","pbpaste","pbcopy","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","Konsole","Überzug","pkgs","pdftoppm","poppler","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK","btime","nsec","codegen","gethostname","fchmod","fdfind","Rustc","rustc","ffprobe","vframes","luma","obase","outln","errln","tmtheme","twox","cfgs","fstype","objc","rdev","runloop","exfat","rclone","DECRQSS","DECSCUSR","libvterm","Uninit","lockin","rposition","resvg","foldhash","tilded","futs","chdir","hashbrown","JEMALLOC","RUSTFLAGS","RDONLY","GETPATH","fcntl","casefold","inodes","Splatable","casefied","thiserror","memchr","memmem","russh","deadpool","keepalive","nodelay","publickey","deadpool","initing"],"version":"0.2","language":"en"} \ No newline at end of file diff --git a/yazi-binding/src/runtime.rs b/yazi-binding/src/runtime.rs index db73b1c2..24c0ae96 100644 --- a/yazi-binding/src/runtime.rs +++ b/yazi-binding/src/runtime.rs @@ -3,10 +3,11 @@ use std::collections::VecDeque; use hashbrown::HashMap; use mlua::Function; -#[derive(Debug, Default)] +#[derive(Debug)] pub struct Runtime { - frames: VecDeque, - blocks: HashMap>, + frames: VecDeque, + blocks: HashMap>, + pub initing: bool, } #[derive(Debug)] @@ -16,10 +17,13 @@ struct RuntimeFrame { } impl Runtime { - pub fn new(id: &str) -> Self { + pub fn new() -> Self { Self { frames: <_>::default(), blocks: <_>::default(), initing: true } } + + pub fn new_isolate(id: &str) -> Self { Self { - frames: VecDeque::from([RuntimeFrame { id: id.to_owned(), calls: 0 }]), - ..Default::default() + frames: VecDeque::from([RuntimeFrame { id: id.to_owned(), calls: 0 }]), + blocks: <_>::default(), + initing: false, } } diff --git a/yazi-plugin/src/elements/elements.rs b/yazi-plugin/src/elements/elements.rs index a197865e..4fd14a1e 100644 --- a/yazi-plugin/src/elements/elements.rs +++ b/yazi-plugin/src/elements/elements.rs @@ -3,7 +3,7 @@ use std::borrow::Cow; use mlua::{AnyUserData, ExternalError, IntoLua, Lua, ObjectLike, Table, Value}; use tracing::error; use unicode_width::{UnicodeWidthChar, UnicodeWidthStr}; -use yazi_binding::{Composer, ComposerGet, ComposerSet, Permit, PermitRef, elements::{Line, Rect, Span}}; +use yazi_binding::{Composer, ComposerGet, ComposerSet, Permit, PermitRef, elements::{Line, Rect, Span}, runtime}; use yazi_config::LAYOUT; use yazi_proxy::{AppProxy, HIDER}; use yazi_shared::replace_to_printable; @@ -44,6 +44,10 @@ pub(super) fn area(lua: &Lua) -> mlua::Result { pub(super) fn hide(lua: &Lua) -> mlua::Result { 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 lua.named_registry_value::>("HIDE_PERMIT").is_ok_and(|h| h.is_some()) { return Err("Cannot hide while already hidden".into_lua_err()); } diff --git a/yazi-plugin/src/isolate/isolate.rs b/yazi-plugin/src/isolate/isolate.rs index c60098e3..afcd67ce 100644 --- a/yazi-plugin/src/isolate/isolate.rs +++ b/yazi-plugin/src/isolate/isolate.rs @@ -4,7 +4,7 @@ use yazi_macro::plugin_preset as preset; pub fn slim_lua(name: &str) -> mlua::Result { let lua = Lua::new(); - lua.set_app_data(Runtime::new(name)); + lua.set_app_data(Runtime::new_isolate(name)); // Base let globals = lua.globals(); diff --git a/yazi-plugin/src/lua.rs b/yazi-plugin/src/lua.rs index 42f40518..f0dea9f8 100644 --- a/yazi-plugin/src/lua.rs +++ b/yazi-plugin/src/lua.rs @@ -1,7 +1,7 @@ use anyhow::{Context, Result}; use futures::executor::block_on; use mlua::Lua; -use yazi_binding::Runtime; +use yazi_binding::{Runtime, runtime_mut}; use yazi_boot::BOOT; use yazi_macro::plugin_preset as preset; use yazi_shared::RoCell; @@ -17,7 +17,7 @@ pub(super) fn init_lua() -> Result<()> { } fn stage_1(lua: &'static Lua) -> Result<()> { - lua.set_app_data(Runtime::default()); + lua.set_app_data(Runtime::new()); // Base let globals = lua.globals(); @@ -67,5 +67,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; Ok(()) } diff --git a/yazi-plugin/src/utils/layer.rs b/yazi-plugin/src/utils/layer.rs index d09f8618..19a82b09 100644 --- a/yazi-plugin/src/utils/layer.rs +++ b/yazi-plugin/src/utils/layer.rs @@ -3,7 +3,7 @@ use std::{str::FromStr, time::Duration}; use mlua::{ExternalError, ExternalResult, Function, IntoLuaMulti, Lua, Table, Value}; use tokio::sync::mpsc; use tokio_stream::wrappers::UnboundedReceiverStream; -use yazi_binding::{deprecate, elements::{Line, Pos, Text}}; +use yazi_binding::{deprecate, elements::{Line, Pos, Text}, runtime}; use yazi_config::{keymap::{Chord, Key}, popup::{ConfirmCfg, InputCfg}}; use yazi_macro::relay; use yazi_parser::which::ShowOpt; @@ -15,20 +15,27 @@ use crate::bindings::InputRx; impl Utils { pub(super) fn which(lua: &Lua) -> mlua::Result { - lua.create_async_function(|_, t: Table| async move { - let (tx, mut rx) = mpsc::channel::(1); - - let mut cands = Vec::with_capacity(30); - for (i, cand) in t.raw_get::("cands")?.sequence_values::
().enumerate() { - let cand = cand?; - cands.push(Chord { - on: Self::parse_keys(cand.raw_get("on")?)?, - run: vec![relay!(which:callback, [i]).with_any("tx", tx.clone())], - desc: cand.raw_get("desc").ok(), - r#for: None, - }); + 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()); } + let (tx, mut rx) = mpsc::channel::(1); + let cands: Vec<_> = t + .raw_get::
("cands")? + .sequence_values::
() + .enumerate() + .map(|(i, cand)| { + let cand = cand?; + Ok(Chord { + on: Self::parse_keys(cand.raw_get("on")?)?, + run: vec![relay!(which:callback, [i]).with_any("tx", tx.clone())], + desc: cand.raw_get("desc").ok(), + r#for: None, + }) + }) + .collect::>()?; + drop(tx); WhichProxy::show(ShowOpt { cands, silent: t.raw_get("silent").unwrap_or_default() }); @@ -38,6 +45,10 @@ impl Utils { pub(super) fn input(lua: &Lua) -> mlua::Result { 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()); + } + let mut pos = t.raw_get::("pos")?; if pos.is_nil() { pos = t.raw_get("position")?; @@ -80,7 +91,11 @@ impl Utils { }) } - lua.create_async_function(|_, t: Table| async move { + 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()); + } + let result = ConfirmProxy::show(ConfirmCfg { position: Pos::try_from(t.raw_get::("pos")?)?.into(), title: Line::try_from(t.raw_get::("title")?)?.into(),