diff --git a/Cargo.lock b/Cargo.lock index 7c8669dc..06652881 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -211,6 +211,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" dependencies = [ "rustversion", + "serde", ] [[package]] @@ -2130,7 +2131,7 @@ checksum = "ae8e22120c32fb4d19ec55fba35015f57095cd95a2e3b732e44457f5915b2ee8" dependencies = [ "num-integer", "num-traits", - "rand 0.10.0", + "rand 0.10.1", "rand_core 0.10.0", ] @@ -3431,9 +3432,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "7ec095654a25171c2124e9e3393a930bddbffdc939556c914957a4c3e0a87166" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.5", @@ -3441,9 +3442,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8" +checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" dependencies = [ "chacha20 0.10.0", "getrandom 0.4.2", @@ -3623,7 +3624,7 @@ dependencies = [ "num-traits", "paste", "profiling", - "rand 0.9.2", + "rand 0.9.3", "rand_chacha 0.9.0", "simd_helpers", "thiserror 2.0.18", @@ -3828,7 +3829,7 @@ dependencies = [ "pkcs5", "pkcs8", "polyval 0.7.1", - "rand 0.10.0", + "rand 0.10.1", "rand_core 0.10.0", "ring", "rsa", @@ -4864,7 +4865,7 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" dependencies = [ - "rand 0.9.2", + "rand 0.9.3", ] [[package]] @@ -5908,6 +5909,7 @@ name = "yazi-config" version = "26.2.2" dependencies = [ "anyhow", + "arc-swap", "bitflags 2.11.0", "crossterm 0.29.0", "globset", @@ -5916,6 +5918,7 @@ dependencies = [ "ratatui", "regex", "serde", + "serde_with", "strum 0.28.0", "tokio", "toml", @@ -5924,6 +5927,7 @@ dependencies = [ "yazi-fs", "yazi-macro", "yazi-shared", + "yazi-shim", "yazi-tty", ] @@ -6076,7 +6080,7 @@ dependencies = [ "objc2", "parking_lot", "percent-encoding", - "rand 0.10.0", + "rand 0.10.1", "regex", "scopeguard", "serde", @@ -6278,8 +6282,12 @@ dependencies = [ name = "yazi-shim" version = "26.2.2" dependencies = [ + "arc-swap", "crossterm 0.29.0", "ratatui", + "serde", + "thiserror 2.0.18", + "toml", "twox-hash", "unicode-segmentation", "unicode-width", diff --git a/Cargo.toml b/Cargo.toml index 6acc8042..6cd9f1ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ debug = false [workspace.dependencies] ansi-to-tui = "8.0.1" anyhow = "1.0.102" -arc-swap = "1.9.1" +arc-swap = { version = "1.9.1", features = [ "serde" ] } base64 = "0.22.1" bitflags = { version = "2.11.0", features = [ "serde" ] } chrono = "0.4.44" @@ -60,7 +60,7 @@ ordered-float = { version = "5.3.0", features = [ "serde" ] } parking_lot = "0.12.5" paste = "1.0.15" percent-encoding = "2.3.2" -rand = { version = "0.10.0", default-features = false, features = [ "std", "sys_rng" ] } +rand = { version = "0.10.1", default-features = false, features = [ "std", "sys_rng" ] } ratatui = { version = "0.30.0", features = [ "serde", "unstable-rendered-line-info", "unstable-widget-ref" ] } regex = "1.12.3" russh = { version = "0.60.0", default-features = false, features = [ "ring", "rsa" ] } diff --git a/README.md b/README.md index e1f46cea..63e6513a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@
Special thanks to:
-|Warp sponsorship
Warp, built for coding with multiple AI agents
Available for macOS, Linux and Windows
| -|-| +| Warp sponsorship
Warp, built for coding with multiple AI agents
Available for macOS, Linux and Windows
| +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -47,24 +47,24 @@ Yazi is currently in heavy development, expect breaking changes. ## Image Preview -| Platform | Protocol | Support | -| ---------------------------------------------------------------------------- | -------------------------------------- | ---------------------------------------- | -| [kitty](https://github.com/kovidgoyal/kitty) (>= 0.28.0) | [Kitty unicode placeholders][kgp] | ✅ Built-in | -| [iTerm2](https://iterm2.com) | [Inline images protocol][iip] | ✅ Built-in | -| [WezTerm](https://github.com/wez/wezterm) | [Inline images protocol][iip] | ✅ Built-in | -| [Konsole](https://invent.kde.org/utilities/konsole) | [Kitty old protocol][kgp-old] | ✅ Built-in | -| [foot](https://codeberg.org/dnkl/foot) | [Sixel graphics format][sixel] | ✅ Built-in | -| [Ghostty](https://github.com/ghostty-org/ghostty) | [Kitty unicode placeholders][kgp] | ✅ Built-in | -| [Windows Terminal](https://github.com/microsoft/terminal) (>= v1.22.10352.0) | [Sixel graphics format][sixel] | ✅ Built-in | -| [st with Sixel patch](https://github.com/bakkeby/st-flexipatch) | [Sixel graphics format][sixel] | ✅ Built-in | -| [Warp](https://www.warp.dev) (macOS/Linux only) | [Inline images protocol][iip] | ✅ Built-in | -| [Tabby](https://github.com/Eugeny/tabby) | [Inline images protocol][iip] | ✅ Built-in | -| [VSCode](https://github.com/microsoft/vscode) | [Inline images protocol][iip] | ✅ Built-in | -| [Rio](https://github.com/raphamorim/rio) | [Inline images protocol][iip] | ❌ Rio renders images at incorrect sizes | -| [Black Box](https://gitlab.gnome.org/raggesilver/blackbox) | [Sixel graphics format][sixel] | ✅ Built-in | -| [Bobcat](https://github.com/ismail-yilmaz/Bobcat) | [Inline images protocol][iip] | ✅ Built-in | -| X11 / Wayland | Window system protocol | ☑️ [Überzug++][ueberzug] required | -| Fallback | [ASCII art (Unicode block)][ascii-art] | ☑️ [Chafa][chafa] required (>= 1.16.0) | +| Platform | Protocol | Support | +| ---------------------------------------------------------------------------- | -------------------------------------- | -------------------------------------- | +| [kitty](https://github.com/kovidgoyal/kitty) (>= 0.28.0) | [Kitty unicode placeholders][kgp] | ✅ Built-in | +| [iTerm2](https://iterm2.com) | [Inline images protocol][iip] | ✅ Built-in | +| [WezTerm](https://github.com/wez/wezterm) | [Inline images protocol][iip] | ✅ Built-in | +| [Konsole](https://invent.kde.org/utilities/konsole) | [Kitty old protocol][kgp-old] | ✅ Built-in | +| [foot](https://codeberg.org/dnkl/foot) | [Sixel graphics format][sixel] | ✅ Built-in | +| [Ghostty](https://github.com/ghostty-org/ghostty) | [Kitty unicode placeholders][kgp] | ✅ Built-in | +| [Windows Terminal](https://github.com/microsoft/terminal) (>= v1.22.10352.0) | [Sixel graphics format][sixel] | ✅ Built-in | +| [st with Sixel patch](https://github.com/bakkeby/st-flexipatch) | [Sixel graphics format][sixel] | ✅ Built-in | +| [Warp](https://www.warp.dev) (macOS/Linux only) | [Inline images protocol][iip] | ✅ Built-in | +| [Tabby](https://github.com/Eugeny/tabby) | [Inline images protocol][iip] | ✅ Built-in | +| [VSCode](https://github.com/microsoft/vscode) | [Inline images protocol][iip] | ✅ Built-in | +| [Rio](https://github.com/raphamorim/rio) (>= 0.3.9) | [Kitty unicode placeholders][kgp] | ✅ Built-in | +| [Black Box](https://gitlab.gnome.org/raggesilver/blackbox) | [Sixel graphics format][sixel] | ✅ Built-in | +| [Bobcat](https://github.com/ismail-yilmaz/Bobcat) | [Inline images protocol][iip] | ✅ Built-in | +| X11 / Wayland | Window system protocol | ☑️ [Überzug++][ueberzug] required | +| Fallback | [ASCII art (Unicode block)][ascii-art] | ☑️ [Chafa][chafa] required (>= 1.16.0) | See https://yazi-rs.github.io/docs/image-preview for details. diff --git a/cspell.json b/cspell.json index 3fc3d927..e5d69993 100644 --- a/cspell.json +++ b/cspell.json @@ -1 +1 @@ -{"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","treelize","TOCTOU","fellback","watchee","Textlike","sstr"],"flagWords":[],"language":"en","version":"0.2"} \ No newline at end of file +{"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","treelize","TOCTOU","fellback","watchee","Textlike","sstr","pointee"],"version":"0.2","language":"en","flagWords":[]} \ No newline at end of file diff --git a/yazi-actor/src/mgr/seek.rs b/yazi-actor/src/mgr/seek.rs index 6e0ed78d..fde0477a 100644 --- a/yazi-actor/src/mgr/seek.rs +++ b/yazi-actor/src/mgr/seek.rs @@ -25,12 +25,12 @@ impl Actor for Seek { succ!(cx.tab_mut().preview.reset()); }; - let Some(previewer) = YAZI.plugin.previewer(hovered, mime) else { + let Some(previewer) = YAZI.plugin.previewers.matches(hovered, mime) else { succ!(cx.tab_mut().preview.reset()); }; let job = SeekJob { file: hovered.clone(), units: form.units }; - let opt = PluginOpt::new_callback(&*previewer.run.name, move |_, plugin| { + let opt = PluginOpt::new_callback(previewer.name.clone(), move |_, plugin| { plugin.call_method("seek", job) }); act!(app:plugin, cx, opt) diff --git a/yazi-adapter/src/adapters.rs b/yazi-adapter/src/adapters.rs index 36b50e71..77912c41 100644 --- a/yazi-adapter/src/adapters.rs +++ b/yazi-adapter/src/adapters.rs @@ -33,7 +33,7 @@ impl From for Adapters { B::Ghostty => vec![A::Kgp], B::Microsoft => vec![A::Sixel], B::Warp => vec![A::Iip, A::KgpOld], - B::Rio => vec![A::Iip, A::Sixel], + B::Rio => vec![A::Kgp], B::BlackBox => vec![A::Sixel], B::VSCode => vec![A::Iip, A::Sixel], B::Tabby => vec![A::Iip, A::Sixel], diff --git a/yazi-binding/src/access.rs b/yazi-binding/src/access.rs index bb8a1d85..1134d982 100644 --- a/yazi-binding/src/access.rs +++ b/yazi-binding/src/access.rs @@ -8,15 +8,15 @@ pub struct Access(yazi_vfs::provider::Gate); impl UserData for Access { fn add_methods>(methods: &mut M) { - methods.add_function_mut("append", |_, (ud, append): (AnyUserData, bool)| { + methods.add_function("append", |_, (ud, append): (AnyUserData, bool)| { ud.borrow_mut::()?.0.append(append); Ok(ud) }); - methods.add_function_mut("create", |_, (ud, create): (AnyUserData, bool)| { + methods.add_function("create", |_, (ud, create): (AnyUserData, bool)| { ud.borrow_mut::()?.0.create(create); Ok(ud) }); - methods.add_function_mut("create_new", |_, (ud, create_new): (AnyUserData, bool)| { + methods.add_function("create_new", |_, (ud, create_new): (AnyUserData, bool)| { ud.borrow_mut::()?.0.create_new(create_new); Ok(ud) }); @@ -26,15 +26,15 @@ impl UserData for Access { Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua), } }); - methods.add_function_mut("read", |_, (ud, read): (AnyUserData, bool)| { + methods.add_function("read", |_, (ud, read): (AnyUserData, bool)| { ud.borrow_mut::()?.0.read(read); Ok(ud) }); - methods.add_function_mut("truncate", |_, (ud, truncate): (AnyUserData, bool)| { + methods.add_function("truncate", |_, (ud, truncate): (AnyUserData, bool)| { ud.borrow_mut::()?.0.truncate(truncate); Ok(ud) }); - methods.add_function_mut("write", |_, (ud, write): (AnyUserData, bool)| { + methods.add_function("write", |_, (ud, write): (AnyUserData, bool)| { ud.borrow_mut::()?.0.write(write); Ok(ud) }); diff --git a/yazi-binding/src/config/fetcher.rs b/yazi-binding/src/config/fetcher.rs new file mode 100644 index 00000000..eb2d799e --- /dev/null +++ b/yazi-binding/src/config/fetcher.rs @@ -0,0 +1,32 @@ +use std::{ops::Deref, sync::Arc}; + +use mlua::{UserData, UserDataFields, Value}; + +use crate::{Id, cached_field}; + +#[derive(Clone)] +pub struct Fetcher { + inner: Arc, + + v_name: Option, +} + +impl Deref for Fetcher { + type Target = yazi_config::plugin::Fetcher; + + fn deref(&self) -> &Self::Target { &self.inner } +} + +impl Fetcher { + pub fn new(inner: impl Into>) -> Self { + Self { inner: inner.into(), v_name: None } + } +} + +impl UserData for Fetcher { + fn add_fields>(fields: &mut F) { + fields.add_field_method_get("id", |_, me| Ok(Id(me.id))); + + cached_field!(fields, name, |lua, me| lua.create_string(&*me.name)); + } +} diff --git a/yazi-binding/src/config/fetchers.rs b/yazi-binding/src/config/fetchers.rs new file mode 100644 index 00000000..7b8f6885 --- /dev/null +++ b/yazi-binding/src/config/fetchers.rs @@ -0,0 +1,51 @@ +use mlua::{ExternalError, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value}; +use yazi_config::YAZI; + +use crate::{FileRef, Id, Iter, config::Fetcher}; + +pub struct Fetchers; + +impl UserData for Fetchers { + fn add_methods>(methods: &mut M) { + methods.add_method("match", |_, _, matcher: FetcherMatcher| Ok(matcher)); + + methods.add_meta_method(MetaMethod::Len, |_, _, ()| Ok(YAZI.plugin.fetchers.load().len())); + } +} + +// --- Matcher +pub struct FetcherMatcher(yazi_config::plugin::FetcherMatcher<'static>); + +impl TryFrom for FetcherMatcher { + type Error = mlua::Error; + + fn try_from(value: Table) -> Result { + let id: Id = value.raw_get("id").unwrap_or_default(); + let file: Option = value.raw_get("file")?; + let mime: Option = value.raw_get("mime")?; + + Ok(Self(yazi_config::plugin::FetcherMatcher { + fetchers: YAZI.plugin.fetchers.load_full(), + id: id.0, + file: file.map(|f| f.inner.clone().into()), + mime: mime.map(Into::into), + offset: 0, + seen: Default::default(), + })) + } +} + +impl FromLua for FetcherMatcher { + fn from_lua(value: Value, _: &Lua) -> mlua::Result { + match value { + Value::Table(t) => t.try_into(), + _ => return Err("expected a table of FetcherMatcher".into_lua_err()), + } + } +} + +impl IntoLua for FetcherMatcher { + fn into_lua(self, lua: &Lua) -> mlua::Result { + Iter::new(self.0.into_iter().map(Fetcher::new), None).into_lua(lua) + } +} diff --git a/yazi-binding/src/config/mod.rs b/yazi-binding/src/config/mod.rs new file mode 100644 index 00000000..5d106eb4 --- /dev/null +++ b/yazi-binding/src/config/mod.rs @@ -0,0 +1 @@ +yazi_macro::mod_flat!(fetcher fetchers preloader preloaders previewer previewers spotter spotters); diff --git a/yazi-binding/src/config/preloader.rs b/yazi-binding/src/config/preloader.rs new file mode 100644 index 00000000..08403d5a --- /dev/null +++ b/yazi-binding/src/config/preloader.rs @@ -0,0 +1,32 @@ +use std::{ops::Deref, sync::Arc}; + +use mlua::{UserData, UserDataFields, Value}; + +use crate::{Id, cached_field}; + +#[derive(Clone)] +pub struct Preloader { + inner: Arc, + + v_name: Option, +} + +impl Deref for Preloader { + type Target = yazi_config::plugin::Preloader; + + fn deref(&self) -> &Self::Target { &self.inner } +} + +impl Preloader { + pub fn new(inner: impl Into>) -> Self { + Self { inner: inner.into(), v_name: None } + } +} + +impl UserData for Preloader { + fn add_fields>(fields: &mut F) { + fields.add_field_method_get("id", |_, me| Ok(Id(me.id))); + + cached_field!(fields, name, |lua, me| lua.create_string(&*me.name)); + } +} diff --git a/yazi-binding/src/config/preloaders.rs b/yazi-binding/src/config/preloaders.rs new file mode 100644 index 00000000..7e9348a3 --- /dev/null +++ b/yazi-binding/src/config/preloaders.rs @@ -0,0 +1,51 @@ +use mlua::{ExternalError, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value}; +use yazi_config::YAZI; + +use crate::{FileRef, Id, Iter, config::Preloader}; + +pub struct Preloaders; + +impl UserData for Preloaders { + fn add_methods>(methods: &mut M) { + methods.add_method("match", |_, _, matcher: PreloaderMatcher| Ok(matcher)); + + methods.add_meta_method(MetaMethod::Len, |_, _, ()| Ok(YAZI.plugin.preloaders.load().len())); + } +} + +// --- Matcher +pub struct PreloaderMatcher(yazi_config::plugin::PreloaderMatcher<'static>); + +impl TryFrom
for PreloaderMatcher { + type Error = mlua::Error; + + fn try_from(value: Table) -> Result { + let id: Id = value.raw_get("id").unwrap_or_default(); + let file: Option = value.raw_get("file")?; + let mime: Option = value.raw_get("mime")?; + + Ok(Self(yazi_config::plugin::PreloaderMatcher { + preloaders: YAZI.plugin.preloaders.load_full(), + id: id.0, + file: file.map(|f| f.inner.clone().into()), + mime: mime.map(Into::into), + offset: 0, + next: true, + })) + } +} + +impl FromLua for PreloaderMatcher { + fn from_lua(value: Value, _: &Lua) -> mlua::Result { + match value { + Value::Table(t) => t.try_into(), + _ => return Err("expected a table of PreloaderMatcher".into_lua_err()), + } + } +} + +impl IntoLua for PreloaderMatcher { + fn into_lua(self, lua: &Lua) -> mlua::Result { + Iter::new(self.0.into_iter().map(Preloader::new), None).into_lua(lua) + } +} diff --git a/yazi-binding/src/config/previewer.rs b/yazi-binding/src/config/previewer.rs new file mode 100644 index 00000000..07190a66 --- /dev/null +++ b/yazi-binding/src/config/previewer.rs @@ -0,0 +1,70 @@ +use std::{ops::Deref, sync::Arc}; + +use mlua::{AnyUserData, ExternalError, FromLua, Lua, UserData, UserDataFields, Value}; +use yazi_config::plugin::previewer_id; + +use crate::{Id, cached_field}; + +const EXPECTED: &str = "expected a table or Previewer"; + +#[derive(Clone)] +pub struct Previewer { + inner: Arc, + + v_name: Option, +} + +impl Deref for Previewer { + type Target = yazi_config::plugin::Previewer; + + fn deref(&self) -> &Self::Target { &self.inner } +} + +impl From for Arc { + fn from(value: Previewer) -> Self { value.inner } +} + +impl Previewer { + pub fn new(inner: impl Into>) -> Self { + Self { inner: inner.into(), v_name: None } + } +} + +impl TryFrom for Previewer { + type Error = mlua::Error; + + fn try_from(t: mlua::Table) -> Result { + Ok(Self::new(yazi_config::plugin::Previewer { + id: previewer_id(), + url: t.raw_get::>("url")?.map(|s| s.to_str()?.parse()).transpose()?, + mime: t.raw_get::>("mime")?.map(|s| s.to_str()?.parse()).transpose()?, + run: t.raw_get::("run")?.to_str()?.parse()?, + })) + } +} + +impl TryFrom for Previewer { + type Error = mlua::Error; + + fn try_from(value: AnyUserData) -> Result { + Ok(Self::new(value.borrow::()?.clone())) + } +} + +impl FromLua for Previewer { + fn from_lua(value: Value, _: &Lua) -> mlua::Result { + match value { + Value::Table(tbl) => Self::try_from(tbl), + Value::UserData(ud) => Self::try_from(ud), + _ => Err(EXPECTED.into_lua_err())?, + } + } +} + +impl UserData for Previewer { + fn add_fields>(fields: &mut F) { + fields.add_field_method_get("id", |_, me| Ok(Id(me.id))); + + cached_field!(fields, name, |lua, me| lua.create_string(&*me.name)); + } +} diff --git a/yazi-binding/src/config/previewers.rs b/yazi-binding/src/config/previewers.rs new file mode 100644 index 00000000..71564a6b --- /dev/null +++ b/yazi-binding/src/config/previewers.rs @@ -0,0 +1,66 @@ +use mlua::{ExternalError, ExternalResult, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value}; +use yazi_config::YAZI; + +use crate::{FileRef, Id, Iter, config::Previewer}; + +pub struct Previewers; + +impl UserData for Previewers { + fn add_methods>(methods: &mut M) { + methods.add_method("match", |_, _, matcher: PreviewerMatcher| Ok(matcher)); + + methods.add_method("insert", |_, _, (index, previewer): (isize, Previewer)| { + let index = match index { + 1.. => index - 1, + 0 => return Err("index must be 1-based or negative".into_lua_err()), + _ => index, + }; + + YAZI.plugin.previewers.insert(index, previewer.clone().into()).into_lua_err()?; + Ok(previewer) + }); + + methods.add_method("remove", |_, _, matcher: PreviewerMatcher| { + YAZI.plugin.previewers.remove(matcher.0); + Ok(()) + }); + + methods.add_meta_method(MetaMethod::Len, |_, _, ()| Ok(YAZI.plugin.previewers.load().len())); + } +} + +// --- Matcher +pub struct PreviewerMatcher(yazi_config::plugin::PreviewerMatcher<'static>); + +impl TryFrom
for PreviewerMatcher { + type Error = mlua::Error; + + fn try_from(value: Table) -> Result { + let id: Id = value.raw_get("id").unwrap_or_default(); + let file: Option = value.raw_get("file")?; + let mime: Option = value.raw_get("mime")?; + + Ok(Self(yazi_config::plugin::PreviewerMatcher { + previewers: YAZI.plugin.previewers.load_full(), + id: id.0, + file: file.map(|f| f.inner.clone().into()), + mime: mime.map(Into::into), + offset: 0, + })) + } +} + +impl FromLua for PreviewerMatcher { + fn from_lua(value: Value, _: &Lua) -> mlua::Result { + match value { + Value::Table(t) => t.try_into(), + _ => return Err("expected a table of PreviewerMatcher".into_lua_err()), + } + } +} + +impl IntoLua for PreviewerMatcher { + fn into_lua(self, lua: &Lua) -> mlua::Result { + Iter::new(self.0.into_iter().map(Previewer::new), None).into_lua(lua) + } +} diff --git a/yazi-binding/src/config/spotter.rs b/yazi-binding/src/config/spotter.rs new file mode 100644 index 00000000..be0ea1c4 --- /dev/null +++ b/yazi-binding/src/config/spotter.rs @@ -0,0 +1,32 @@ +use std::{ops::Deref, sync::Arc}; + +use mlua::{UserData, UserDataFields, Value}; + +use crate::{Id, cached_field}; + +#[derive(Clone)] +pub struct Spotter { + inner: Arc, + + v_name: Option, +} + +impl Deref for Spotter { + type Target = yazi_config::plugin::Spotter; + + fn deref(&self) -> &Self::Target { &self.inner } +} + +impl Spotter { + pub fn new(inner: impl Into>) -> Self { + Self { inner: inner.into(), v_name: None } + } +} + +impl UserData for Spotter { + fn add_fields>(fields: &mut F) { + fields.add_field_method_get("id", |_, me| Ok(Id(me.id))); + + cached_field!(fields, name, |lua, me| lua.create_string(&*me.name)); + } +} diff --git a/yazi-binding/src/config/spotters.rs b/yazi-binding/src/config/spotters.rs new file mode 100644 index 00000000..6f4028df --- /dev/null +++ b/yazi-binding/src/config/spotters.rs @@ -0,0 +1,50 @@ +use mlua::{ExternalError, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value}; +use yazi_config::YAZI; + +use crate::{FileRef, Id, Iter, config::Spotter}; + +pub struct Spotters; + +impl UserData for Spotters { + fn add_methods>(methods: &mut M) { + methods.add_method("match", |_, _, matcher: SpotterMatcher| Ok(matcher)); + + methods.add_meta_method(MetaMethod::Len, |_, _, ()| Ok(YAZI.plugin.spotters.load().len())); + } +} + +// --- Matcher +pub struct SpotterMatcher(yazi_config::plugin::SpotterMatcher<'static>); + +impl TryFrom
for SpotterMatcher { + type Error = mlua::Error; + + fn try_from(value: Table) -> Result { + let id: Id = value.raw_get("id").unwrap_or_default(); + let file: Option = value.raw_get("file")?; + let mime: Option = value.raw_get("mime")?; + + Ok(Self(yazi_config::plugin::SpotterMatcher { + spotters: YAZI.plugin.spotters.load_full(), + id: id.0, + file: file.map(|f| f.inner.clone().into()), + mime: mime.map(Into::into), + offset: 0, + })) + } +} + +impl FromLua for SpotterMatcher { + fn from_lua(value: Value, _: &Lua) -> mlua::Result { + match value { + Value::Table(t) => t.try_into(), + _ => return Err("expected a table of SpotterMatcher".into_lua_err()), + } + } +} + +impl IntoLua for SpotterMatcher { + fn into_lua(self, lua: &Lua) -> mlua::Result { + Iter::new(self.0.into_iter().map(Spotter::new), None).into_lua(lua) + } +} diff --git a/yazi-binding/src/elements/bar.rs b/yazi-binding/src/elements/bar.rs index a3eb15a1..eb94303b 100644 --- a/yazi-binding/src/elements/bar.rs +++ b/yazi-binding/src/elements/bar.rs @@ -81,11 +81,11 @@ impl UserData for Bar { crate::impl_area_method!(methods); crate::impl_style_method!(methods, style); - methods.add_function_mut("edge", |_, (ud, edge): (AnyUserData, Edge)| { + methods.add_function("edge", |_, (ud, edge): (AnyUserData, Edge)| { ud.borrow_mut::()?.edge = edge; Ok(ud) }); - methods.add_function_mut("symbol", |_, (ud, symbol): (AnyUserData, String)| { + methods.add_function("symbol", |_, (ud, symbol): (AnyUserData, String)| { ud.borrow_mut::()?.symbol = symbol; Ok(ud) }); diff --git a/yazi-binding/src/elements/border.rs b/yazi-binding/src/elements/border.rs index f32d0038..a56ac58d 100644 --- a/yazi-binding/src/elements/border.rs +++ b/yazi-binding/src/elements/border.rs @@ -79,7 +79,7 @@ impl UserData for Border { crate::impl_area_method!(methods); crate::impl_style_method!(methods, style); - methods.add_function_mut("type", |_, (ud, value): (AnyUserData, u8)| { + methods.add_function("type", |_, (ud, value): (AnyUserData, u8)| { ud.borrow_mut::()?.r#type = match value { ROUNDED => ratatui::widgets::BorderType::Rounded, DOUBLE => ratatui::widgets::BorderType::Double, @@ -90,20 +90,17 @@ impl UserData for Border { }; Ok(ud) }); - methods.add_function_mut( - "title", - |_, (ud, line, position): (AnyUserData, Line, Option)| { - let position = if position == Some(Borders::BOTTOM.bits()) { - ratatui::widgets::TitlePosition::Bottom - } else { - ratatui::widgets::TitlePosition::Top - }; + methods.add_function("title", |_, (ud, line, position): (AnyUserData, Line, Option)| { + let position = if position == Some(Borders::BOTTOM.bits()) { + ratatui::widgets::TitlePosition::Bottom + } else { + ratatui::widgets::TitlePosition::Top + }; - ud.borrow_mut::()?.titles.push((position, line.inner)); - Ok(ud) - }, - ); - methods.add_function_mut("edge", |_, (ud, edge): (AnyUserData, Edge)| { + ud.borrow_mut::()?.titles.push((position, line.inner)); + Ok(ud) + }); + methods.add_function("edge", |_, (ud, edge): (AnyUserData, Edge)| { ud.borrow_mut::()?.edge = edge; Ok(ud) }); diff --git a/yazi-binding/src/elements/gauge.rs b/yazi-binding/src/elements/gauge.rs index c3543a5c..d9eb611c 100644 --- a/yazi-binding/src/elements/gauge.rs +++ b/yazi-binding/src/elements/gauge.rs @@ -57,7 +57,7 @@ impl UserData for Gauge { crate::impl_area_method!(methods); crate::impl_style_method!(methods, style); - methods.add_function_mut("percent", |_, (ud, percent): (AnyUserData, u8)| { + methods.add_function("percent", |_, (ud, percent): (AnyUserData, u8)| { if percent > 100 { return Err("percent must be between 0 and 100".into_lua_err()); } @@ -66,7 +66,7 @@ impl UserData for Gauge { Ok(ud) }); - methods.add_function_mut("ratio", |_, (ud, ratio): (AnyUserData, f64)| { + methods.add_function("ratio", |_, (ud, ratio): (AnyUserData, f64)| { if !(0.0..1.0).contains(&ratio) { return Err("ratio must be between 0 and 1".into_lua_err()); } @@ -75,12 +75,12 @@ impl UserData for Gauge { Ok(ud) }); - methods.add_function_mut("label", |_, (ud, label): (AnyUserData, Span)| { + methods.add_function("label", |_, (ud, label): (AnyUserData, Span)| { ud.borrow_mut::()?.label = Some(label.0); Ok(ud) }); - methods.add_function_mut("gauge_style", |_, (ud, style): (AnyUserData, Style)| { + methods.add_function("gauge_style", |_, (ud, style): (AnyUserData, Style)| { ud.borrow_mut::()?.gauge_style = style.0; Ok(ud) }); diff --git a/yazi-binding/src/elements/layout.rs b/yazi-binding/src/elements/layout.rs index 5449d70e..bf499894 100644 --- a/yazi-binding/src/elements/layout.rs +++ b/yazi-binding/src/elements/layout.rs @@ -25,15 +25,15 @@ impl Layout { impl UserData for Layout { fn add_methods>(methods: &mut M) { - methods.add_function_mut("direction", |_, (ud, value): (AnyUserData, bool)| { + methods.add_function("direction", |_, (ud, value): (AnyUserData, bool)| { ud.borrow_mut::()?.direction = value; Ok(ud) }); - methods.add_function_mut("margin", |_, (ud, value): (AnyUserData, u16)| { + methods.add_function("margin", |_, (ud, value): (AnyUserData, u16)| { ud.borrow_mut::()?.margin = Some(ratatui::layout::Margin::new(value, value)); Ok(ud) }); - methods.add_function_mut("margin_h", |_, (ud, value): (AnyUserData, u16)| { + methods.add_function("margin_h", |_, (ud, value): (AnyUserData, u16)| { { let mut me = ud.borrow_mut::()?; if let Some(margin) = &mut me.margin { @@ -44,7 +44,7 @@ impl UserData for Layout { } Ok(ud) }); - methods.add_function_mut("margin_v", |_, (ud, value): (AnyUserData, u16)| { + methods.add_function("margin_v", |_, (ud, value): (AnyUserData, u16)| { { let mut me = ud.borrow_mut::()?; if let Some(margin) = &mut me.margin { @@ -55,7 +55,7 @@ impl UserData for Layout { } Ok(ud) }); - methods.add_function_mut("constraints", |_, (ud, value): (AnyUserData, Vec)| { + methods.add_function("constraints", |_, (ud, value): (AnyUserData, Vec)| { ud.borrow_mut::()?.constraints = value.into_iter().map(Into::into).collect(); Ok(ud) }); diff --git a/yazi-binding/src/elements/line.rs b/yazi-binding/src/elements/line.rs index 8d23a4a2..7a38dfcb 100644 --- a/yazi-binding/src/elements/line.rs +++ b/yazi-binding/src/elements/line.rs @@ -133,14 +133,14 @@ impl UserData for Line { crate::impl_style_shorthands!(methods, style); methods.add_method("width", |_, me, ()| Ok(me.width())); - methods.add_function_mut("align", |_, (ud, align): (AnyUserData, Align)| { + methods.add_function("align", |_, (ud, align): (AnyUserData, Align)| { ud.borrow_mut::()?.alignment = Some(align.0); Ok(ud) }); methods.add_method("visible", |_, me, ()| { Ok(me.iter().flat_map(|s| s.content.chars()).any(|c| c.width().unwrap_or(0) > 0)) }); - methods.add_function_mut("truncate", |lua, (ud, t): (AnyUserData, Table)| { + methods.add_function("truncate", |lua, (ud, t): (AnyUserData, Table)| { let mut me = ud.borrow_mut::()?; let max = t.raw_get("max")?; diff --git a/yazi-binding/src/elements/pos.rs b/yazi-binding/src/elements/pos.rs index 5912f223..4e701c4c 100644 --- a/yazi-binding/src/elements/pos.rs +++ b/yazi-binding/src/elements/pos.rs @@ -91,7 +91,7 @@ impl UserData for Pos { } fn add_methods>(methods: &mut M) { - methods.add_function_mut("pad", |_, (ud, pad): (AnyUserData, Pad)| { + methods.add_function("pad", |_, (ud, pad): (AnyUserData, Pad)| { ud.borrow_mut::()?.pad = pad; Ok(ud) }); diff --git a/yazi-binding/src/elements/row.rs b/yazi-binding/src/elements/row.rs index 9120eeb7..969f81ef 100644 --- a/yazi-binding/src/elements/row.rs +++ b/yazi-binding/src/elements/row.rs @@ -55,15 +55,15 @@ impl UserData for Row { fn add_methods>(methods: &mut M) { crate::impl_style_method!(methods, style); - methods.add_function_mut("height", |_, (ud, value): (AnyUserData, u16)| { + methods.add_function("height", |_, (ud, value): (AnyUserData, u16)| { ud.borrow_mut::()?.height = value; Ok(ud) }); - methods.add_function_mut("margin_t", |_, (ud, value): (AnyUserData, u16)| { + methods.add_function("margin_t", |_, (ud, value): (AnyUserData, u16)| { ud.borrow_mut::()?.top_margin = value; Ok(ud) }); - methods.add_function_mut("margin_b", |_, (ud, value): (AnyUserData, u16)| { + methods.add_function("margin_b", |_, (ud, value): (AnyUserData, u16)| { ud.borrow_mut::()?.bottom_margin = value; Ok(ud) }); diff --git a/yazi-binding/src/elements/span.rs b/yazi-binding/src/elements/span.rs index 22609808..717a0d73 100644 --- a/yazi-binding/src/elements/span.rs +++ b/yazi-binding/src/elements/span.rs @@ -82,7 +82,7 @@ impl UserData for Span { methods.add_method("visible", |_, Self(me), ()| { Ok(me.content.chars().any(|c| c.width().unwrap_or(0) > 0)) }); - methods.add_function_mut("truncate", |_, (ud, t): (AnyUserData, Table)| { + methods.add_function("truncate", |_, (ud, t): (AnyUserData, Table)| { ud.borrow_mut::()?.truncate(t.raw_get("max")?); Ok(ud) }); diff --git a/yazi-binding/src/elements/table.rs b/yazi-binding/src/elements/table.rs index 9fa5ead1..f7defacf 100644 --- a/yazi-binding/src/elements/table.rs +++ b/yazi-binding/src/elements/table.rs @@ -108,45 +108,45 @@ impl UserData for Table { fn add_methods>(methods: &mut M) { crate::impl_area_method!(methods); - methods.add_function_mut("header", |_, (ud, header): (AnyUserData, Row)| { + methods.add_function("header", |_, (ud, header): (AnyUserData, Row)| { ud.borrow_mut::()?.header = Some(header.into()); Ok(ud) }); - methods.add_function_mut("footer", |_, (ud, footer): (AnyUserData, Row)| { + methods.add_function("footer", |_, (ud, footer): (AnyUserData, Row)| { ud.borrow_mut::()?.footer = Some(footer.into()); Ok(ud) }); - methods.add_function_mut("widths", |_, (ud, widths): (AnyUserData, Vec)| { + methods.add_function("widths", |_, (ud, widths): (AnyUserData, Vec)| { ud.borrow_mut::()?.widths = widths.into_iter().map(Into::into).collect(); Ok(ud) }); - methods.add_function_mut("spacing", |_, (ud, spacing): (AnyUserData, u16)| { + methods.add_function("spacing", |_, (ud, spacing): (AnyUserData, u16)| { ud.borrow_mut::()?.column_spacing = spacing; Ok(ud) }); - methods.add_function_mut("row", |_, (ud, idx): (AnyUserData, Option)| { + methods.add_function("row", |_, (ud, idx): (AnyUserData, Option)| { ud.borrow_mut::()?.state.select(idx); Ok(ud) }); - methods.add_function_mut("col", |_, (ud, idx): (AnyUserData, Option)| { + methods.add_function("col", |_, (ud, idx): (AnyUserData, Option)| { ud.borrow_mut::()?.state.select_column(idx); Ok(ud) }); - methods.add_function_mut("style", |_, (ud, style): (AnyUserData, Style)| { + methods.add_function("style", |_, (ud, style): (AnyUserData, Style)| { ud.borrow_mut::()?.style = style.0; Ok(ud) }); - methods.add_function_mut("row_style", |_, (ud, style): (AnyUserData, Style)| { + methods.add_function("row_style", |_, (ud, style): (AnyUserData, Style)| { ud.borrow_mut::()?.row_highlight_style = style.0; Ok(ud) }); - methods.add_function_mut("col_style", |_, (ud, style): (AnyUserData, Style)| { + methods.add_function("col_style", |_, (ud, style): (AnyUserData, Style)| { ud.borrow_mut::()?.column_highlight_style = style.0; Ok(ud) }); - methods.add_function_mut("cell_style", |_, (ud, style): (AnyUserData, Style)| { + methods.add_function("cell_style", |_, (ud, style): (AnyUserData, Style)| { ud.borrow_mut::()?.cell_highlight_style = style.0; Ok(ud) }); diff --git a/yazi-binding/src/elements/text.rs b/yazi-binding/src/elements/text.rs index 47e824f3..64b0f8cf 100644 --- a/yazi-binding/src/elements/text.rs +++ b/yazi-binding/src/elements/text.rs @@ -124,15 +124,15 @@ impl UserData for Text { crate::impl_style_method!(methods, inner.style); crate::impl_style_shorthands!(methods, inner.style); - methods.add_function_mut("align", |_, (ud, align): (AnyUserData, Align)| { + methods.add_function("align", |_, (ud, align): (AnyUserData, Align)| { ud.borrow_mut::()?.inner.alignment = Some(align.0); Ok(ud) }); - methods.add_function_mut("wrap", |_, (ud, wrap): (AnyUserData, Wrap)| { + methods.add_function("wrap", |_, (ud, wrap): (AnyUserData, Wrap)| { ud.borrow_mut::()?.wrap = wrap; Ok(ud) }); - methods.add_function_mut("scroll", |_, (ud, x, y): (AnyUserData, u16, u16)| { + methods.add_function("scroll", |_, (ud, x, y): (AnyUserData, u16, u16)| { ud.borrow_mut::()?.scroll = ratatui::layout::Position { x, y }; Ok(ud) }); diff --git a/yazi-binding/src/file.rs b/yazi-binding/src/file.rs index d4c5761c..0ef0b640 100644 --- a/yazi-binding/src/file.rs +++ b/yazi-binding/src/file.rs @@ -10,7 +10,7 @@ const EXPECTED: &str = "expected a table, File, or fs::File"; #[derive(Clone)] pub struct File { - inner: yazi_fs::File, + pub(crate) inner: yazi_fs::File, v_cha: Option, v_url: Option, diff --git a/yazi-binding/src/id.rs b/yazi-binding/src/id.rs index 985316b0..1b38b478 100644 --- a/yazi-binding/src/id.rs +++ b/yazi-binding/src/id.rs @@ -2,7 +2,7 @@ use std::ops::Deref; use mlua::{ExternalError, ExternalResult, FromLua, Lua, UserData, Value}; -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Default)] pub struct Id(pub yazi_shared::Id); impl Deref for Id { diff --git a/yazi-binding/src/lib.rs b/yazi-binding/src/lib.rs index fc046f2d..3ef516ab 100644 --- a/yazi-binding/src/lib.rs +++ b/yazi-binding/src/lib.rs @@ -1,5 +1,5 @@ mod macros; -yazi_macro::mod_pub!(elements process); +yazi_macro::mod_pub!(config elements process); yazi_macro::mod_flat!(access calculator cha chan chord_cow composer error fd file handle icon id image input iter layer mouse path permit range runtime scheme stage style url utils); diff --git a/yazi-binding/src/macros.rs b/yazi-binding/src/macros.rs index 69f4d64e..94f7c220 100644 --- a/yazi-binding/src/macros.rs +++ b/yazi-binding/src/macros.rs @@ -88,7 +88,7 @@ macro_rules! cached_field_mut { #[macro_export] macro_rules! impl_area_method { ($methods:ident) => { - $methods.add_function_mut( + $methods.add_function( "area", |lua, (ud, area): (mlua::AnyUserData, Option)| { use mlua::IntoLua; @@ -106,7 +106,7 @@ macro_rules! impl_area_method { #[macro_export] macro_rules! impl_style_method { ($methods:ident, $($field:tt).+) => { - $methods.add_function_mut("style", |_, (ud, style): (mlua::AnyUserData, $crate::Style)| { + $methods.add_function("style", |_, (ud, style): (mlua::AnyUserData, $crate::Style)| { ud.borrow_mut::()?.$($field).+ = style.0; Ok(ud) }); @@ -116,7 +116,7 @@ macro_rules! impl_style_method { #[macro_export] macro_rules! impl_style_shorthands { ($methods:ident, $($field:tt).+) => { - $methods.add_function_mut("fg", |lua, (ud, value): (mlua::AnyUserData, mlua::Value)| { + $methods.add_function("fg", |lua, (ud, value): (mlua::AnyUserData, mlua::Value)| { use $crate::elements::Color; use mlua::FromLua; use ratatui::style::Modifier; @@ -135,7 +135,7 @@ macro_rules! impl_style_shorthands { } } }); - $methods.add_function_mut("bg", |lua, (ud, value): (mlua::AnyUserData, mlua::Value)| { + $methods.add_function("bg", |lua, (ud, value): (mlua::AnyUserData, mlua::Value)| { use $crate::elements::Color; use mlua::FromLua; use ratatui::style::Modifier; @@ -154,7 +154,7 @@ macro_rules! impl_style_shorthands { } } }); - $methods.add_function_mut("bold", |_, (ud, remove): (mlua::AnyUserData, bool)| { + $methods.add_function("bold", |_, (ud, remove): (mlua::AnyUserData, bool)| { let me = &mut ud.borrow_mut::()?.$($field).+; if remove { *me = me.remove_modifier(ratatui::style::Modifier::BOLD); @@ -163,7 +163,7 @@ macro_rules! impl_style_shorthands { } Ok(ud) }); - $methods.add_function_mut("dim", |_, (ud, remove): (mlua::AnyUserData, bool)| { + $methods.add_function("dim", |_, (ud, remove): (mlua::AnyUserData, bool)| { let me = &mut ud.borrow_mut::()?.$($field).+; if remove { *me = me.remove_modifier(ratatui::style::Modifier::DIM); @@ -172,7 +172,7 @@ macro_rules! impl_style_shorthands { } Ok(ud) }); - $methods.add_function_mut("italic", |_, (ud, remove): (mlua::AnyUserData, bool)| { + $methods.add_function("italic", |_, (ud, remove): (mlua::AnyUserData, bool)| { let me = &mut ud.borrow_mut::()?.$($field).+; if remove { *me = me.remove_modifier(ratatui::style::Modifier::ITALIC); @@ -181,7 +181,7 @@ macro_rules! impl_style_shorthands { } Ok(ud) }); - $methods.add_function_mut("underline", |_, (ud, remove): (mlua::AnyUserData, bool)| { + $methods.add_function("underline", |_, (ud, remove): (mlua::AnyUserData, bool)| { let me = &mut ud.borrow_mut::()?.$($field).+; if remove { *me = me.remove_modifier(ratatui::style::Modifier::UNDERLINED); @@ -190,7 +190,7 @@ macro_rules! impl_style_shorthands { } Ok(ud) }); - $methods.add_function_mut("blink", |_, (ud, remove): (mlua::AnyUserData, bool)| { + $methods.add_function("blink", |_, (ud, remove): (mlua::AnyUserData, bool)| { let me = &mut ud.borrow_mut::()?.$($field).+; if remove { *me = me.remove_modifier(ratatui::style::Modifier::SLOW_BLINK); @@ -199,7 +199,7 @@ macro_rules! impl_style_shorthands { } Ok(ud) }); - $methods.add_function_mut("blink_rapid", |_, (ud, remove): (mlua::AnyUserData, bool)| { + $methods.add_function("blink_rapid", |_, (ud, remove): (mlua::AnyUserData, bool)| { let me = &mut ud.borrow_mut::()?.$($field).+; if remove { *me = me.remove_modifier(ratatui::style::Modifier::RAPID_BLINK); @@ -208,7 +208,7 @@ macro_rules! impl_style_shorthands { } Ok(ud) }); - $methods.add_function_mut("reverse", |_, (ud, remove): (mlua::AnyUserData, bool)| { + $methods.add_function("reverse", |_, (ud, remove): (mlua::AnyUserData, bool)| { let me = &mut ud.borrow_mut::()?.$($field).+; if remove { *me = me.remove_modifier(ratatui::style::Modifier::REVERSED); @@ -217,7 +217,7 @@ macro_rules! impl_style_shorthands { } Ok(ud) }); - $methods.add_function_mut("hidden", |_, (ud, remove): (mlua::AnyUserData, bool)| { + $methods.add_function("hidden", |_, (ud, remove): (mlua::AnyUserData, bool)| { let me = &mut ud.borrow_mut::()?.$($field).+; if remove { *me = me.remove_modifier(ratatui::style::Modifier::HIDDEN); @@ -226,7 +226,7 @@ macro_rules! impl_style_shorthands { } Ok(ud) }); - $methods.add_function_mut("crossed", |_, (ud, remove): (mlua::AnyUserData, bool)| { + $methods.add_function("crossed", |_, (ud, remove): (mlua::AnyUserData, bool)| { let me = &mut ud.borrow_mut::()?.$($field).+; if remove { *me = me.remove_modifier(ratatui::style::Modifier::CROSSED_OUT); @@ -235,7 +235,7 @@ macro_rules! impl_style_shorthands { } Ok(ud) }); - $methods.add_function_mut("reset", |_, ud: mlua::AnyUserData| { + $methods.add_function("reset", |_, ud: mlua::AnyUserData| { ud.borrow_mut::()?.$($field).+ = ratatui::style::Style::reset(); Ok(ud) }); diff --git a/yazi-binding/src/process/child.rs b/yazi-binding/src/process/child.rs index 961cdcb9..b0550167 100644 --- a/yazi-binding/src/process/child.rs +++ b/yazi-binding/src/process/child.rs @@ -3,10 +3,9 @@ use std::{ops::DerefMut, process::ExitStatus, time::Duration}; use futures::future::try_join3; use mlua::{AnyUserData, ExternalError, IntoLua, IntoLuaMulti, Table, UserData, UserDataMethods, Value}; use tokio::{io::{self, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter}, process::{ChildStderr, ChildStdin, ChildStdout}, select}; -use crate::Error; use super::Status; -use crate::process::Output; +use crate::{Error, process::Output}; pub struct Child { inner: tokio::process::Child, diff --git a/yazi-binding/src/process/command.rs b/yazi-binding/src/process/command.rs index 5dd4fdbc..bc18d5e8 100644 --- a/yazi-binding/src/process/command.rs +++ b/yazi-binding/src/process/command.rs @@ -138,7 +138,7 @@ impl UserData for Command { ) } - methods.add_function_mut("arg", |lua, (ud, arg): (AnyUserData, Value)| { + methods.add_function("arg", |lua, (ud, arg): (AnyUserData, Value)| { let mut me = ud.borrow_mut::()?; match arg { Value::Nil => return lua.create_sequence_from(me.inner.as_std().get_args())?.into_lua(lua), @@ -154,11 +154,11 @@ impl UserData for Command { } ud.into_lua(lua) }); - methods.add_function_mut("cwd", |_, (ud, dir): (AnyUserData, mlua::String)| { + methods.add_function("cwd", |_, (ud, dir): (AnyUserData, mlua::String)| { ud.borrow_mut::()?.inner.current_dir(dir.to_str()?.as_ref()); Ok(ud) }); - methods.add_function_mut( + methods.add_function( "env", |_, (ud, key, value): (AnyUserData, mlua::String, mlua::String)| { ud.borrow_mut::()? @@ -167,19 +167,19 @@ impl UserData for Command { Ok(ud) }, ); - methods.add_function_mut("stdin", |_, (ud, stdio): (AnyUserData, Value)| { + methods.add_function("stdin", |_, (ud, stdio): (AnyUserData, Value)| { ud.borrow_mut::()?.inner.stdin(make_stdio(stdio)?); Ok(ud) }); - methods.add_function_mut("stdout", |_, (ud, stdio): (AnyUserData, Value)| { + methods.add_function("stdout", |_, (ud, stdio): (AnyUserData, Value)| { ud.borrow_mut::()?.inner.stdout(make_stdio(stdio)?); Ok(ud) }); - methods.add_function_mut("stderr", |_, (ud, stdio): (AnyUserData, Value)| { + methods.add_function("stderr", |_, (ud, stdio): (AnyUserData, Value)| { ud.borrow_mut::()?.inner.stderr(make_stdio(stdio)?); Ok(ud) }); - methods.add_function_mut("memory", |_, (ud, max): (AnyUserData, usize)| { + methods.add_function("memory", |_, (ud, max): (AnyUserData, usize)| { ud.borrow_mut::()?.memory = Some(max); Ok(ud) }); diff --git a/yazi-binding/src/process/output.rs b/yazi-binding/src/process/output.rs index ad0a05ef..f0892486 100644 --- a/yazi-binding/src/process/output.rs +++ b/yazi-binding/src/process/output.rs @@ -1,9 +1,9 @@ use std::mem; use mlua::{UserData, Value}; -use crate::{cached_field, cached_field_mut}; use super::Status; +use crate::{cached_field, cached_field_mut}; pub struct Output { inner: std::process::Output, diff --git a/yazi-binding/src/style.rs b/yazi-binding/src/style.rs index 07e325b3..83c0899a 100644 --- a/yazi-binding/src/style.rs +++ b/yazi-binding/src/style.rs @@ -2,6 +2,7 @@ use std::ops::Deref; use mlua::{ExternalError, FromLua, IntoLua, Lua, LuaSerdeExt, MetaMethod, Table, UserData, UserDataMethods, Value}; use ratatui::style::Modifier; +use yazi_shared::SyncCell; use crate::{SER_OPT, elements::Color}; @@ -22,6 +23,10 @@ impl From