From 74bd98031e04b0455f83bed8b7970967a3ec9a1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20misaki=20masa?= Date: Sun, 20 Jul 2025 14:11:57 +0800 Subject: [PATCH] feat: `key-*` DDS events to allow canceling user key commands (#3005) --- Cargo.lock | 29 ++- Cargo.toml | 2 +- cspell.json | 2 +- yazi-actor/Cargo.toml | 8 + yazi-actor/src/actor.rs | 2 + yazi-actor/src/context.rs | 31 ++- yazi-actor/src/core/mod.rs | 1 + yazi-actor/src/core/preflight.rs | 48 ++++ yazi-actor/src/lib.rs | 2 +- {yazi-fm => yazi-actor}/src/lives/core.rs | 0 {yazi-fm => yazi-actor}/src/lives/file.rs | 0 {yazi-fm => yazi-actor}/src/lives/files.rs | 0 {yazi-fm => yazi-actor}/src/lives/filter.rs | 0 {yazi-fm => yazi-actor}/src/lives/finder.rs | 0 {yazi-fm => yazi-actor}/src/lives/folder.rs | 0 {yazi-fm => yazi-actor}/src/lives/lives.rs | 7 +- {yazi-fm => yazi-actor}/src/lives/mod.rs | 0 {yazi-fm => yazi-actor}/src/lives/mode.rs | 0 .../src/lives/preference.rs | 0 {yazi-fm => yazi-actor}/src/lives/preview.rs | 0 {yazi-fm => yazi-actor}/src/lives/ptr.rs | 0 {yazi-fm => yazi-actor}/src/lives/selected.rs | 0 {yazi-fm => yazi-actor}/src/lives/tab.rs | 0 {yazi-fm => yazi-actor}/src/lives/tabs.rs | 0 {yazi-fm => yazi-actor}/src/lives/tasks.rs | 0 {yazi-fm => yazi-actor}/src/lives/yanked.rs | 0 yazi-actor/src/mgr/quit.rs | 4 + yazi-actor/src/mgr/search.rs | 4 +- yazi-actor/src/mgr/sort.rs | 20 +- yazi-actor/src/mgr/tab_close.rs | 2 +- yazi-actor/src/mgr/tab_create.rs | 2 +- yazi-actor/src/mgr/tab_swap.rs | 2 +- yazi-actor/src/mgr/tab_switch.rs | 2 +- yazi-adapter/src/adapter.rs | 2 +- yazi-adapter/src/brand.rs | 2 +- yazi-adapter/src/unknown.rs | 2 +- yazi-binding/Cargo.toml | 4 + yazi-binding/src/lib.rs | 2 +- yazi-binding/src/macros.rs | 2 +- yazi-binding/src/source.rs | 7 - yazi-config/src/keymap/chord.rs | 3 +- yazi-config/src/keymap/key.rs | 2 +- yazi-config/src/layout.rs | 2 +- yazi-config/src/mgr/mouse.rs | 2 +- yazi-config/src/mgr/ratio.rs | 2 +- yazi-config/src/opener/rule.rs | 2 +- yazi-config/src/preview/wrap.rs | 2 +- yazi-config/src/priority.rs | 2 +- yazi-dds/src/body/before_default.rs | 72 ------ yazi-dds/src/body/before_quit.rs | 36 --- yazi-dds/src/body/body.rs | 222 +++++++++++++++++- yazi-dds/src/body/bulk.rs | 39 +-- yazi-dds/src/body/cd.rs | 2 +- yazi-dds/src/body/delete.rs | 2 +- yazi-dds/src/body/hover.rs | 2 +- yazi-dds/src/body/load.rs | 2 +- yazi-dds/src/body/mod.rs | 2 +- yazi-dds/src/body/move.rs | 2 +- yazi-dds/src/body/rename.rs | 2 +- yazi-dds/src/body/trash.rs | 2 +- yazi-dds/src/body/yank.rs | 2 +- yazi-dds/src/macros.rs | 14 +- yazi-dds/src/payload.rs | 8 +- yazi-fm/Cargo.toml | 2 - yazi-fm/src/app/app.rs | 1 - yazi-fm/src/app/commands/accept_payload.rs | 36 +-- yazi-fm/src/app/commands/bootstrap.rs | 8 +- yazi-fm/src/app/commands/mouse.rs | 3 +- yazi-fm/src/app/commands/plugin.rs | 3 +- yazi-fm/src/app/commands/reflow.rs | 3 +- yazi-fm/src/app/commands/render.rs | 7 +- yazi-fm/src/app/commands/resize.rs | 3 +- yazi-fm/src/app/commands/update_progress.rs | 3 +- yazi-fm/src/executor.rs | 11 +- yazi-fm/src/main.rs | 2 +- yazi-fs/src/op.rs | 6 +- yazi-macro/src/actor.rs | 43 ++-- yazi-macro/src/event.rs | 44 +--- yazi-macro/src/lib.rs | 1 + yazi-macro/src/render.rs | 30 +++ yazi-parser/Cargo.toml | 4 + yazi-parser/src/arrow.rs | 7 +- yazi-parser/src/{mgr => input}/forward.rs | 0 yazi-parser/src/input/mod.rs | 2 +- yazi-parser/src/mgr/back.rs | 1 - yazi-parser/src/mgr/cd.rs | 8 +- yazi-parser/src/mgr/close.rs | 7 +- yazi-parser/src/mgr/copy.rs | 8 +- yazi-parser/src/mgr/create.rs | 6 + yazi-parser/src/mgr/enter.rs | 1 - yazi-parser/src/mgr/escape.rs | 6 + yazi-parser/src/mgr/filter.rs | 7 +- yazi-parser/src/mgr/find.rs | 6 + yazi-parser/src/mgr/find_arrow.rs | 6 + yazi-parser/src/mgr/find_do.rs | 6 + yazi-parser/src/mgr/hardlink.rs | 6 + yazi-parser/src/mgr/hidden.rs | 6 + yazi-parser/src/mgr/hover.rs | 12 +- yazi-parser/src/mgr/linemode.rs | 6 + yazi-parser/src/mgr/link.rs | 6 + yazi-parser/src/mgr/mod.rs | 4 +- yazi-parser/src/mgr/open.rs | 13 +- yazi-parser/src/mgr/paste.rs | 6 + yazi-parser/src/mgr/peek.rs | 5 + yazi-parser/src/mgr/quit.rs | 6 +- yazi-parser/src/mgr/remove.rs | 6 + yazi-parser/src/mgr/rename.rs | 6 + yazi-parser/src/mgr/reveal.rs | 6 + yazi-parser/src/mgr/search.rs | 8 +- yazi-parser/src/mgr/seek.rs | 5 + yazi-parser/src/mgr/shell.rs | 6 + yazi-parser/src/mgr/sort.rs | 32 +++ yazi-parser/src/mgr/spot.rs | 7 +- yazi-parser/src/mgr/tab_close.rs | 6 + yazi-parser/src/mgr/tab_create.rs | 6 + yazi-parser/src/mgr/tab_switch.rs | 6 + yazi-parser/src/mgr/toggle.rs | 6 + yazi-parser/src/mgr/toggle_all.rs | 6 + yazi-parser/src/mgr/update_files.rs | 6 + yazi-parser/src/mgr/update_mimes.rs | 6 + yazi-parser/src/mgr/update_paged.rs | 7 +- yazi-parser/src/mgr/update_peeked.rs | 7 +- yazi-parser/src/mgr/update_spotted.rs | 8 +- yazi-parser/src/mgr/update_tasks.rs | 6 + yazi-parser/src/mgr/update_yanked.rs | 8 +- yazi-parser/src/mgr/visual_mode.rs | 6 + yazi-parser/src/mgr/yank.rs | 6 + yazi-parser/src/void.rs | 7 +- yazi-plugin/src/loader/loader.rs | 4 +- yazi-plugin/src/utils/call.rs | 11 +- yazi-plugin/src/utils/layer.rs | 5 +- yazi-plugin/src/utils/sync.rs | 19 +- yazi-proxy/Cargo.toml | 6 - yazi-proxy/src/app.rs | 17 +- yazi-proxy/src/cmp.rs | 8 +- yazi-proxy/src/confirm.rs | 5 +- yazi-proxy/src/input.rs | 6 +- yazi-proxy/src/mgr.rs | 28 +-- yazi-proxy/src/pick.rs | 5 +- yazi-proxy/src/tasks.rs | 12 +- yazi-proxy/src/which.rs | 5 +- yazi-scheduler/src/plugin/plugin.rs | 8 +- yazi-shared/Cargo.toml | 1 - yazi-shared/src/event/cmd.rs | 45 ++-- yazi-shared/src/source.rs | 26 +- yazi-shared/src/url/url.rs | 4 +- yazi-widgets/Cargo.toml | 2 +- yazi-widgets/src/input/commands/forward.rs | 2 +- 148 files changed, 893 insertions(+), 465 deletions(-) create mode 100644 yazi-actor/src/core/mod.rs create mode 100644 yazi-actor/src/core/preflight.rs rename {yazi-fm => yazi-actor}/src/lives/core.rs (100%) rename {yazi-fm => yazi-actor}/src/lives/file.rs (100%) rename {yazi-fm => yazi-actor}/src/lives/files.rs (100%) rename {yazi-fm => yazi-actor}/src/lives/filter.rs (100%) rename {yazi-fm => yazi-actor}/src/lives/finder.rs (100%) rename {yazi-fm => yazi-actor}/src/lives/folder.rs (100%) rename {yazi-fm => yazi-actor}/src/lives/lives.rs (88%) rename {yazi-fm => yazi-actor}/src/lives/mod.rs (100%) rename {yazi-fm => yazi-actor}/src/lives/mode.rs (100%) rename {yazi-fm => yazi-actor}/src/lives/preference.rs (100%) rename {yazi-fm => yazi-actor}/src/lives/preview.rs (100%) rename {yazi-fm => yazi-actor}/src/lives/ptr.rs (100%) rename {yazi-fm => yazi-actor}/src/lives/selected.rs (100%) rename {yazi-fm => yazi-actor}/src/lives/tab.rs (100%) rename {yazi-fm => yazi-actor}/src/lives/tabs.rs (100%) rename {yazi-fm => yazi-actor}/src/lives/tasks.rs (100%) rename {yazi-fm => yazi-actor}/src/lives/yanked.rs (100%) delete mode 100644 yazi-binding/src/source.rs delete mode 100644 yazi-dds/src/body/before_default.rs delete mode 100644 yazi-dds/src/body/before_quit.rs create mode 100644 yazi-macro/src/render.rs rename yazi-parser/src/{mgr => input}/forward.rs (100%) delete mode 100644 yazi-parser/src/mgr/back.rs delete mode 100644 yazi-parser/src/mgr/enter.rs create mode 100644 yazi-parser/src/mgr/sort.rs diff --git a/Cargo.lock b/Cargo.lock index 25499046..257acce1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -352,9 +352,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.29" +version = "1.2.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362" +checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7" dependencies = [ "jobserver", "libc", @@ -460,9 +460,9 @@ checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "clipboard-win" -version = "5.4.0" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892" +checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4" dependencies = [ "error-code", ] @@ -1193,9 +1193,9 @@ dependencies = [ [[package]] name = "instability" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf9fed6d91cfb734e7476a06bde8300a1b94e217e1b523b6f0cd1a01998c71d" +checksum = "435d80800b936787d62688c927b6490e887c7ef5ff9ce922c6c6050fca75eb9a" dependencies = [ "darling", "indoc", @@ -1335,9 +1335,9 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638" +checksum = "4488594b9328dee448adb906d8b126d9b7deb7cf5c22161ee591610bb1be83c0" dependencies = [ "bitflags 2.9.1", "libc", @@ -2344,9 +2344,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.140" +version = "1.0.141" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3" dependencies = [ "itoa", "memchr", @@ -3489,13 +3489,17 @@ version = "25.6.11" dependencies = [ "anyhow", "crossterm 0.29.0", + "foldhash", "futures", + "indexmap", "libc", + "mlua", "paste", "scopeguard", "tokio", "tokio-stream", "tracing", + "yazi-binding", "yazi-boot", "yazi-config", "yazi-core", @@ -3696,9 +3700,7 @@ dependencies = [ "better-panic", "crossterm 0.29.0", "fdlimit", - "foldhash", "futures", - "indexmap", "libc", "mlua", "paste", @@ -3829,8 +3831,6 @@ name = "yazi-proxy" version = "25.6.11" dependencies = [ "anyhow", - "mlua", - "serde", "tokio", "yazi-config", "yazi-macro", @@ -3868,7 +3868,6 @@ name = "yazi-shared" version = "25.6.11" dependencies = [ "anyhow", - "bitflags 2.9.1", "crossterm 0.29.0", "foldhash", "futures", diff --git a/Cargo.toml b/Cargo.toml index 8914f0cf..239f1556 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ ratatui = { version = "0.29.0", features = [ "unstable-rendered-line regex = "1.11.1" scopeguard = "1.2.0" serde = { version = "1.0.219", features = [ "derive" ] } -serde_json = "1.0.140" +serde_json = "1.0.141" syntect = { version = "5.2.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] } tokio = { version = "1.46.1", features = [ "full" ] } tokio-stream = "0.1.17" diff --git a/cspell.json b/cspell.json index b4f2d024..3d23639a 100644 --- a/cspell.json +++ b/cspell.json @@ -1 +1 @@ -{"version":"0.2","language":"en","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"]} \ 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"],"version":"0.2","flagWords":[],"language":"en"} \ No newline at end of file diff --git a/yazi-actor/Cargo.toml b/yazi-actor/Cargo.toml index d19ad551..e4c1a1fc 100644 --- a/yazi-actor/Cargo.toml +++ b/yazi-actor/Cargo.toml @@ -8,7 +8,12 @@ description = "Yazi actor model" homepage = "https://yazi-rs.github.io" repository = "https://github.com/sxyazi/yazi" +[features] +default = [ "vendored-lua" ] +vendored-lua = [ "mlua/vendored" ] + [dependencies] +yazi-binding = { path = "../yazi-binding", version = "25.6.11" } yazi-boot = { path = "../yazi-boot", version = "25.6.11" } yazi-config = { path = "../yazi-config", version = "25.6.11" } yazi-core = { path = "../yazi-core", version = "25.6.11" } @@ -25,7 +30,10 @@ yazi-widgets = { path = "../yazi-widgets", version = "25.6.11" } # External dependencies anyhow = { workspace = true } crossterm = { workspace = true } +foldhash = { workspace = true } futures = { workspace = true } +indexmap = { workspace = true } +mlua = { workspace = true } paste = { workspace = true } scopeguard = { workspace = true } tokio = { workspace = true } diff --git a/yazi-actor/src/actor.rs b/yazi-actor/src/actor.rs index 280c2303..b9416f03 100644 --- a/yazi-actor/src/actor.rs +++ b/yazi-actor/src/actor.rs @@ -9,4 +9,6 @@ pub trait Actor { const NAME: &str; fn act(cx: &mut Ctx, opt: Self::Options) -> Result; + + fn hook(_cx: &Ctx, _opt: &Self::Options) -> Option<&'static str> { None } } diff --git a/yazi-actor/src/context.rs b/yazi-actor/src/context.rs index 31da66dd..d418e18b 100644 --- a/yazi-actor/src/context.rs +++ b/yazi-actor/src/context.rs @@ -3,11 +3,13 @@ use std::ops::{Deref, DerefMut}; use anyhow::{Result, anyhow}; use yazi_core::{Core, mgr::Tabs, tab::{Folder, Tab}, tasks::Tasks}; use yazi_fs::File; -use yazi_shared::{event::Cmd, url::Url}; +use yazi_shared::{Source, event::Cmd, url::Url}; pub struct Ctx<'a> { - pub core: &'a mut Core, - pub tab: usize, + pub core: &'a mut Core, + pub tab: usize, + pub level: usize, + pub source: Source, } impl Deref for Ctx<'_> { @@ -36,15 +38,23 @@ impl<'a> Ctx<'a> { core.mgr.tabs.cursor }; - Ok(Self { core, tab }) + Ok(Self { core, tab, level: 0, source: cmd.source }) + } + + #[inline] + pub fn renew<'b>(cx: &'a mut Ctx<'b>) -> Ctx<'a> { + let tab = cx.core.mgr.tabs.cursor; + Self { core: cx.core, tab, level: cx.level, source: cx.source } } #[inline] pub fn active(core: &'a mut Core) -> Self { let tab = core.mgr.tabs.cursor; - Self { core, tab } + Self { core, tab, level: 0, source: Source::Unknown } } +} +impl<'a> Ctx<'a> { #[inline] pub fn tabs(&self) -> &Tabs { &self.mgr.tabs } @@ -80,4 +90,15 @@ impl<'a> Ctx<'a> { #[inline] pub fn tasks(&self) -> &Tasks { &self.tasks } + + #[inline] + pub fn source(&self) -> Source { + use Source::*; + match self.source { + Key if self.level != 1 => Ind, + Emit if self.level != 1 => EmitInd, + Relay if self.level != 1 => RelayInd, + s => s, + } + } } diff --git a/yazi-actor/src/core/mod.rs b/yazi-actor/src/core/mod.rs new file mode 100644 index 00000000..7a8e7dbd --- /dev/null +++ b/yazi-actor/src/core/mod.rs @@ -0,0 +1 @@ +yazi_macro::mod_flat!(preflight); diff --git a/yazi-actor/src/core/preflight.rs b/yazi-actor/src/core/preflight.rs new file mode 100644 index 00000000..87385cec --- /dev/null +++ b/yazi-actor/src/core/preflight.rs @@ -0,0 +1,48 @@ +use std::marker::PhantomData; + +use anyhow::Result; +use mlua::{IntoLua, Value}; +use tracing::error; +use yazi_binding::runtime_mut; +use yazi_dds::{LOCAL, body::Body}; +use yazi_macro::succ; +use yazi_plugin::LUA; +use yazi_shared::event::Data; + +use crate::{Actor, Ctx, lives::Lives}; + +pub struct Preflight<'a> { + _lifetime: PhantomData<&'a ()>, +} + +impl<'a> Actor for Preflight<'a> { + type Options = (&'static str, Body<'a>); + + const NAME: &'static str = "preflight"; + + fn act(cx: &mut Ctx, opt: Self::Options) -> Result { + let kind = opt.0; + let Some(handlers) = LOCAL.read().get(kind).filter(|&m| !m.is_empty()).cloned() else { + succ!(false) + }; + + succ!(Lives::scope(cx.core, || { + let body = opt.1.into_lua(&LUA)?; + for (id, cb) in handlers { + runtime_mut!(LUA)?.push(&id); + let result = cb.call::(body.clone()); + runtime_mut!(LUA)?.pop(); + + match result { + Ok(Value::Boolean(true)) => return Ok(true), + Ok(Value::Nil | Value::Boolean(false)) => {} + Ok(v) => { + error!("Unexpected return type from `{kind}` event handler in `{id}` plugin: {v:?}") + } + Err(e) => error!("Failed to run `{kind}` event handler in `{id}` plugin: {e}"), + } + } + Ok(false) + })?) + } +} diff --git a/yazi-actor/src/lib.rs b/yazi-actor/src/lib.rs index 236b4550..def17563 100644 --- a/yazi-actor/src/lib.rs +++ b/yazi-actor/src/lib.rs @@ -2,6 +2,6 @@ extern crate self as yazi_actor; -yazi_macro::mod_pub!(cmp confirm help input mgr pick spot tasks which); +yazi_macro::mod_pub!(cmp confirm core help input lives mgr pick spot tasks which); yazi_macro::mod_flat!(actor context); diff --git a/yazi-fm/src/lives/core.rs b/yazi-actor/src/lives/core.rs similarity index 100% rename from yazi-fm/src/lives/core.rs rename to yazi-actor/src/lives/core.rs diff --git a/yazi-fm/src/lives/file.rs b/yazi-actor/src/lives/file.rs similarity index 100% rename from yazi-fm/src/lives/file.rs rename to yazi-actor/src/lives/file.rs diff --git a/yazi-fm/src/lives/files.rs b/yazi-actor/src/lives/files.rs similarity index 100% rename from yazi-fm/src/lives/files.rs rename to yazi-actor/src/lives/files.rs diff --git a/yazi-fm/src/lives/filter.rs b/yazi-actor/src/lives/filter.rs similarity index 100% rename from yazi-fm/src/lives/filter.rs rename to yazi-actor/src/lives/filter.rs diff --git a/yazi-fm/src/lives/finder.rs b/yazi-actor/src/lives/finder.rs similarity index 100% rename from yazi-fm/src/lives/finder.rs rename to yazi-actor/src/lives/finder.rs diff --git a/yazi-fm/src/lives/folder.rs b/yazi-actor/src/lives/folder.rs similarity index 100% rename from yazi-fm/src/lives/folder.rs rename to yazi-actor/src/lives/folder.rs diff --git a/yazi-fm/src/lives/lives.rs b/yazi-actor/src/lives/lives.rs similarity index 88% rename from yazi-fm/src/lives/lives.rs rename to yazi-actor/src/lives/lives.rs index 5906076c..848f8c8f 100644 --- a/yazi-fm/src/lives/lives.rs +++ b/yazi-actor/src/lives/lives.rs @@ -13,13 +13,10 @@ static TO_DESTROY: RoCell>> = RoCell::new_const(RefCell pub(super) static FILE_CACHE: RoCell, AnyUserData>>> = RoCell::new(); -pub(crate) struct Lives; +pub struct Lives; impl Lives { - pub(crate) fn scope( - core: &yazi_core::Core, - f: impl FnOnce() -> mlua::Result, - ) -> mlua::Result { + pub fn scope(core: &yazi_core::Core, f: impl FnOnce() -> mlua::Result) -> mlua::Result { FILE_CACHE.init(Default::default()); defer! { FILE_CACHE.drop(); } diff --git a/yazi-fm/src/lives/mod.rs b/yazi-actor/src/lives/mod.rs similarity index 100% rename from yazi-fm/src/lives/mod.rs rename to yazi-actor/src/lives/mod.rs diff --git a/yazi-fm/src/lives/mode.rs b/yazi-actor/src/lives/mode.rs similarity index 100% rename from yazi-fm/src/lives/mode.rs rename to yazi-actor/src/lives/mode.rs diff --git a/yazi-fm/src/lives/preference.rs b/yazi-actor/src/lives/preference.rs similarity index 100% rename from yazi-fm/src/lives/preference.rs rename to yazi-actor/src/lives/preference.rs diff --git a/yazi-fm/src/lives/preview.rs b/yazi-actor/src/lives/preview.rs similarity index 100% rename from yazi-fm/src/lives/preview.rs rename to yazi-actor/src/lives/preview.rs diff --git a/yazi-fm/src/lives/ptr.rs b/yazi-actor/src/lives/ptr.rs similarity index 100% rename from yazi-fm/src/lives/ptr.rs rename to yazi-actor/src/lives/ptr.rs diff --git a/yazi-fm/src/lives/selected.rs b/yazi-actor/src/lives/selected.rs similarity index 100% rename from yazi-fm/src/lives/selected.rs rename to yazi-actor/src/lives/selected.rs diff --git a/yazi-fm/src/lives/tab.rs b/yazi-actor/src/lives/tab.rs similarity index 100% rename from yazi-fm/src/lives/tab.rs rename to yazi-actor/src/lives/tab.rs diff --git a/yazi-fm/src/lives/tabs.rs b/yazi-actor/src/lives/tabs.rs similarity index 100% rename from yazi-fm/src/lives/tabs.rs rename to yazi-actor/src/lives/tabs.rs diff --git a/yazi-fm/src/lives/tasks.rs b/yazi-actor/src/lives/tasks.rs similarity index 100% rename from yazi-fm/src/lives/tasks.rs rename to yazi-actor/src/lives/tasks.rs diff --git a/yazi-fm/src/lives/yanked.rs b/yazi-actor/src/lives/yanked.rs similarity index 100% rename from yazi-fm/src/lives/yanked.rs rename to yazi-actor/src/lives/yanked.rs diff --git a/yazi-actor/src/mgr/quit.rs b/yazi-actor/src/mgr/quit.rs index 528fbc33..c05378cf 100644 --- a/yazi-actor/src/mgr/quit.rs +++ b/yazi-actor/src/mgr/quit.rs @@ -59,6 +59,10 @@ impl Actor for Quit { }); succ!(); } + + fn hook(cx: &Ctx, _opt: &Self::Options) -> Option<&'static str> { + Some("key-quit").filter(|_| cx.source().is_key()) + } } impl Quit { diff --git a/yazi-actor/src/mgr/search.rs b/yazi-actor/src/mgr/search.rs index 8399168b..a377b7f0 100644 --- a/yazi-actor/src/mgr/search.rs +++ b/yazi-actor/src/mgr/search.rs @@ -6,7 +6,7 @@ use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream}; use yazi_config::popup::InputCfg; use yazi_fs::{FilesOp, cha::Cha}; use yazi_macro::{act, succ}; -use yazi_parser::mgr::{SearchOpt, SearchOptVia}; +use yazi_parser::{VoidOpt, mgr::{SearchOpt, SearchOptVia}}; use yazi_plugin::external; use yazi_proxy::{InputProxy, MgrProxy}; use yazi_shared::event::Data; @@ -97,7 +97,7 @@ impl Actor for SearchDo { pub struct SearchStop; impl Actor for SearchStop { - type Options = (); + type Options = VoidOpt; const NAME: &str = "search_stop"; diff --git a/yazi-actor/src/mgr/sort.rs b/yazi-actor/src/mgr/sort.rs index dc8b4db7..b8d3c097 100644 --- a/yazi-actor/src/mgr/sort.rs +++ b/yazi-actor/src/mgr/sort.rs @@ -1,26 +1,24 @@ -use std::str::FromStr; - use anyhow::Result; -use yazi_fs::SortBy; use yazi_macro::{act, succ}; -use yazi_shared::event::{CmdCow, Data}; +use yazi_parser::mgr::SortOpt; +use yazi_shared::event::Data; use crate::{Actor, Ctx}; pub struct Sort; impl Actor for Sort { - type Options = CmdCow; + type Options = SortOpt; const NAME: &str = "sort"; - fn act(cx: &mut Ctx, c: Self::Options) -> Result { + fn act(cx: &mut Ctx, opt: Self::Options) -> Result { let mut new = cx.tab().pref.clone(); - new.sort_by = c.first_str().and_then(|s| SortBy::from_str(s).ok()).unwrap_or(new.sort_by); - new.sort_reverse = c.maybe_bool("reverse").unwrap_or(new.sort_reverse); - new.sort_dir_first = c.maybe_bool("dir-first").unwrap_or(new.sort_dir_first); - new.sort_sensitive = c.maybe_bool("sensitive").unwrap_or(new.sort_sensitive); - new.sort_translit = c.maybe_bool("translit").unwrap_or(new.sort_translit); + new.sort_by = opt.by.unwrap_or(new.sort_by); + new.sort_reverse = opt.reverse.unwrap_or(new.sort_reverse); + new.sort_dir_first = opt.dir_first.unwrap_or(new.sort_dir_first); + new.sort_sensitive = opt.sensitive.unwrap_or(new.sort_sensitive); + new.sort_translit = opt.translit.unwrap_or(new.sort_translit); if new == cx.tab().pref { succ!(); diff --git a/yazi-actor/src/mgr/tab_close.rs b/yazi-actor/src/mgr/tab_close.rs index 4c1be15d..2a0b9efb 100644 --- a/yazi-actor/src/mgr/tab_close.rs +++ b/yazi-actor/src/mgr/tab_close.rs @@ -27,7 +27,7 @@ impl Actor for TabClose { tabs.set_idx(usize::min(tabs.cursor + 1, tabs.len() - 1)); } - let cx = &mut Ctx::active(cx.core); + let cx = &mut Ctx::renew(cx); act!(mgr:refresh, cx)?; act!(mgr:peek, cx, true)?; diff --git a/yazi-actor/src/mgr/tab_create.rs b/yazi-actor/src/mgr/tab_create.rs index 60167988..7ca89f64 100644 --- a/yazi-actor/src/mgr/tab_create.rs +++ b/yazi-actor/src/mgr/tab_create.rs @@ -41,7 +41,7 @@ impl Actor for TabCreate { tabs.items.insert(tabs.cursor + 1, tab); tabs.set_idx(tabs.cursor + 1); - let cx = &mut Ctx::active(cx.core); + let cx = &mut Ctx::renew(cx); if cd { act!(mgr:cd, cx, (url, CdSource::Tab))?; } else { diff --git a/yazi-actor/src/mgr/tab_swap.rs b/yazi-actor/src/mgr/tab_swap.rs index 5f26ec0d..8d181b57 100644 --- a/yazi-actor/src/mgr/tab_swap.rs +++ b/yazi-actor/src/mgr/tab_swap.rs @@ -23,7 +23,7 @@ impl Actor for TabSwap { tabs.items.swap(tabs.cursor, new); tabs.set_idx(new); - let cx = &mut Ctx::active(cx.core); + let cx = &mut Ctx::renew(cx); act!(mgr:refresh, cx)?; act!(mgr:peek, cx, true)?; diff --git a/yazi-actor/src/mgr/tab_switch.rs b/yazi-actor/src/mgr/tab_switch.rs index 96602496..0ff7ef29 100644 --- a/yazi-actor/src/mgr/tab_switch.rs +++ b/yazi-actor/src/mgr/tab_switch.rs @@ -25,7 +25,7 @@ impl Actor for TabSwitch { } tabs.set_idx(idx); - let cx = &mut Ctx::active(cx.core); + let cx = &mut Ctx::renew(cx); act!(mgr:refresh, cx)?; act!(mgr:peek, cx, true)?; diff --git a/yazi-adapter/src/adapter.rs b/yazi-adapter/src/adapter.rs index e6296726..658f2def 100644 --- a/yazi-adapter/src/adapter.rs +++ b/yazi-adapter/src/adapter.rs @@ -7,7 +7,7 @@ use yazi_shared::env_exists; use crate::{Emulator, SHOWN, TMUX, drivers}; -#[derive(Clone, Copy, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Adapter { Kgp, KgpOld, diff --git a/yazi-adapter/src/brand.rs b/yazi-adapter/src/brand.rs index b61fc187..91c740f6 100644 --- a/yazi-adapter/src/brand.rs +++ b/yazi-adapter/src/brand.rs @@ -3,7 +3,7 @@ use yazi_shared::env_exists; use crate::Mux; -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Brand { Kitty, Konsole, diff --git a/yazi-adapter/src/unknown.rs b/yazi-adapter/src/unknown.rs index 6d6a578f..fc1f447a 100644 --- a/yazi-adapter/src/unknown.rs +++ b/yazi-adapter/src/unknown.rs @@ -1,6 +1,6 @@ use crate::Adapter; -#[derive(Debug, Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub struct Unknown { pub kgp: bool, pub sixel: bool, diff --git a/yazi-binding/Cargo.toml b/yazi-binding/Cargo.toml index 5adbbd99..1fb7e0c2 100644 --- a/yazi-binding/Cargo.toml +++ b/yazi-binding/Cargo.toml @@ -8,6 +8,10 @@ description = "Yazi Lua bindings" homepage = "https://yazi-rs.github.io" repository = "https://github.com/sxyazi/yazi" +[features] +default = [ "vendored-lua" ] +vendored-lua = [ "mlua/vendored" ] + [dependencies] yazi-adapter = { path = "../yazi-adapter", version = "25.6.11" } yazi-config = { path = "../yazi-config", version = "25.6.11" } diff --git a/yazi-binding/src/lib.rs b/yazi-binding/src/lib.rs index ff8a8cc1..0271786a 100644 --- a/yazi-binding/src/lib.rs +++ b/yazi-binding/src/lib.rs @@ -4,4 +4,4 @@ mod macros; yazi_macro::mod_pub!(elements); -yazi_macro::mod_flat!(cha color composer error file icon id iter permit runtime source stage style url urn utils); +yazi_macro::mod_flat!(cha color composer error file icon id iter permit runtime stage style url urn utils); diff --git a/yazi-binding/src/macros.rs b/yazi-binding/src/macros.rs index 8e49b235..a3b8b9f7 100644 --- a/yazi-binding/src/macros.rs +++ b/yazi-binding/src/macros.rs @@ -24,7 +24,7 @@ macro_rules! deprecate { None => "`init.lua` config", }; yazi_macro::emit!(Call( - yazi_shared::event::Cmd::new("app:deprecate").with("content", format!($tt, id)) + yazi_macro::relay!(app:deprecate).with("content", format!($tt, id)) )); } }}; diff --git a/yazi-binding/src/source.rs b/yazi-binding/src/source.rs deleted file mode 100644 index 7b6fe2b4..00000000 --- a/yazi-binding/src/source.rs +++ /dev/null @@ -1,7 +0,0 @@ -use mlua::{IntoLua, Lua, Value}; - -pub struct Source(pub yazi_shared::Source); - -impl IntoLua for Source { - fn into_lua(self, lua: &Lua) -> mlua::Result { self.0.bits().into_lua(lua) } -} diff --git a/yazi-config/src/keymap/chord.rs b/yazi-config/src/keymap/chord.rs index f2e39766..80923bd7 100644 --- a/yazi-config/src/keymap/chord.rs +++ b/yazi-config/src/keymap/chord.rs @@ -3,7 +3,7 @@ use std::{borrow::Cow, hash::{Hash, Hasher}, sync::OnceLock}; use anyhow::Result; use regex::Regex; use serde::Deserialize; -use yazi_shared::{Layer, event::Cmd}; +use yazi_shared::{Layer, Source, event::Cmd}; use super::Key; @@ -60,6 +60,7 @@ impl Chord { impl Chord { pub(super) fn reshape(mut self, layer: Layer) -> Result { for cmd in &mut self.run { + cmd.source = Source::Key; if cmd.layer == Default::default() { cmd.layer = layer; } diff --git a/yazi-config/src/keymap/key.rs b/yazi-config/src/keymap/key.rs index 62e2e8a9..5b85c025 100644 --- a/yazi-config/src/keymap/key.rs +++ b/yazi-config/src/keymap/key.rs @@ -3,7 +3,7 @@ use std::{fmt::{Display, Write}, str::FromStr}; use anyhow::bail; use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct Key { pub code: KeyCode, pub shift: bool, diff --git a/yazi-config/src/layout.rs b/yazi-config/src/layout.rs index b2f220b7..46f39d0c 100644 --- a/yazi-config/src/layout.rs +++ b/yazi-config/src/layout.rs @@ -1,6 +1,6 @@ use ratatui::layout::Rect; -#[derive(Clone, Copy, Default, PartialEq, Eq)] +#[derive(Clone, Copy, Default, Eq, PartialEq)] pub struct Layout { pub current: Rect, pub preview: Rect, diff --git a/yazi-config/src/mgr/mouse.rs b/yazi-config/src/mgr/mouse.rs index b4b82c5b..b1d68b7f 100644 --- a/yazi-config/src/mgr/mouse.rs +++ b/yazi-config/src/mgr/mouse.rs @@ -4,7 +4,7 @@ use crossterm::event::MouseEventKind; use serde::{Deserialize, Serialize}; bitflags! { - #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Deserialize, Serialize)] + #[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(try_from = "Vec", into = "Vec")] pub struct MouseEvents: u8 { const CLICK = 0b00001; diff --git a/yazi-config/src/mgr/ratio.rs b/yazi-config/src/mgr/ratio.rs index c27c50f8..2840b96e 100644 --- a/yazi-config/src/mgr/ratio.rs +++ b/yazi-config/src/mgr/ratio.rs @@ -1,7 +1,7 @@ use anyhow::bail; use serde::{Deserialize, Serialize}; -#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(try_from = "[u16; 3]")] pub struct MgrRatio { pub parent: u16, diff --git a/yazi-config/src/opener/rule.rs b/yazi-config/src/opener/rule.rs index 7079248b..20075c87 100644 --- a/yazi-config/src/opener/rule.rs +++ b/yazi-config/src/opener/rule.rs @@ -1,7 +1,7 @@ use anyhow::{Result, bail}; use serde::Deserialize; -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct OpenerRule { pub run: String, #[serde(default)] diff --git a/yazi-config/src/preview/wrap.rs b/yazi-config/src/preview/wrap.rs index af24f20e..cf9fc6f7 100644 --- a/yazi-config/src/preview/wrap.rs +++ b/yazi-config/src/preview/wrap.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "kebab-case")] pub enum PreviewWrap { No, diff --git a/yazi-config/src/priority.rs b/yazi-config/src/priority.rs index 1aa5ff9d..4caeafa2 100644 --- a/yazi-config/src/priority.rs +++ b/yazi-config/src/priority.rs @@ -1,6 +1,6 @@ use serde::Deserialize; -#[derive(Default, Clone, Copy, Debug, Deserialize)] +#[derive(Clone, Copy, Debug, Default, Deserialize)] #[serde(rename_all = "kebab-case")] pub enum Priority { Low = 0, diff --git a/yazi-dds/src/body/before_default.rs b/yazi-dds/src/body/before_default.rs deleted file mode 100644 index b8f09812..00000000 --- a/yazi-dds/src/body/before_default.rs +++ /dev/null @@ -1,72 +0,0 @@ -use anyhow::bail; - -use crate::body::Body; - -macro_rules! unsupported { - [ $( $layer:ident : $name:ident $(<$lt:lifetime>)? $(,)? )+ ] => { - $( - paste::paste! { - unsupported!(yazi_parser::$layer::[<$name:camel Opt>] $(<$lt>)?); - } - )+ - }; - [ $( $path:path $(,)? )+ ] => { - $( - impl TryFrom<&$path> for Body<'static> { - type Error = anyhow::Error; - - fn try_from(_: &$path) -> Result { - bail!("unsupported"); - } - } - )+ - }; -} - -unsupported!( - mgr:cd - mgr:close - mgr:copy - mgr:create - mgr:escape - mgr:filter - mgr:find - mgr:find_arrow - mgr:find_do - mgr:forward - mgr:hardlink - mgr:hidden - mgr:linemode - mgr:link - mgr:open - mgr:open_do - mgr:paste - mgr:peek - mgr:remove - mgr:rename - mgr:reveal - mgr:search - mgr:seek - mgr:shell - mgr:spot - mgr:tab_close - mgr:tab_create - mgr:tab_switch - mgr:toggle - mgr:toggle_all - mgr:update_files - mgr:update_mimes - mgr:update_paged - mgr:update_peeked - mgr:update_spotted - mgr:update_tasks - mgr:update_yanked<'_> - mgr:visual_mode - mgr:yank -); - -unsupported!( - yazi_parser::ArrowOpt - yazi_parser::VoidOpt - yazi_shared::event::CmdCow -); diff --git a/yazi-dds/src/body/before_quit.rs b/yazi-dds/src/body/before_quit.rs deleted file mode 100644 index 244997db..00000000 --- a/yazi-dds/src/body/before_quit.rs +++ /dev/null @@ -1,36 +0,0 @@ -use mlua::{IntoLua, Lua, Value}; -use serde::{Deserialize, Serialize}; -use yazi_parser::mgr::QuitOpt; -use yazi_shared::Source; - -use crate::{body::Body, local_or_err}; - -#[derive(Debug, Serialize, Deserialize)] -pub struct BeforeQuitBody { - pub opts: QuitOpt, - pub source: Source, -} - -impl IntoLua for BeforeQuitBody { - fn into_lua(self, lua: &Lua) -> mlua::Result { - lua - .create_table_from([ - ("opts", self.opts.into_lua(lua)?), - ("source", yazi_binding::Source(self.source).into_lua(lua)?), - ])? - .into_lua(lua) - } -} - -impl TryFrom<&QuitOpt> for Body<'static> { - type Error = anyhow::Error; - - fn try_from(value: &QuitOpt) -> Result { - local_or_err!("before-quit"); - - Ok(Body::BeforeQuit(BeforeQuitBody { - opts: value.clone(), - source: Source::default(), // FIXME - })) - } -} diff --git a/yazi-dds/src/body/body.rs b/yazi-dds/src/body/body.rs index 08340153..57af5c60 100644 --- a/yazi-dds/src/body/body.rs +++ b/yazi-dds/src/body/body.rs @@ -1,13 +1,11 @@ use anyhow::{Result, bail}; use mlua::{ExternalResult, IntoLua, Lua, Value}; -use serde::Serialize; use yazi_shared::Id; -use super::{BeforeQuitBody, BodyBulk, BodyBye, BodyCd, BodyCustom, BodyDelete, BodyHey, BodyHi, BodyHover, BodyLoad, BodyMount, BodyMove, BodyRename, BodyTab, BodyTrash, BodyYank}; +use super::{BodyBulk, BodyBye, BodyCd, BodyCustom, BodyDelete, BodyHey, BodyHi, BodyHover, BodyLoad, BodyMount, BodyMove, BodyRename, BodyTab, BodyTrash, BodyYank}; use crate::Payload; -#[derive(Debug, Serialize)] -#[serde(untagged)] +#[derive(Debug)] pub enum Body<'a> { Hi(BodyHi<'a>), Hey(BodyHey), @@ -23,8 +21,74 @@ pub enum Body<'a> { Trash(BodyTrash<'a>), Delete(BodyDelete<'a>), Mount(BodyMount), - BeforeQuit(BeforeQuitBody), Custom(BodyCustom), + + // Manager key events + KeyArrow(&'a yazi_parser::ArrowOpt), + KeyBack(&'a yazi_parser::VoidOpt), + KeyBulkRename(&'a yazi_parser::VoidOpt), + KeyCd(&'a yazi_parser::mgr::CdOpt), + KeyClose(&'a yazi_parser::mgr::CloseOpt), + KeyCopy(&'a yazi_parser::mgr::CopyOpt), + KeyCreate(&'a yazi_parser::mgr::CreateOpt), + KeyEnter(&'a yazi_parser::VoidOpt), + KeyEscape(&'a yazi_parser::mgr::EscapeOpt), + KeyEscapeFilter(&'a yazi_parser::VoidOpt), + KeyEscapeFind(&'a yazi_parser::VoidOpt), + KeyEscapeSearch(&'a yazi_parser::VoidOpt), + KeyEscapeSelect(&'a yazi_parser::VoidOpt), + KeyEscapeVisual(&'a yazi_parser::VoidOpt), + KeyFilter(&'a yazi_parser::mgr::FilterOpt), + KeyFilterDo(&'a yazi_parser::mgr::FilterOpt), + KeyFind(&'a yazi_parser::mgr::FindOpt), + KeyFindArrow(&'a yazi_parser::mgr::FindArrowOpt), + KeyFindDo(&'a yazi_parser::mgr::FindDoOpt), + KeyFollow(&'a yazi_parser::VoidOpt), + KeyForward(&'a yazi_parser::VoidOpt), + KeyHardlink(&'a yazi_parser::mgr::HardlinkOpt), + KeyHidden(&'a yazi_parser::mgr::HiddenOpt), + KeyHover(&'a yazi_parser::mgr::HoverOpt), + KeyHoverDo(&'a yazi_parser::mgr::HoverDoOpt), + KeyLeave(&'a yazi_parser::VoidOpt), + KeyLinemode(&'a yazi_parser::mgr::LinemodeOpt), + KeyLink(&'a yazi_parser::mgr::LinkOpt), + KeyOpen(&'a yazi_parser::mgr::OpenOpt), + KeyOpenDo(&'a yazi_parser::mgr::OpenDoOpt), + KeyPaste(&'a yazi_parser::mgr::PasteOpt), + KeyPeek(&'a yazi_parser::mgr::PeekOpt), + KeyQuit(&'a yazi_parser::mgr::QuitOpt), + KeyRefresh(&'a yazi_parser::VoidOpt), + KeyRemove(&'a yazi_parser::mgr::RemoveOpt), + KeyRemoveDo(&'a yazi_parser::mgr::RemoveOpt), + KeyRename(&'a yazi_parser::mgr::RenameOpt), + KeyReveal(&'a yazi_parser::mgr::RevealOpt), + KeySearch(&'a yazi_parser::mgr::SearchOpt), + KeySearchDo(&'a yazi_parser::mgr::SearchOpt), + KeySearchStop(&'a yazi_parser::VoidOpt), + KeySeek(&'a yazi_parser::mgr::SeekOpt), + KeyShell(&'a yazi_parser::mgr::ShellOpt), + KeySort(&'a yazi_parser::mgr::SortOpt), + KeySpot(&'a yazi_parser::mgr::SpotOpt), + KeySuspend(&'a yazi_parser::VoidOpt), + KeyTabClose(&'a yazi_parser::mgr::TabCloseOpt), + KeyTabCreate(&'a yazi_parser::mgr::TabCreateOpt), + KeyTabSwap(&'a yazi_parser::ArrowOpt), + KeyTabSwitch(&'a yazi_parser::mgr::TabSwitchOpt), + KeyToggle(&'a yazi_parser::mgr::ToggleOpt), + KeyToggleAll(&'a yazi_parser::mgr::ToggleAllOpt), + KeyUnyank(&'a yazi_parser::VoidOpt), + KeyUpdateFiles(&'a yazi_parser::mgr::UpdateFilesOpt), + KeyUpdateMimes(&'a yazi_parser::mgr::UpdateMimesOpt), + KeyUpdatePaged(&'a yazi_parser::mgr::UpdatePagedOpt), + KeyUpdatePeeked(&'a yazi_parser::mgr::UpdatePeekedOpt), + KeyUpdateSpotted(&'a yazi_parser::mgr::UpdateSpottedOpt), + KeyUpdateTasks(&'a yazi_parser::mgr::UpdateTasksOpt), + KeyUpdateYanked(&'a yazi_parser::mgr::UpdateYankedOpt<'a>), + KeyVisualMode(&'a yazi_parser::mgr::VisualModeOpt), + KeyWatch(&'a yazi_parser::VoidOpt), + KeyYank(&'a yazi_parser::mgr::YankOpt), + // Void + Void(&'a yazi_parser::VoidOpt), } impl Body<'static> { @@ -44,7 +108,6 @@ impl Body<'static> { "trash" => Self::Trash(serde_json::from_str(body)?), "delete" => Self::Delete(serde_json::from_str(body)?), "mount" => Self::Mount(serde_json::from_str(body)?), - "before-quit" => Self::BeforeQuit(serde_json::from_str(body)?), _ => BodyCustom::from_str(kind, body)?, }) } @@ -71,8 +134,13 @@ impl Body<'static> { | "trash" | "delete" | "mount" - | "before-quit" - ) { + ) || kind.starts_with("emit-") + || kind.starts_with("emit-ind-") + || kind.starts_with("ind-") + || kind.starts_with("key-") + || kind.starts_with("relay-") + || kind.starts_with("relay-ind-") + { bail!("Cannot construct system event"); } @@ -106,8 +174,74 @@ impl<'a> Body<'a> { Self::Trash(_) => "trash", Self::Delete(_) => "delete", Self::Mount(_) => "mount", - Self::BeforeQuit(_) => "before-quit", Self::Custom(b) => b.kind.as_str(), + + // Manager key events + Self::KeyArrow(_) => "key-arrow", + Self::KeyBack(_) => "key-back", + Self::KeyBulkRename(_) => "key-bulk-rename", + Self::KeyCd(_) => "key-cd", + Self::KeyClose(_) => "key-close", + Self::KeyCopy(_) => "key-copy", + Self::KeyCreate(_) => "key-create", + Self::KeyEnter(_) => "key-enter", + Self::KeyEscape(_) => "key-escape", + Self::KeyEscapeFilter(_) => "key-escape-filter", + Self::KeyEscapeFind(_) => "key-escape-find", + Self::KeyEscapeSearch(_) => "key-escape-search", + Self::KeyEscapeSelect(_) => "key-escape-select", + Self::KeyEscapeVisual(_) => "key-escape-visual", + Self::KeyFilter(_) => "key-filter", + Self::KeyFilterDo(_) => "key-filter-do", + Self::KeyFind(_) => "key-find", + Self::KeyFindArrow(_) => "key-find-arrow", + Self::KeyFindDo(_) => "key-find-do", + Self::KeyFollow(_) => "key-follow", + Self::KeyForward(_) => "key-forward", + Self::KeyHardlink(_) => "key-hardlink", + Self::KeyHidden(_) => "key-hidden", + Self::KeyHover(_) => "key-hover", + Self::KeyHoverDo(_) => "key-hover-do", + Self::KeyLeave(_) => "key-leave", + Self::KeyLinemode(_) => "key-linemode", + Self::KeyLink(_) => "key-link", + Self::KeyOpen(_) => "key-open", + Self::KeyOpenDo(_) => "key-open-do", + Self::KeyPaste(_) => "key-paste", + Self::KeyPeek(_) => "key-peek", + Self::KeyQuit(_) => "key-quit", + Self::KeyRefresh(_) => "key-refresh", + Self::KeyRemove(_) => "key-remove", + Self::KeyRemoveDo(_) => "key-remove-do", + Self::KeyRename(_) => "key-rename", + Self::KeyReveal(_) => "key-reveal", + Self::KeySearch(_) => "key-search", + Self::KeySearchDo(_) => "key-search-do", + Self::KeySearchStop(_) => "key-search-stop", + Self::KeySeek(_) => "key-seek", + Self::KeyShell(_) => "key-shell", + Self::KeySort(_) => "key-sort", + Self::KeySpot(_) => "key-spot", + Self::KeySuspend(_) => "key-suspend", + Self::KeyTabClose(_) => "key-tab-close", + Self::KeyTabCreate(_) => "key-tab-create", + Self::KeyTabSwap(_) => "key-tab-swap", + Self::KeyTabSwitch(_) => "key-tab-switch", + Self::KeyToggle(_) => "key-toggle", + Self::KeyToggleAll(_) => "key-toggle-all", + Self::KeyUnyank(_) => "key-unyank", + Self::KeyUpdateFiles(_) => "key-update-files", + Self::KeyUpdateMimes(_) => "key-update-mimes", + Self::KeyUpdatePaged(_) => "key-update-paged", + Self::KeyUpdatePeeked(_) => "key-update-peeked", + Self::KeyUpdateSpotted(_) => "key-update-spotted", + Self::KeyUpdateTasks(_) => "key-update-tasks", + Self::KeyUpdateYanked(_) => "key-update-yanked", + Self::KeyVisualMode(_) => "key-visual-mode", + Self::KeyWatch(_) => "key-watch", + Self::KeyYank(_) => "key-yank", + // Void + Self::Void(_) => "void", } } @@ -120,7 +254,7 @@ impl<'a> Body<'a> { pub fn with_sender(self, sender: Id) -> Payload<'a> { Payload::new(self).with_sender(sender) } } -impl IntoLua for Body<'static> { +impl<'a> IntoLua for Body<'a> { fn into_lua(self, lua: &Lua) -> mlua::Result { match self { Self::Hi(b) => b.into_lua(lua), @@ -137,8 +271,74 @@ impl IntoLua for Body<'static> { Self::Trash(b) => b.into_lua(lua), Self::Delete(b) => b.into_lua(lua), Self::Mount(b) => b.into_lua(lua), - Self::BeforeQuit(b) => b.into_lua(lua), Self::Custom(b) => b.into_lua(lua), + + // Manager key events + Self::KeyArrow(b) => b.into_lua(lua), + Self::KeyBack(b) => b.into_lua(lua), + Self::KeyBulkRename(b) => b.into_lua(lua), + Self::KeyCd(b) => b.into_lua(lua), + Self::KeyClose(b) => b.into_lua(lua), + Self::KeyCopy(b) => b.into_lua(lua), + Self::KeyCreate(b) => b.into_lua(lua), + Self::KeyEnter(b) => b.into_lua(lua), + Self::KeyEscape(b) => b.into_lua(lua), + Self::KeyEscapeFilter(b) => b.into_lua(lua), + Self::KeyEscapeFind(b) => b.into_lua(lua), + Self::KeyEscapeSearch(b) => b.into_lua(lua), + Self::KeyEscapeSelect(b) => b.into_lua(lua), + Self::KeyEscapeVisual(b) => b.into_lua(lua), + Self::KeyFilter(b) => b.into_lua(lua), + Self::KeyFilterDo(b) => b.into_lua(lua), + Self::KeyFind(b) => b.into_lua(lua), + Self::KeyFindArrow(b) => b.into_lua(lua), + Self::KeyFindDo(b) => b.into_lua(lua), + Self::KeyFollow(b) => b.into_lua(lua), + Self::KeyForward(b) => b.into_lua(lua), + Self::KeyHardlink(b) => b.into_lua(lua), + Self::KeyHidden(b) => b.into_lua(lua), + Self::KeyHover(b) => b.into_lua(lua), + Self::KeyHoverDo(b) => b.into_lua(lua), + Self::KeyLeave(b) => b.into_lua(lua), + Self::KeyLinemode(b) => b.into_lua(lua), + Self::KeyLink(b) => b.into_lua(lua), + Self::KeyOpen(b) => b.into_lua(lua), + Self::KeyOpenDo(b) => b.into_lua(lua), + Self::KeyPaste(b) => b.into_lua(lua), + Self::KeyPeek(b) => b.into_lua(lua), + Self::KeyQuit(b) => b.into_lua(lua), + Self::KeyRefresh(b) => b.into_lua(lua), + Self::KeyRemove(b) => b.into_lua(lua), + Self::KeyRemoveDo(b) => b.into_lua(lua), + Self::KeyRename(b) => b.into_lua(lua), + Self::KeyReveal(b) => b.into_lua(lua), + Self::KeySearch(b) => b.into_lua(lua), + Self::KeySearchDo(b) => b.into_lua(lua), + Self::KeySearchStop(b) => b.into_lua(lua), + Self::KeySeek(b) => b.into_lua(lua), + Self::KeyShell(b) => b.into_lua(lua), + Self::KeySort(b) => b.into_lua(lua), + Self::KeySpot(b) => b.into_lua(lua), + Self::KeySuspend(b) => b.into_lua(lua), + Self::KeyTabClose(b) => b.into_lua(lua), + Self::KeyTabCreate(b) => b.into_lua(lua), + Self::KeyTabSwap(b) => b.into_lua(lua), + Self::KeyTabSwitch(b) => b.into_lua(lua), + Self::KeyToggle(b) => b.into_lua(lua), + Self::KeyToggleAll(b) => b.into_lua(lua), + Self::KeyUnyank(b) => b.into_lua(lua), + Self::KeyUpdateFiles(b) => b.into_lua(lua), + Self::KeyUpdateMimes(b) => b.into_lua(lua), + Self::KeyUpdatePaged(b) => b.into_lua(lua), + Self::KeyUpdatePeeked(b) => b.into_lua(lua), + Self::KeyUpdateSpotted(b) => b.into_lua(lua), + Self::KeyUpdateTasks(b) => b.into_lua(lua), + Self::KeyUpdateYanked(b) => b.into_lua(lua), + Self::KeyVisualMode(b) => b.into_lua(lua), + Self::KeyWatch(b) => b.into_lua(lua), + Self::KeyYank(b) => b.into_lua(lua), + // Void + Self::Void(b) => b.into_lua(lua), } } } diff --git a/yazi-dds/src/body/bulk.rs b/yazi-dds/src/body/bulk.rs index 0dd77b5e..761e9b88 100644 --- a/yazi-dds/src/body/bulk.rs +++ b/yazi-dds/src/body/bulk.rs @@ -1,6 +1,6 @@ -use std::{borrow::Cow, collections::{HashMap, hash_map}}; +use std::{borrow::Cow, collections::HashMap}; -use mlua::{AnyUserData, IntoLua, IntoLuaMulti, Lua, MetaMethod, UserData, UserDataRefMut, Value}; +use mlua::{IntoLua, Lua, Value}; use serde::{Deserialize, Serialize}; use yazi_shared::url::Url; @@ -34,32 +34,15 @@ impl<'a> From> for Body<'a> { fn from(value: BodyBulk<'a>) -> Self { Self::Bulk(value) } } -impl IntoLua for BodyBulk<'static> { +impl IntoLua for BodyBulk<'_> { fn into_lua(self, lua: &Lua) -> mlua::Result { - BodyBulkIter { inner: self.changes.into_iter() }.into_lua(lua) - } -} - -// --- Iterator -// TODO: use `yazi_binding::Iter` instead -pub struct BodyBulkIter { - pub inner: hash_map::IntoIter, Cow<'static, Url>>, -} - -impl UserData for BodyBulkIter { - fn add_methods>(methods: &mut M) { - methods.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.inner.len())); - - methods.add_meta_function(MetaMethod::Pairs, |lua, me: AnyUserData| { - let iter = lua.create_function(|lua, mut me: UserDataRefMut| { - if let Some((Cow::Owned(from), Cow::Owned(to))) = me.inner.next() { - (yazi_binding::Url::new(from), yazi_binding::Url::new(to)).into_lua_multi(lua) - } else { - ().into_lua_multi(lua) - } - })?; - - Ok((iter, me)) - }); + lua + .create_table_from( + self + .changes + .into_iter() + .map(|(from, to)| (yazi_binding::Url::new(from), yazi_binding::Url::new(to))), + )? + .into_lua(lua) } } diff --git a/yazi-dds/src/body/cd.rs b/yazi-dds/src/body/cd.rs index f897bcdf..9e3f53b1 100644 --- a/yazi-dds/src/body/cd.rs +++ b/yazi-dds/src/body/cd.rs @@ -30,7 +30,7 @@ impl<'a> From> for Body<'a> { fn from(value: BodyCd<'a>) -> Self { Self::Cd(value) } } -impl IntoLua for BodyCd<'static> { +impl IntoLua for BodyCd<'_> { fn into_lua(self, lua: &Lua) -> mlua::Result { lua .create_table_from([ diff --git a/yazi-dds/src/body/delete.rs b/yazi-dds/src/body/delete.rs index a88ee19f..8c0fbf17 100644 --- a/yazi-dds/src/body/delete.rs +++ b/yazi-dds/src/body/delete.rs @@ -23,7 +23,7 @@ impl<'a> From> for Body<'a> { fn from(value: BodyDelete<'a>) -> Self { Self::Delete(value) } } -impl IntoLua for BodyDelete<'static> { +impl IntoLua for BodyDelete<'_> { fn into_lua(self, lua: &Lua) -> mlua::Result { let urls = lua.create_sequence_from(self.urls.into_owned().into_iter().map(yazi_binding::Url::new))?; diff --git a/yazi-dds/src/body/hover.rs b/yazi-dds/src/body/hover.rs index 6b479f79..c9559397 100644 --- a/yazi-dds/src/body/hover.rs +++ b/yazi-dds/src/body/hover.rs @@ -26,7 +26,7 @@ impl<'a> From> for Body<'a> { fn from(value: BodyHover<'a>) -> Self { Self::Hover(value) } } -impl IntoLua for BodyHover<'static> { +impl IntoLua for BodyHover<'_> { fn into_lua(self, lua: &Lua) -> mlua::Result { lua .create_table_from([ diff --git a/yazi-dds/src/body/load.rs b/yazi-dds/src/body/load.rs index 85e89dce..af22dbc9 100644 --- a/yazi-dds/src/body/load.rs +++ b/yazi-dds/src/body/load.rs @@ -30,7 +30,7 @@ impl<'a> From> for Body<'a> { fn from(value: BodyLoad<'a>) -> Self { Self::Load(value) } } -impl IntoLua for BodyLoad<'static> { +impl IntoLua for BodyLoad<'_> { fn into_lua(self, lua: &Lua) -> mlua::Result { lua .create_table_from([ diff --git a/yazi-dds/src/body/mod.rs b/yazi-dds/src/body/mod.rs index 62f7926b..f19aac64 100644 --- a/yazi-dds/src/body/mod.rs +++ b/yazi-dds/src/body/mod.rs @@ -1,5 +1,5 @@ #![allow(clippy::module_inception)] yazi_macro::mod_flat!( - before_default before_quit body bulk bye cd custom delete hey hi hover load mount r#move rename tab trash yank + body bulk bye cd custom delete hey hi hover load mount r#move rename tab trash yank ); diff --git a/yazi-dds/src/body/move.rs b/yazi-dds/src/body/move.rs index ad1ea44b..45320080 100644 --- a/yazi-dds/src/body/move.rs +++ b/yazi-dds/src/body/move.rs @@ -27,7 +27,7 @@ impl<'a> From> for Body<'a> { fn from(value: BodyMove<'a>) -> Self { Self::Move(value) } } -impl IntoLua for BodyMove<'static> { +impl IntoLua for BodyMove<'_> { fn into_lua(self, lua: &Lua) -> mlua::Result { lua.create_table_from([("items", self.items.into_owned())])?.into_lua(lua) } diff --git a/yazi-dds/src/body/rename.rs b/yazi-dds/src/body/rename.rs index 1f6ce75a..d4aa41c7 100644 --- a/yazi-dds/src/body/rename.rs +++ b/yazi-dds/src/body/rename.rs @@ -29,7 +29,7 @@ impl<'a> From> for Body<'a> { fn from(value: BodyRename<'a>) -> Self { Self::Rename(value) } } -impl IntoLua for BodyRename<'static> { +impl IntoLua for BodyRename<'_> { fn into_lua(self, lua: &Lua) -> mlua::Result { lua .create_table_from([ diff --git a/yazi-dds/src/body/trash.rs b/yazi-dds/src/body/trash.rs index 92991661..01fd9eda 100644 --- a/yazi-dds/src/body/trash.rs +++ b/yazi-dds/src/body/trash.rs @@ -23,7 +23,7 @@ impl<'a> From> for Body<'a> { fn from(value: BodyTrash<'a>) -> Self { Self::Trash(value) } } -impl IntoLua for BodyTrash<'static> { +impl IntoLua for BodyTrash<'_> { fn into_lua(self, lua: &Lua) -> mlua::Result { let urls = lua.create_sequence_from(self.urls.into_owned().into_iter().map(yazi_binding::Url::new))?; diff --git a/yazi-dds/src/body/yank.rs b/yazi-dds/src/body/yank.rs index 0b072307..3f1f443e 100644 --- a/yazi-dds/src/body/yank.rs +++ b/yazi-dds/src/body/yank.rs @@ -26,6 +26,6 @@ impl<'a> From> for Body<'a> { fn from(value: BodyYank<'a>) -> Self { Self::Yank(value) } } -impl IntoLua for BodyYank<'static> { +impl IntoLua for BodyYank<'_> { fn into_lua(self, lua: &Lua) -> mlua::Result { self.0.into_lua(lua) } } diff --git a/yazi-dds/src/macros.rs b/yazi-dds/src/macros.rs index 4ee8d03e..1b9d202d 100644 --- a/yazi-dds/src/macros.rs +++ b/yazi-dds/src/macros.rs @@ -1,8 +1,14 @@ #[macro_export] -macro_rules! local_or_err { - ($name:literal) => { - if !$crate::LOCAL.read().contains_key($name) { - anyhow::bail!("No local event handler found"); +macro_rules! body { + (mgr: $name:ident, $body:expr) => { + paste::paste! { + $crate::body::Body::[]($body) } }; + ($layer:ident : $name:ident, $body:expr) => { + $crate::body::Body::Void(&yazi_parser::VoidOpt) + // paste::paste! { + // $crate::body::Body::[]($body) + // } + }; } diff --git a/yazi-dds/src/payload.rs b/yazi-dds/src/payload.rs index 0408190d..e2e119c3 100644 --- a/yazi-dds/src/payload.rs +++ b/yazi-dds/src/payload.rs @@ -2,8 +2,8 @@ use std::{fmt::Display, io::Write, str::FromStr}; use anyhow::{Result, anyhow}; use yazi_boot::BOOT; -use yazi_macro::emit; -use yazi_shared::{Id, event::Cmd}; +use yazi_macro::{emit, relay}; +use yazi_shared::Id; use crate::{ID, body::Body}; @@ -47,7 +47,7 @@ impl<'a> Payload<'a> { impl Payload<'static> { pub(super) fn emit(self) -> Result<()> { self.try_flush()?; - emit!(Call(Cmd::new("app:accept_payload").with_any("payload", self))); + emit!(Call(relay!(app:accept_payload).with_any("payload", self))); Ok(()) } } @@ -93,8 +93,8 @@ impl Display for Payload<'_> { Body::Trash(b) => serde_json::to_string(b), Body::Delete(b) => serde_json::to_string(b), Body::Mount(b) => serde_json::to_string(b), - Body::BeforeQuit(b) => serde_json::to_string(b), Body::Custom(b) => serde_json::to_string(b), + _ => return Err(std::fmt::Error), }; if let Ok(s) = result { diff --git a/yazi-fm/Cargo.toml b/yazi-fm/Cargo.toml index 7ee042af..e8d23203 100644 --- a/yazi-fm/Cargo.toml +++ b/yazi-fm/Cargo.toml @@ -44,9 +44,7 @@ anyhow = { workspace = true } better-panic = "0.3.0" crossterm = { workspace = true } fdlimit = "0.3.0" -foldhash = { workspace = true } futures = { workspace = true } -indexmap = { workspace = true } mlua = { workspace = true } paste = { workspace = true } ratatui = { workspace = true } diff --git a/yazi-fm/src/app/app.rs b/yazi-fm/src/app/app.rs index 0c9a0d14..63fb9064 100644 --- a/yazi-fm/src/app/app.rs +++ b/yazi-fm/src/app/app.rs @@ -21,7 +21,6 @@ impl App { let mut app = Self { core: Core::make(), term: Some(term), signals }; act!(bootstrap, app)?; - act!(render, app)?; let mut events = Vec::with_capacity(50); let (mut timeout, mut last_render) = (None, Instant::now()); diff --git a/yazi-fm/src/app/commands/accept_payload.rs b/yazi-fm/src/app/commands/accept_payload.rs index 9d76154c..a95b70eb 100644 --- a/yazi-fm/src/app/commands/accept_payload.rs +++ b/yazi-fm/src/app/commands/accept_payload.rs @@ -1,14 +1,14 @@ use anyhow::{Result, bail}; -use mlua::{IntoLua, Value}; +use mlua::IntoLua; use tracing::error; +use yazi_actor::lives::Lives; use yazi_binding::runtime_mut; -use yazi_core::Core; -use yazi_dds::{LOCAL, Payload, REMOTE, body::Body}; +use yazi_dds::{LOCAL, Payload, REMOTE}; use yazi_macro::succ; use yazi_plugin::LUA; use yazi_shared::event::{CmdCow, Data}; -use crate::{app::App, lives::Lives}; +use crate::app::App; impl App { pub(crate) fn accept_payload(&self, mut c: CmdCow) -> Result { @@ -38,32 +38,4 @@ impl App { Ok(()) })?); } - - // FIXME: find a better name - pub(crate) fn accept_payload2(core: &Core, body: Body<'static>) -> Result { - let kind = body.kind(); - let Some(handlers) = LOCAL.read().get(kind).filter(|&m| !m.is_empty()).cloned() else { - succ!(false) - }; - - let kind = kind.to_owned(); - succ!(Lives::scope(core, || { - let body = body.into_lua(&LUA)?; - for (id, cb) in handlers { - runtime_mut!(LUA)?.push(&id); - let result = cb.call::(body.clone()); - runtime_mut!(LUA)?.pop(); - - match result { - Ok(Value::Boolean(true)) => return Ok(true), - Ok(Value::Nil | Value::Boolean(false)) => {} - Ok(v) => { - error!("Unexpected return type from `{kind}` event handler in `{id}` plugin: {v:?}") - } - Err(e) => error!("Failed to run `{kind}` event handler in `{id}` plugin: {e}"), - } - } - Ok(false) - })?); - } } diff --git a/yazi-fm/src/app/commands/bootstrap.rs b/yazi-fm/src/app/commands/bootstrap.rs index 5fb23763..3ffbe4cf 100644 --- a/yazi-fm/src/app/commands/bootstrap.rs +++ b/yazi-fm/src/app/commands/bootstrap.rs @@ -1,7 +1,7 @@ use anyhow::Result; use yazi_actor::Ctx; use yazi_boot::BOOT; -use yazi_macro::{act, succ}; +use yazi_macro::act; use yazi_parser::{VoidOpt, mgr::CdSource}; use yazi_shared::{event::Data, url::Url}; @@ -15,7 +15,9 @@ impl App { tabs.push(Default::default()); } - let cx = &mut Ctx { core: &mut self.core, tab: i }; + let cx = &mut Ctx::active(&mut self.core); + cx.tab = i; + if file.is_empty() { act!(mgr:cd, cx, (Url::from(&BOOT.cwds[i]), CdSource::Tab))?; } else { @@ -23,6 +25,6 @@ impl App { } } - succ!(); + act!(render, self) } } diff --git a/yazi-fm/src/app/commands/mouse.rs b/yazi-fm/src/app/commands/mouse.rs index c6984c74..70cefe6e 100644 --- a/yazi-fm/src/app/commands/mouse.rs +++ b/yazi-fm/src/app/commands/mouse.rs @@ -2,13 +2,14 @@ use anyhow::Result; use crossterm::event::MouseEventKind; use mlua::{ObjectLike, Table}; use tracing::error; +use yazi_actor::lives::Lives; use yazi_config::YAZI; use yazi_macro::succ; use yazi_parser::app::MouseOpt; use yazi_plugin::LUA; use yazi_shared::event::Data; -use crate::{app::App, lives::Lives}; +use crate::app::App; impl App { pub fn mouse(&mut self, opt: MouseOpt) -> Result { diff --git a/yazi-fm/src/app/commands/plugin.rs b/yazi-fm/src/app/commands/plugin.rs index ca9ed0d6..52002b68 100644 --- a/yazi-fm/src/app/commands/plugin.rs +++ b/yazi-fm/src/app/commands/plugin.rs @@ -2,6 +2,7 @@ use anyhow::Result; use mlua::ObjectLike; use scopeguard::defer; use tracing::{error, warn}; +use yazi_actor::lives::Lives; use yazi_binding::runtime_mut; use yazi_dds::Sendable; use yazi_macro::succ; @@ -10,7 +11,7 @@ use yazi_plugin::{LUA, loader::{LOADER, Loader}}; use yazi_proxy::AppProxy; use yazi_shared::event::Data; -use crate::{app::App, lives::Lives}; +use crate::app::App; impl App { pub(crate) fn plugin(&mut self, mut opt: PluginOpt) -> Result { diff --git a/yazi-fm/src/app/commands/reflow.rs b/yazi-fm/src/app/commands/reflow.rs index 9c73e56d..f6f19314 100644 --- a/yazi-fm/src/app/commands/reflow.rs +++ b/yazi-fm/src/app/commands/reflow.rs @@ -2,12 +2,13 @@ use anyhow::Result; use mlua::Value; use ratatui::layout::Position; use tracing::error; +use yazi_actor::lives::Lives; use yazi_config::LAYOUT; use yazi_macro::{render, succ}; use yazi_parser::VoidOpt; use yazi_shared::event::Data; -use crate::{Root, app::App, lives::Lives}; +use crate::{Root, app::App}; impl App { pub fn reflow(&mut self, _: VoidOpt) -> Result { diff --git a/yazi-fm/src/app/commands/render.rs b/yazi-fm/src/app/commands/render.rs index e9b17b1a..8d71a41c 100644 --- a/yazi-fm/src/app/commands/render.rs +++ b/yazi-fm/src/app/commands/render.rs @@ -3,14 +3,14 @@ use std::sync::atomic::{AtomicU8, Ordering}; use anyhow::Result; use crossterm::{cursor::{MoveTo, SetCursorStyle, Show}, execute, queue, terminal::{BeginSynchronizedUpdate, EndSynchronizedUpdate}}; use ratatui::{CompletedFrame, backend::{Backend, CrosstermBackend}, buffer::Buffer, layout::Position}; -use yazi_actor::Ctx; +use yazi_actor::{Ctx, lives::Lives}; use yazi_binding::elements::COLLISION; use yazi_macro::{act, succ}; use yazi_parser::VoidOpt; use yazi_shared::event::{Data, NEED_RENDER}; use yazi_term::tty::TTY; -use crate::{app::App, lives::Lives, root::Root}; +use crate::{app::App, root::Root}; impl App { pub(crate) fn render(&mut self, _: VoidOpt) -> Result { @@ -36,7 +36,8 @@ impl App { // Reload preview if collision is resolved if collision && !COLLISION.load(Ordering::Relaxed) { - act!(mgr:peek, &mut Ctx::active(&mut self.core), true)?; + let cx = &mut Ctx::active(&mut self.core); + act!(mgr:peek, cx, true)?; } succ!(); } diff --git a/yazi-fm/src/app/commands/resize.rs b/yazi-fm/src/app/commands/resize.rs index 23851b84..97f11e3b 100644 --- a/yazi-fm/src/app/commands/resize.rs +++ b/yazi-fm/src/app/commands/resize.rs @@ -14,6 +14,7 @@ impl App { self.core.parent_mut().map(|f| f.arrow(0)); self.core.current_mut().sync_page(true); - act!(mgr:peek, &mut Ctx::active(&mut self.core)) + let cx = &mut Ctx::active(&mut self.core); + act!(mgr:peek, cx) } } diff --git a/yazi-fm/src/app/commands/update_progress.rs b/yazi-fm/src/app/commands/update_progress.rs index d6215422..bf85fcfc 100644 --- a/yazi-fm/src/app/commands/update_progress.rs +++ b/yazi-fm/src/app/commands/update_progress.rs @@ -18,7 +18,8 @@ impl App { let new = tasks.paginate(); if tasks.summaries != new { tasks.summaries = new; - act!(tasks:arrow, &mut Ctx::active(&mut self.core))?; + let cx = &mut Ctx::active(&mut self.core); + act!(tasks:arrow, cx)?; succ!(render!()); } } diff --git a/yazi-fm/src/executor.rs b/yazi-fm/src/executor.rs index 0f698c14..7979236b 100644 --- a/yazi-fm/src/executor.rs +++ b/yazi-fm/src/executor.rs @@ -1,6 +1,5 @@ use anyhow::Result; -use yazi_actor::{Actor, Ctx}; -use yazi_dds::body::Body; +use yazi_actor::Ctx; use yazi_macro::{act, succ}; use yazi_shared::{Layer, event::{CmdCow, Data}}; use yazi_widgets::input::InputMode; @@ -57,16 +56,10 @@ impl<'a> Executor<'a> { fn mgr(&mut self, cmd: CmdCow) -> Result { let cx = &mut Ctx::new(&mut self.app.core, &cmd)?; - // FIXME: move the DDS part to `yazi-actor` macro_rules! on { ($name:ident) => { if cmd.name == stringify!($name) { - let opt = ::Options::try_from(cmd)?; - return if let Ok(body) = Body::try_from(&opt) && App::accept_payload2(cx.core, body)? == true { - succ!() - } else { - act!(mgr:$name, cx, opt) - }; + return act!(mgr:$name, cx, cmd) } }; } diff --git a/yazi-fm/src/main.rs b/yazi-fm/src/main.rs index ff65fe81..62089e61 100644 --- a/yazi-fm/src/main.rs +++ b/yazi-fm/src/main.rs @@ -4,7 +4,7 @@ #[global_allocator] static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; -yazi_macro::mod_pub!(app cmp confirm help input lives mgr notify pick spot tasks which); +yazi_macro::mod_pub!(app cmp confirm help input mgr notify pick spot tasks which); yazi_macro::mod_flat!(dispatcher executor logs panic root router signals term); diff --git a/yazi-fs/src/op.rs b/yazi-fs/src/op.rs index 1c0c07f1..6377ecdb 100644 --- a/yazi-fs/src/op.rs +++ b/yazi-fs/src/op.rs @@ -1,6 +1,7 @@ use std::collections::{HashMap, HashSet}; -use yazi_shared::{Id, Ids, event::Cmd, url::{Url, UrnBuf}}; +use yazi_macro::relay; +use yazi_shared::{Id, Ids, url::{Url, UrnBuf}}; use super::File; use crate::{cha::Cha, maybe_exists}; @@ -40,8 +41,7 @@ impl FilesOp { #[inline] pub fn emit(self) { - yazi_shared::event::Event::Call(Cmd::new("mgr:update_files").with_any("op", self).into()) - .emit(); + yazi_shared::event::Event::Call(relay!(mgr:update_files).with_any("op", self).into()).emit(); } pub fn prepare(cwd: &Url) -> Id { diff --git a/yazi-macro/src/actor.rs b/yazi-macro/src/actor.rs index b9b8fcc3..f73b1199 100644 --- a/yazi-macro/src/actor.rs +++ b/yazi-macro/src/actor.rs @@ -1,22 +1,37 @@ #[macro_export] macro_rules! act { - ($layer:ident : $name:ident, $cx:expr, $cmd:expr) => {{ - #[allow(unused_imports)] - use ::yazi_actor::Actor; - ::act($cx, $cmd.try_into()?) - }}; - ($layer:ident : $name:ident, $cx:expr) => {{ - #[allow(unused_imports)] - use yazi_actor::Actor; - ::act($cx, Default::default()) - }}; - ($name:ident, $cx:expr, $cmd:expr) => { - $cx.$name($cmd.try_into()?) + (@pre $layer:ident : $name:ident, $cx:ident, $opt:ident) => { + ::hook($cx, &$opt).map(|hook| { + ::act($cx, (hook, yazi_dds::body!($layer:$name, &$opt))) + }) }; - ($name:ident, $cx:expr) => { - $cx.$name(Default::default()) + (@impl $layer:ident : $name:ident, $cx:ident, $opt:ident) => {{ + $cx.level += 1; + let result = match act!(@pre $layer:$name, $cx, $opt) { + None | Some(Ok(yazi_shared::event::Data::Boolean(false))) => ::act($cx, $opt), + Some(Ok(_)) => Err(anyhow::anyhow!("canceled on preflight")), + Some(e @ Err(_)) => e, + }; + $cx.level -= 1; + result + }}; + + ($layer:ident : $name:ident, $cx:ident, $cmd:expr) => { + ::Options::try_from($cmd) + .map_err(anyhow::Error::from) + .and_then(|opt| act!(@impl $layer:$name, $cx, opt)) + }; + ($layer:ident : $name:ident, $cx:ident) => { + act!($layer:$name, $cx, <::Options as Default>::default()) }; ($layer:ident : $name:ident) => { paste::paste! { yazi_actor::$layer::[<$name:camel>] } }; + + ($name:ident, $cx:expr, $cmd:expr) => { + $cmd.try_into().map_err(anyhow::Error::from).and_then(|opt| $cx.$name(opt)) + }; + ($name:ident, $cx:expr) => { + $cx.$name(Default::default()) + }; } diff --git a/yazi-macro/src/event.rs b/yazi-macro/src/event.rs index 06d50ff9..a42092b4 100644 --- a/yazi-macro/src/event.rs +++ b/yazi-macro/src/event.rs @@ -14,6 +14,19 @@ macro_rules! emit { }; } +#[macro_export] +macro_rules! relay { + ($layer:ident : $name:ident) => { + yazi_shared::event::Cmd::new_relay(concat!(stringify!($layer), ":", stringify!($name))) + }; + ($layer:ident : $name:ident, $args:expr) => { + yazi_shared::event::Cmd::new_relay_args( + concat!(stringify!($layer), ":", stringify!($name)), + $args, + ) + }; +} + #[macro_export] macro_rules! succ { ($data:expr) => { @@ -23,34 +36,3 @@ macro_rules! succ { return Ok(yazi_shared::event::Data::Nil) }; } - -#[macro_export] -macro_rules! render { - () => { - yazi_shared::event::NEED_RENDER.store(true, std::sync::atomic::Ordering::Relaxed); - }; - ($cond:expr) => { - if $cond { - render!(); - } - }; - ($left:expr, > $right:expr) => {{ - let val = $left; - if val > $right { - render!(); - } - val - }}; -} - -#[macro_export] -macro_rules! render_and { - ($cond:expr) => { - if $cond { - yazi_macro::render!(); - true - } else { - false - } - }; -} diff --git a/yazi-macro/src/lib.rs b/yazi-macro/src/lib.rs index 90fc0cb9..db8a7f4d 100644 --- a/yazi-macro/src/lib.rs +++ b/yazi-macro/src/lib.rs @@ -5,4 +5,5 @@ mod fmt; mod log; mod module; mod platform; +mod render; mod stdio; diff --git a/yazi-macro/src/render.rs b/yazi-macro/src/render.rs new file mode 100644 index 00000000..5bdf9864 --- /dev/null +++ b/yazi-macro/src/render.rs @@ -0,0 +1,30 @@ +#[macro_export] +macro_rules! render { + () => { + yazi_shared::event::NEED_RENDER.store(true, std::sync::atomic::Ordering::Relaxed); + }; + ($cond:expr) => { + if $cond { + render!(); + } + }; + ($left:expr, > $right:expr) => {{ + let val = $left; + if val > $right { + render!(); + } + val + }}; +} + +#[macro_export] +macro_rules! render_and { + ($cond:expr) => { + if $cond { + yazi_macro::render!(); + true + } else { + false + } + }; +} diff --git a/yazi-parser/Cargo.toml b/yazi-parser/Cargo.toml index cb246dc5..0e88a45e 100644 --- a/yazi-parser/Cargo.toml +++ b/yazi-parser/Cargo.toml @@ -8,6 +8,10 @@ description = "Yazi command parser" homepage = "https://yazi-rs.github.io" repository = "https://github.com/sxyazi/yazi" +[features] +default = [ "vendored-lua" ] +vendored-lua = [ "mlua/vendored" ] + [dependencies] yazi-binding = { path = "../yazi-binding", version = "25.6.11" } yazi-boot = { path = "../yazi-boot", version = "25.6.11" } diff --git a/yazi-parser/src/arrow.rs b/yazi-parser/src/arrow.rs index 48f121b9..a8a164c4 100644 --- a/yazi-parser/src/arrow.rs +++ b/yazi-parser/src/arrow.rs @@ -1,9 +1,10 @@ use anyhow::bail; +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::CmdCow; use crate::Step; -#[derive(Default)] +#[derive(Clone, Copy, Debug, Default)] pub struct ArrowOpt { pub step: Step, } @@ -23,3 +24,7 @@ impl TryFrom for ArrowOpt { impl From for ArrowOpt { fn from(n: isize) -> Self { Self { step: n.into() } } } + +impl IntoLua for ArrowOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/forward.rs b/yazi-parser/src/input/forward.rs similarity index 100% rename from yazi-parser/src/mgr/forward.rs rename to yazi-parser/src/input/forward.rs diff --git a/yazi-parser/src/input/mod.rs b/yazi-parser/src/input/mod.rs index 344a371e..9f587eba 100644 --- a/yazi-parser/src/input/mod.rs +++ b/yazi-parser/src/input/mod.rs @@ -1 +1 @@ -yazi_macro::mod_flat!(backspace backward close complete delete insert kill r#move paste show); +yazi_macro::mod_flat!(backspace backward close complete delete forward insert kill paste r#move show); diff --git a/yazi-parser/src/mgr/back.rs b/yazi-parser/src/mgr/back.rs deleted file mode 100644 index 8b137891..00000000 --- a/yazi-parser/src/mgr/back.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/yazi-parser/src/mgr/cd.rs b/yazi-parser/src/mgr/cd.rs index ab6e722a..d1ced338 100644 --- a/yazi-parser/src/mgr/cd.rs +++ b/yazi-parser/src/mgr/cd.rs @@ -1,6 +1,8 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_fs::expand_path; use yazi_shared::{event::CmdCow, url::Url}; +#[derive(Debug)] pub struct CdOpt { pub target: Url, pub interactive: bool, @@ -21,8 +23,12 @@ impl From<(Url, CdSource)> for CdOpt { fn from((target, source): (Url, CdSource)) -> Self { Self { target, interactive: false, source } } } +impl IntoLua for &CdOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} + // --- Source -#[derive(Clone, Copy, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum CdSource { Tab, Cd, diff --git a/yazi-parser/src/mgr/close.rs b/yazi-parser/src/mgr/close.rs index bfc77c9d..7ad879ee 100644 --- a/yazi-parser/src/mgr/close.rs +++ b/yazi-parser/src/mgr/close.rs @@ -1,10 +1,15 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::CmdCow; use crate::mgr::QuitOpt; -#[derive(Default)] +#[derive(Debug, Default)] pub struct CloseOpt(pub QuitOpt); impl From for CloseOpt { fn from(c: CmdCow) -> Self { Self(c.into()) } } + +impl IntoLua for &CloseOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/copy.rs b/yazi-parser/src/mgr/copy.rs index 554bd9a5..5c8220a6 100644 --- a/yazi-parser/src/mgr/copy.rs +++ b/yazi-parser/src/mgr/copy.rs @@ -1,7 +1,9 @@ use std::{borrow::Cow, ffi::OsStr, path::Path}; +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::{SStr, event::CmdCow}; +#[derive(Debug)] pub struct CopyOpt { pub r#type: SStr, pub separator: CopySeparator, @@ -18,8 +20,12 @@ impl From for CopyOpt { } } +impl IntoLua for &CopyOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} + // --- Separator -#[derive(Clone, Copy, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum CopySeparator { Auto, Unix, diff --git a/yazi-parser/src/mgr/create.rs b/yazi-parser/src/mgr/create.rs index 49b3fce9..228f0bd2 100644 --- a/yazi-parser/src/mgr/create.rs +++ b/yazi-parser/src/mgr/create.rs @@ -1,5 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::CmdCow; +#[derive(Debug)] pub struct CreateOpt { pub dir: bool, pub force: bool, @@ -8,3 +10,7 @@ pub struct CreateOpt { impl From for CreateOpt { fn from(c: CmdCow) -> Self { Self { dir: c.bool("dir"), force: c.bool("force") } } } + +impl IntoLua for &CreateOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/enter.rs b/yazi-parser/src/mgr/enter.rs deleted file mode 100644 index 8b137891..00000000 --- a/yazi-parser/src/mgr/enter.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/yazi-parser/src/mgr/escape.rs b/yazi-parser/src/mgr/escape.rs index 10bef8cb..b9c58194 100644 --- a/yazi-parser/src/mgr/escape.rs +++ b/yazi-parser/src/mgr/escape.rs @@ -1,7 +1,9 @@ use bitflags::bitflags; +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::CmdCow; bitflags! { + #[derive(Debug)] pub struct EscapeOpt: u8 { const FIND = 0b00001; const VISUAL = 0b00010; @@ -26,3 +28,7 @@ impl From for EscapeOpt { }) } } + +impl IntoLua for &EscapeOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/filter.rs b/yazi-parser/src/mgr/filter.rs index cd9e3f8e..36aa20d5 100644 --- a/yazi-parser/src/mgr/filter.rs +++ b/yazi-parser/src/mgr/filter.rs @@ -1,7 +1,8 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_fs::FilterCase; use yazi_shared::{SStr, event::CmdCow}; -#[derive(Default)] +#[derive(Debug, Default)] pub struct FilterOpt { pub query: SStr, pub case: FilterCase, @@ -23,3 +24,7 @@ impl TryFrom for FilterOpt { }) } } + +impl IntoLua for &FilterOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/find.rs b/yazi-parser/src/mgr/find.rs index 942ffd5a..d720b458 100644 --- a/yazi-parser/src/mgr/find.rs +++ b/yazi-parser/src/mgr/find.rs @@ -1,6 +1,8 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_fs::FilterCase; use yazi_shared::event::CmdCow; +#[derive(Debug)] pub struct FindOpt { pub prev: bool, pub case: FilterCase, @@ -13,3 +15,7 @@ impl TryFrom for FindOpt { Ok(Self { prev: c.bool("previous"), case: FilterCase::from(&*c) }) } } + +impl IntoLua for &FindOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/find_arrow.rs b/yazi-parser/src/mgr/find_arrow.rs index 3936ae2b..5089406d 100644 --- a/yazi-parser/src/mgr/find_arrow.rs +++ b/yazi-parser/src/mgr/find_arrow.rs @@ -1,5 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::CmdCow; +#[derive(Debug)] pub struct FindArrowOpt { pub prev: bool, } @@ -7,3 +9,7 @@ pub struct FindArrowOpt { impl From for FindArrowOpt { fn from(c: CmdCow) -> Self { Self { prev: c.bool("previous") } } } + +impl IntoLua for &FindArrowOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/find_do.rs b/yazi-parser/src/mgr/find_do.rs index 0cbc9828..15c357d9 100644 --- a/yazi-parser/src/mgr/find_do.rs +++ b/yazi-parser/src/mgr/find_do.rs @@ -1,7 +1,9 @@ use anyhow::bail; +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_fs::FilterCase; use yazi_shared::{SStr, event::CmdCow}; +#[derive(Debug)] pub struct FindDoOpt { pub query: SStr, pub prev: bool, @@ -23,3 +25,7 @@ impl TryFrom for FindDoOpt { Ok(Self { query, prev: c.bool("previous"), case: FilterCase::from(&*c) }) } } + +impl IntoLua for &FindDoOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/hardlink.rs b/yazi-parser/src/mgr/hardlink.rs index d02fb1d6..e004c250 100644 --- a/yazi-parser/src/mgr/hardlink.rs +++ b/yazi-parser/src/mgr/hardlink.rs @@ -1,5 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::CmdCow; +#[derive(Debug)] pub struct HardlinkOpt { pub force: bool, pub follow: bool, @@ -8,3 +10,7 @@ pub struct HardlinkOpt { impl From for HardlinkOpt { fn from(c: CmdCow) -> Self { Self { force: c.bool("force"), follow: c.bool("follow") } } } + +impl IntoLua for &HardlinkOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/hidden.rs b/yazi-parser/src/mgr/hidden.rs index aba2adcd..0fa8b482 100644 --- a/yazi-parser/src/mgr/hidden.rs +++ b/yazi-parser/src/mgr/hidden.rs @@ -1,5 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::CmdCow; +#[derive(Debug)] pub struct HiddenOpt { pub state: Option, } @@ -15,3 +17,7 @@ impl From for HiddenOpt { Self { state } } } + +impl IntoLua for &HiddenOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/hover.rs b/yazi-parser/src/mgr/hover.rs index 55568532..16f95360 100644 --- a/yazi-parser/src/mgr/hover.rs +++ b/yazi-parser/src/mgr/hover.rs @@ -1,6 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::{event::CmdCow, url::Url}; -#[derive(Default)] +#[derive(Debug, Default)] pub struct HoverOpt { pub url: Option, } @@ -13,7 +14,12 @@ impl From> for HoverOpt { fn from(url: Option) -> Self { Self { url } } } +impl IntoLua for &HoverOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} + // --- Do +#[derive(Debug)] pub struct HoverDoOpt { pub url: Url, } @@ -21,3 +27,7 @@ pub struct HoverDoOpt { impl From for HoverDoOpt { fn from(url: Url) -> Self { Self { url } } } + +impl IntoLua for &HoverDoOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/linemode.rs b/yazi-parser/src/mgr/linemode.rs index 78f33935..01be03fa 100644 --- a/yazi-parser/src/mgr/linemode.rs +++ b/yazi-parser/src/mgr/linemode.rs @@ -1,6 +1,8 @@ use anyhow::bail; +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::{SStr, event::CmdCow}; +#[derive(Debug)] pub struct LinemodeOpt { pub new: SStr, } @@ -20,3 +22,7 @@ impl TryFrom for LinemodeOpt { Ok(Self { new }) } } + +impl IntoLua for &LinemodeOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/link.rs b/yazi-parser/src/mgr/link.rs index dd76a50b..af12d894 100644 --- a/yazi-parser/src/mgr/link.rs +++ b/yazi-parser/src/mgr/link.rs @@ -1,5 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::CmdCow; +#[derive(Debug)] pub struct LinkOpt { pub relative: bool, pub force: bool, @@ -8,3 +10,7 @@ pub struct LinkOpt { impl From for LinkOpt { fn from(c: CmdCow) -> Self { Self { relative: c.bool("relative"), force: c.bool("force") } } } + +impl IntoLua for &LinkOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/mod.rs b/yazi-parser/src/mgr/mod.rs index e7055cdb..d8ad26f2 100644 --- a/yazi-parser/src/mgr/mod.rs +++ b/yazi-parser/src/mgr/mod.rs @@ -1,16 +1,13 @@ yazi_macro::mod_flat!( - back cd close copy create - enter escape filter find find_arrow find_do - forward hardlink hidden hover @@ -26,6 +23,7 @@ yazi_macro::mod_flat!( search seek shell + sort spot tab_close tab_create diff --git a/yazi-parser/src/mgr/open.rs b/yazi-parser/src/mgr/open.rs index 3da47547..955b93a1 100644 --- a/yazi-parser/src/mgr/open.rs +++ b/yazi-parser/src/mgr/open.rs @@ -1,10 +1,11 @@ use std::borrow::Cow; use anyhow::anyhow; +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_config::opener::OpenerRule; use yazi_shared::{event::CmdCow, url::Url}; -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub struct OpenOpt { pub interactive: bool, pub hovered: bool, @@ -16,8 +17,12 @@ impl From for OpenOpt { } } +impl IntoLua for &OpenOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} + // --- Do -#[derive(Default)] +#[derive(Debug, Default)] pub struct OpenDoOpt { pub cwd: Url, pub hovered: Url, @@ -29,6 +34,10 @@ impl From for OpenDoOpt { fn from(mut c: CmdCow) -> Self { c.take_any("option").unwrap_or_default() } } +impl IntoLua for &OpenDoOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} + // --- Open with pub struct OpenWithOpt { pub opener: Cow<'static, OpenerRule>, diff --git a/yazi-parser/src/mgr/paste.rs b/yazi-parser/src/mgr/paste.rs index 8ca75fad..134b6b79 100644 --- a/yazi-parser/src/mgr/paste.rs +++ b/yazi-parser/src/mgr/paste.rs @@ -1,5 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::CmdCow; +#[derive(Debug)] pub struct PasteOpt { pub force: bool, pub follow: bool, @@ -8,3 +10,7 @@ pub struct PasteOpt { impl From for PasteOpt { fn from(c: CmdCow) -> Self { Self { force: c.bool("force"), follow: c.bool("follow") } } } + +impl IntoLua for &PasteOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/peek.rs b/yazi-parser/src/mgr/peek.rs index fccc26f1..1ac05f42 100644 --- a/yazi-parser/src/mgr/peek.rs +++ b/yazi-parser/src/mgr/peek.rs @@ -1,3 +1,4 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::{event::{CmdCow, Data}, url::Url}; #[derive(Debug, Default)] @@ -22,3 +23,7 @@ impl From for PeekOpt { impl From for PeekOpt { fn from(force: bool) -> Self { Self { force, ..Default::default() } } } + +impl IntoLua for &PeekOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/quit.rs b/yazi-parser/src/mgr/quit.rs index 3e5d5c22..087075d1 100644 --- a/yazi-parser/src/mgr/quit.rs +++ b/yazi-parser/src/mgr/quit.rs @@ -2,7 +2,7 @@ use mlua::{IntoLua, Lua, LuaSerdeExt, Value}; use serde::{Deserialize, Serialize}; use yazi_shared::event::{CmdCow, Data, EventQuit}; -#[derive(Clone, Debug, Default, Serialize, Deserialize)] +#[derive(Debug, Default, Serialize, Deserialize)] pub struct QuitOpt { pub code: i32, pub no_cwd_file: bool, @@ -23,6 +23,6 @@ impl From for EventQuit { } } -impl IntoLua for QuitOpt { - fn into_lua(self, lua: &Lua) -> mlua::Result { lua.to_value(&self) } +impl IntoLua for &QuitOpt { + fn into_lua(self, lua: &Lua) -> mlua::Result { lua.to_value(self) } } diff --git a/yazi-parser/src/mgr/remove.rs b/yazi-parser/src/mgr/remove.rs index dd425d77..a7c2c7f2 100644 --- a/yazi-parser/src/mgr/remove.rs +++ b/yazi-parser/src/mgr/remove.rs @@ -1,5 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::{event::CmdCow, url::Url}; +#[derive(Debug)] pub struct RemoveOpt { pub force: bool, pub permanently: bool, @@ -17,3 +19,7 @@ impl From for RemoveOpt { } } } + +impl IntoLua for &RemoveOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/rename.rs b/yazi-parser/src/mgr/rename.rs index e5b0e975..b64eb0a1 100644 --- a/yazi-parser/src/mgr/rename.rs +++ b/yazi-parser/src/mgr/rename.rs @@ -1,5 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::{SStr, event::CmdCow}; +#[derive(Debug)] pub struct RenameOpt { pub hovered: bool, pub force: bool, @@ -17,3 +19,7 @@ impl From for RenameOpt { } } } + +impl IntoLua for &RenameOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/reveal.rs b/yazi-parser/src/mgr/reveal.rs index 7f1e6e0a..c5938ff2 100644 --- a/yazi-parser/src/mgr/reveal.rs +++ b/yazi-parser/src/mgr/reveal.rs @@ -1,8 +1,10 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_fs::expand_path; use yazi_shared::{event::CmdCow, url::Url}; use crate::mgr::CdSource; +#[derive(Debug)] pub struct RevealOpt { pub target: Url, pub source: CdSource, @@ -27,3 +29,7 @@ impl From for RevealOpt { impl From<(Url, CdSource)> for RevealOpt { fn from((target, source): (Url, CdSource)) -> Self { Self { target, source, no_dummy: false } } } + +impl IntoLua for &RevealOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/search.rs b/yazi-parser/src/mgr/search.rs index e366b59c..193e76bd 100644 --- a/yazi-parser/src/mgr/search.rs +++ b/yazi-parser/src/mgr/search.rs @@ -1,6 +1,8 @@ use anyhow::bail; +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::{SStr, event::CmdCow}; +#[derive(Debug)] pub struct SearchOpt { pub via: SearchOptVia, pub subject: SStr, @@ -33,8 +35,12 @@ impl TryFrom for SearchOpt { } } +impl IntoLua for &SearchOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} + // Via -#[derive(Clone, Copy, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum SearchOptVia { Rg, Rga, diff --git a/yazi-parser/src/mgr/seek.rs b/yazi-parser/src/mgr/seek.rs index 238e40dc..0c1560d7 100644 --- a/yazi-parser/src/mgr/seek.rs +++ b/yazi-parser/src/mgr/seek.rs @@ -1,3 +1,4 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::{CmdCow, Data}; #[derive(Debug)] @@ -8,3 +9,7 @@ pub struct SeekOpt { impl From for SeekOpt { fn from(c: CmdCow) -> Self { Self { units: c.first().and_then(Data::as_i16).unwrap_or(0) } } } + +impl IntoLua for &SeekOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/shell.rs b/yazi-parser/src/mgr/shell.rs index b2bd9c73..8f89e950 100644 --- a/yazi-parser/src/mgr/shell.rs +++ b/yazi-parser/src/mgr/shell.rs @@ -1,6 +1,8 @@ use anyhow::bail; +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::{SStr, event::{CmdCow, Data}, url::Url}; +#[derive(Debug)] pub struct ShellOpt { pub run: SStr, pub cwd: Option, @@ -34,3 +36,7 @@ impl TryFrom for ShellOpt { Ok(me) } } + +impl IntoLua for &ShellOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/sort.rs b/yazi-parser/src/mgr/sort.rs new file mode 100644 index 00000000..5a97653b --- /dev/null +++ b/yazi-parser/src/mgr/sort.rs @@ -0,0 +1,32 @@ +use std::str::FromStr; + +use mlua::{ExternalError, IntoLua, Lua, Value}; +use yazi_fs::SortBy; +use yazi_shared::event::CmdCow; + +#[derive(Debug)] +pub struct SortOpt { + pub by: Option, + pub reverse: Option, + pub dir_first: Option, + pub sensitive: Option, + pub translit: Option, +} + +impl TryFrom for SortOpt { + type Error = anyhow::Error; + + fn try_from(c: CmdCow) -> Result { + Ok(Self { + by: c.first_str().map(SortBy::from_str).transpose()?, + reverse: c.maybe_bool("reverse"), + dir_first: c.maybe_bool("dir-first"), + sensitive: c.maybe_bool("sensitive"), + translit: c.maybe_bool("translit"), + }) + } +} + +impl IntoLua for &SortOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/spot.rs b/yazi-parser/src/mgr/spot.rs index 22fc421a..e2afe9c8 100644 --- a/yazi-parser/src/mgr/spot.rs +++ b/yazi-parser/src/mgr/spot.rs @@ -1,6 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::{CmdCow, Data}; -#[derive(Default)] +#[derive(Debug, Default)] pub struct SpotOpt { pub skip: Option, } @@ -12,3 +13,7 @@ impl From for SpotOpt { impl From for SpotOpt { fn from(skip: usize) -> Self { Self { skip: Some(skip) } } } + +impl IntoLua for &SpotOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/tab_close.rs b/yazi-parser/src/mgr/tab_close.rs index 546589f8..8fca1e2f 100644 --- a/yazi-parser/src/mgr/tab_close.rs +++ b/yazi-parser/src/mgr/tab_close.rs @@ -1,5 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::{CmdCow, Data}; +#[derive(Debug)] pub struct TabCloseOpt { pub idx: usize, } @@ -11,3 +13,7 @@ impl From for TabCloseOpt { impl From for TabCloseOpt { fn from(idx: usize) -> Self { Self { idx } } } + +impl IntoLua for &TabCloseOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/tab_create.rs b/yazi-parser/src/mgr/tab_create.rs index 64e352b4..4e1da1f4 100644 --- a/yazi-parser/src/mgr/tab_create.rs +++ b/yazi-parser/src/mgr/tab_create.rs @@ -1,7 +1,9 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_boot::BOOT; use yazi_fs::expand_path; use yazi_shared::{event::CmdCow, url::Url}; +#[derive(Debug)] pub struct TabCreateOpt { pub wd: Option, } @@ -20,3 +22,7 @@ impl From for TabCreateOpt { Self { wd: Some(wd) } } } + +impl IntoLua for &TabCreateOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/tab_switch.rs b/yazi-parser/src/mgr/tab_switch.rs index 680b8031..6291c668 100644 --- a/yazi-parser/src/mgr/tab_switch.rs +++ b/yazi-parser/src/mgr/tab_switch.rs @@ -1,5 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::{CmdCow, Data}; +#[derive(Debug)] pub struct TabSwitchOpt { pub step: isize, pub relative: bool, @@ -10,3 +12,7 @@ impl From for TabSwitchOpt { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0), relative: c.bool("relative") } } } + +impl IntoLua for &TabSwitchOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/toggle.rs b/yazi-parser/src/mgr/toggle.rs index 45ff892f..c70cc78d 100644 --- a/yazi-parser/src/mgr/toggle.rs +++ b/yazi-parser/src/mgr/toggle.rs @@ -1,5 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::{event::CmdCow, url::Url}; +#[derive(Debug)] pub struct ToggleOpt { pub url: Option, pub state: Option, @@ -17,3 +19,7 @@ impl From for ToggleOpt { } } } + +impl IntoLua for &ToggleOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/toggle_all.rs b/yazi-parser/src/mgr/toggle_all.rs index 03bcc071..2c8bb128 100644 --- a/yazi-parser/src/mgr/toggle_all.rs +++ b/yazi-parser/src/mgr/toggle_all.rs @@ -1,5 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::{event::CmdCow, url::Url}; +#[derive(Debug)] pub struct ToggleAllOpt { pub urls: Vec, pub state: Option, @@ -29,3 +31,7 @@ impl From for ToggleAllOpt { impl From> for ToggleAllOpt { fn from(state: Option) -> Self { Self { urls: vec![], state } } } + +impl IntoLua for &ToggleAllOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/update_files.rs b/yazi-parser/src/mgr/update_files.rs index 5332e610..ffceb4a3 100644 --- a/yazi-parser/src/mgr/update_files.rs +++ b/yazi-parser/src/mgr/update_files.rs @@ -1,7 +1,9 @@ use anyhow::bail; +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_fs::FilesOp; use yazi_shared::event::CmdCow; +#[derive(Debug)] pub struct UpdateFilesOpt { pub op: FilesOp, } @@ -17,3 +19,7 @@ impl TryFrom for UpdateFilesOpt { Ok(Self { op }) } } + +impl IntoLua for &UpdateFilesOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/update_mimes.rs b/yazi-parser/src/mgr/update_mimes.rs index dac6e54d..be66c910 100644 --- a/yazi-parser/src/mgr/update_mimes.rs +++ b/yazi-parser/src/mgr/update_mimes.rs @@ -1,8 +1,10 @@ use std::collections::HashMap; use anyhow::bail; +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::{CmdCow, Data, DataKey}; +#[derive(Debug)] pub struct UpdateMimesOpt { pub updates: HashMap, } @@ -18,3 +20,7 @@ impl TryFrom for UpdateMimesOpt { Ok(Self { updates }) } } + +impl IntoLua for &UpdateMimesOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/update_paged.rs b/yazi-parser/src/mgr/update_paged.rs index 7973a1b3..f77fb47d 100644 --- a/yazi-parser/src/mgr/update_paged.rs +++ b/yazi-parser/src/mgr/update_paged.rs @@ -1,6 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::{event::{CmdCow, Data}, url::Url}; -#[derive(Default)] +#[derive(Debug, Default)] pub struct UpdatePagedOpt { pub page: Option, pub only_if: Option, @@ -15,3 +16,7 @@ impl From for UpdatePagedOpt { impl From<()> for UpdatePagedOpt { fn from(_: ()) -> Self { Self::default() } } + +impl IntoLua for &UpdatePagedOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/update_peeked.rs b/yazi-parser/src/mgr/update_peeked.rs index d60a5801..bd21fb31 100644 --- a/yazi-parser/src/mgr/update_peeked.rs +++ b/yazi-parser/src/mgr/update_peeked.rs @@ -1,8 +1,9 @@ use anyhow::bail; -use mlua::Table; +use mlua::{ExternalError, IntoLua, Lua, Table, Value}; use yazi_binding::{FileRef, elements::{Rect, Renderable}}; use yazi_shared::event::CmdCow; +#[derive(Debug)] pub struct UpdatePeekedOpt { pub lock: PreviewLock, } @@ -23,6 +24,10 @@ impl TryFrom for UpdatePeekedOpt { } } +impl IntoLua for &UpdatePeekedOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} + // --- Lock #[derive(Debug, Default)] pub struct PreviewLock { diff --git a/yazi-parser/src/mgr/update_spotted.rs b/yazi-parser/src/mgr/update_spotted.rs index f0c1838f..47e2e852 100644 --- a/yazi-parser/src/mgr/update_spotted.rs +++ b/yazi-parser/src/mgr/update_spotted.rs @@ -1,8 +1,9 @@ use anyhow::bail; -use mlua::Table; +use mlua::{ExternalError, IntoLua, Lua, Table, Value}; use yazi_binding::{FileRef, elements::Renderable}; use yazi_shared::{Id, event::CmdCow}; +#[derive(Debug)] pub struct UpdateSpottedOpt { pub lock: SpotLock, } @@ -23,7 +24,12 @@ impl TryFrom for UpdateSpottedOpt { } } +impl IntoLua for &UpdateSpottedOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} + // --- Lock +#[derive(Debug)] pub struct SpotLock { pub url: yazi_shared::url::Url, pub cha: yazi_fs::cha::Cha, diff --git a/yazi-parser/src/mgr/update_tasks.rs b/yazi-parser/src/mgr/update_tasks.rs index ad7d6c87..1f7fdbbb 100644 --- a/yazi-parser/src/mgr/update_tasks.rs +++ b/yazi-parser/src/mgr/update_tasks.rs @@ -1,6 +1,8 @@ use anyhow::bail; +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::{event::CmdCow, url::Url}; +#[derive(Debug)] pub struct UpdateTasksOpt { pub urls: Vec, } @@ -16,3 +18,7 @@ impl TryFrom for UpdateTasksOpt { Ok(Self { urls }) } } + +impl IntoLua for &UpdateTasksOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/update_yanked.rs b/yazi-parser/src/mgr/update_yanked.rs index 463840bf..d1f60874 100644 --- a/yazi-parser/src/mgr/update_yanked.rs +++ b/yazi-parser/src/mgr/update_yanked.rs @@ -1,7 +1,7 @@ use std::{borrow::Cow, collections::HashSet}; use anyhow::bail; -use mlua::{AnyUserData, IntoLua, Lua, MetaMethod, MultiValue, ObjectLike, UserData, UserDataFields, UserDataMethods, Value}; +use mlua::{AnyUserData, ExternalError, IntoLua, Lua, MetaMethod, MultiValue, ObjectLike, UserData, UserDataFields, UserDataMethods, Value}; use serde::{Deserialize, Serialize}; use yazi_binding::get_metatable; use yazi_shared::{event::CmdCow, url::Url}; @@ -29,7 +29,7 @@ impl TryFrom for UpdateYankedOpt<'_> { } } -impl IntoLua for UpdateYankedOpt<'static> { +impl IntoLua for UpdateYankedOpt<'_> { fn into_lua(self, lua: &Lua) -> mlua::Result { let len = self.urls.len(); let iter = Iter::new(self.urls.into_owned().into_iter().map(yazi_binding::Url::new), Some(len)); @@ -37,6 +37,10 @@ impl IntoLua for UpdateYankedOpt<'static> { } } +impl IntoLua for &UpdateYankedOpt<'_> { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} + // --- Iter pub struct UpdateYankedIter { cut: bool, diff --git a/yazi-parser/src/mgr/visual_mode.rs b/yazi-parser/src/mgr/visual_mode.rs index c869eb21..f3eb5e8f 100644 --- a/yazi-parser/src/mgr/visual_mode.rs +++ b/yazi-parser/src/mgr/visual_mode.rs @@ -1,5 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::CmdCow; +#[derive(Debug)] pub struct VisualModeOpt { pub unset: bool, } @@ -7,3 +9,7 @@ pub struct VisualModeOpt { impl From for VisualModeOpt { fn from(c: CmdCow) -> Self { Self { unset: c.bool("unset") } } } + +impl IntoLua for &VisualModeOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/mgr/yank.rs b/yazi-parser/src/mgr/yank.rs index 6bfb1504..bc7225b8 100644 --- a/yazi-parser/src/mgr/yank.rs +++ b/yazi-parser/src/mgr/yank.rs @@ -1,5 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::CmdCow; +#[derive(Debug)] pub struct YankOpt { pub cut: bool, } @@ -7,3 +9,7 @@ pub struct YankOpt { impl From for YankOpt { fn from(c: CmdCow) -> Self { Self { cut: c.bool("cut") } } } + +impl IntoLua for &YankOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-parser/src/void.rs b/yazi-parser/src/void.rs index 0444efc8..abdd6ca1 100644 --- a/yazi-parser/src/void.rs +++ b/yazi-parser/src/void.rs @@ -1,6 +1,7 @@ +use mlua::{ExternalError, IntoLua, Lua, Value}; use yazi_shared::event::CmdCow; -#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct VoidOpt; impl From for VoidOpt { @@ -10,3 +11,7 @@ impl From for VoidOpt { impl From<()> for VoidOpt { fn from(_: ()) -> Self { Self } } + +impl IntoLua for VoidOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} diff --git a/yazi-plugin/src/loader/loader.rs b/yazi-plugin/src/loader/loader.rs index 8869e97b..1cf7aa3a 100644 --- a/yazi-plugin/src/loader/loader.rs +++ b/yazi-plugin/src/loader/loader.rs @@ -6,7 +6,7 @@ use parking_lot::RwLock; use tokio::fs; use yazi_boot::BOOT; use yazi_macro::plugin_preset as preset; -use yazi_shared::RoCell; +use yazi_shared::{LOG_LEVEL, RoCell}; use super::Chunk; @@ -94,7 +94,7 @@ impl Loader { }?; if mode != ChunkMode::Binary { - let b = f.dump(true); + let b = f.dump(LOG_LEVEL.get().is_none()); if let Some(c) = self.write().get_mut(id) { c.mode = ChunkMode::Binary; c.bytes = Cow::Owned(b); diff --git a/yazi-plugin/src/utils/call.rs b/yazi-plugin/src/utils/call.rs index c9636184..ba320088 100644 --- a/yazi-plugin/src/utils/call.rs +++ b/yazi-plugin/src/utils/call.rs @@ -2,7 +2,7 @@ use mlua::{Function, Lua, Table}; use yazi_binding::deprecate; use yazi_dds::Sendable; use yazi_macro::{emit, render}; -use yazi_shared::{Layer, event::Cmd}; +use yazi_shared::{Layer, Source, event::Cmd}; use super::Utils; @@ -18,7 +18,7 @@ impl Utils { pub(super) fn emit(lua: &Lua) -> mlua::Result { lua.create_function(|lua, (name, args): (String, Table)| { - let mut cmd = Cmd::new_or(name, Layer::Mgr)?; + let mut cmd = Cmd::new(name, Source::Emit, Some(Layer::Mgr))?; cmd.args = Sendable::table_to_args(lua, args)?; Ok(emit!(Call(cmd))) }) @@ -27,9 +27,10 @@ impl Utils { pub(super) fn mgr_emit(lua: &Lua) -> mlua::Result { lua.create_function(|lua, (name, args): (String, Table)| { emit!(Call(Cmd { - name: name.into(), - args: Sendable::table_to_args(lua, args)?, - layer: Layer::Mgr, + name: name.into(), + args: Sendable::table_to_args(lua, args)?, + layer: Layer::Mgr, + source: Source::Emit, })); Ok(()) }) diff --git a/yazi-plugin/src/utils/layer.rs b/yazi-plugin/src/utils/layer.rs index 579dcd8d..d09f8618 100644 --- a/yazi-plugin/src/utils/layer.rs +++ b/yazi-plugin/src/utils/layer.rs @@ -5,9 +5,10 @@ use tokio::sync::mpsc; use tokio_stream::wrappers::UnboundedReceiverStream; use yazi_binding::{deprecate, elements::{Line, Pos, Text}}; use yazi_config::{keymap::{Chord, Key}, popup::{ConfirmCfg, InputCfg}}; +use yazi_macro::relay; use yazi_parser::which::ShowOpt; use yazi_proxy::{AppProxy, ConfirmProxy, InputProxy, WhichProxy}; -use yazi_shared::{Debounce, event::Cmd}; +use yazi_shared::Debounce; use super::Utils; use crate::bindings::InputRx; @@ -22,7 +23,7 @@ impl Utils { let cand = cand?; cands.push(Chord { on: Self::parse_keys(cand.raw_get("on")?)?, - run: vec![Cmd::args("which:callback", [i]).with_any("tx", tx.clone())], + run: vec![relay!(which:callback, [i]).with_any("tx", tx.clone())], desc: cand.raw_get("desc").ok(), r#for: None, }); diff --git a/yazi-plugin/src/utils/sync.rs b/yazi-plugin/src/utils/sync.rs index 445e5187..37382129 100644 --- a/yazi-plugin/src/utils/sync.rs +++ b/yazi-plugin/src/utils/sync.rs @@ -1,3 +1,4 @@ +use anyhow::Context; use futures::future::join_all; use mlua::{ExternalError, ExternalResult, Function, IntoLuaMulti, Lua, MultiValue, Value, Variadic}; use tokio::sync::oneshot; @@ -20,9 +21,14 @@ impl Utils { lua.create_async_function(move |lua, args: MultiValue| async move { let Some(cur) = runtime!(lua)?.current_owned() else { - return Err("block spawned by `ya.sync()` must be called in a plugin").into_lua_err(); + return Err("`ya.sync()` block must be used within a plugin").into_lua_err(); }; - Sendable::list_to_values(&lua, Self::retrieve(&lua, cur, block, args).await?) + + Self::retrieve(&lua, &cur, block, args) + .await + .and_then(|data| Sendable::list_to_values(&lua, data)) + .with_context(|| format!("Failed to execute sync block-{block} in `{cur}` plugin")) + .into_lua_err() }) }) } else { @@ -81,7 +87,7 @@ impl Utils { async fn retrieve( lua: &Lua, - id: String, + id: &str, calls: usize, args: MultiValue, ) -> mlua::Result> { @@ -89,7 +95,7 @@ impl Utils { let (tx, rx) = oneshot::channel::>(); let callback: PluginCallback = { - let id = id.clone(); + let id = id.to_owned(); Box::new(move |lua, plugin| { let Some(block) = runtime!(lua)?.get_block(&id, calls) else { return Err("sync block not found".into_lua_err()); @@ -105,9 +111,8 @@ impl Utils { }) }; - AppProxy::plugin(PluginOpt::new_callback(id.clone(), callback)); + AppProxy::plugin(PluginOpt::new_callback(id.to_owned(), callback)); - rx.await - .map_err(|_| format!("Failed to execute sync block-{calls} in `{id}` plugin").into_lua_err()) + rx.await.into_lua_err() } } diff --git a/yazi-proxy/Cargo.toml b/yazi-proxy/Cargo.toml index 8137b3a5..85193e4c 100644 --- a/yazi-proxy/Cargo.toml +++ b/yazi-proxy/Cargo.toml @@ -8,10 +8,6 @@ description = "Yazi event proxy" homepage = "https://yazi-rs.github.io" repository = "https://github.com/sxyazi/yazi" -[features] -default = [ "vendored-lua" ] -vendored-lua = [ "mlua/vendored" ] - [dependencies] yazi-config = { path = "../yazi-config", version = "25.6.11" } yazi-macro = { path = "../yazi-macro", version = "25.6.11" } @@ -20,6 +16,4 @@ yazi-shared = { path = "../yazi-shared", version = "25.6.11" } # External dependencies anyhow = { workspace = true } -mlua = { workspace = true } -serde = { workspace = true } tokio = { workspace = true } diff --git a/yazi-proxy/src/app.rs b/yazi-proxy/src/app.rs index 0a0c7987..2f07a06b 100644 --- a/yazi-proxy/src/app.rs +++ b/yazi-proxy/src/app.rs @@ -1,29 +1,28 @@ use std::time::Duration; use tokio::sync::oneshot; -use yazi_macro::emit; +use yazi_macro::{emit, relay}; use yazi_parser::app::{NotifyLevel, NotifyOpt, PluginOpt, TasksProgress}; -use yazi_shared::event::Cmd; pub struct AppProxy; impl AppProxy { pub async fn stop() { let (tx, rx) = oneshot::channel::<()>(); - emit!(Call(Cmd::new("app:stop").with_any("tx", tx))); + emit!(Call(relay!(app:stop).with_any("tx", tx))); rx.await.ok(); } pub fn resume() { - emit!(Call(Cmd::new("app:resume"))); + emit!(Call(relay!(app:resume))); } pub fn notify(opt: NotifyOpt) { - emit!(Call(Cmd::new("app:notify").with_any("option", opt))); + emit!(Call(relay!(app:notify).with_any("option", opt))); } pub fn update_notify(dur: Duration) { - emit!(Call(Cmd::args("app:update_notify", [dur.as_secs_f64()]))); + emit!(Call(relay!(app:update_notify, [dur.as_secs_f64()]))); } pub fn notify_warn(title: &str, content: impl ToString) { @@ -45,14 +44,14 @@ impl AppProxy { } pub fn plugin(opt: PluginOpt) { - emit!(Call(Cmd::new("app:plugin").with_any("opt", opt))); + emit!(Call(relay!(app:plugin).with_any("opt", opt))); } pub fn plugin_do(opt: PluginOpt) { - emit!(Call(Cmd::new("app:plugin_do").with_any("opt", opt))); + emit!(Call(relay!(app:plugin_do).with_any("opt", opt))); } pub fn update_progress(progress: TasksProgress) { - emit!(Call(Cmd::new("app:update_progress").with_any("progress", progress))); + emit!(Call(relay!(app:update_progress).with_any("progress", progress))); } } diff --git a/yazi-proxy/src/cmp.rs b/yazi-proxy/src/cmp.rs index 3ca2ba6d..2597244e 100644 --- a/yazi-proxy/src/cmp.rs +++ b/yazi-proxy/src/cmp.rs @@ -1,15 +1,15 @@ -use yazi_macro::emit; +use yazi_macro::{emit, relay}; use yazi_parser::cmp::ShowOpt; -use yazi_shared::{Id, event::Cmd}; +use yazi_shared::Id; pub struct CmpProxy; impl CmpProxy { pub fn show(opt: ShowOpt) { - emit!(Call(Cmd::new("cmp:show").with_any("opt", opt))); + emit!(Call(relay!(cmp:show).with_any("opt", opt))); } pub fn trigger(word: &str, ticket: Id) { - emit!(Call(Cmd::args("cmp:trigger", [word]).with("ticket", ticket))); + emit!(Call(relay!(cmp:trigger, [word]).with("ticket", ticket))); } } diff --git a/yazi-proxy/src/confirm.rs b/yazi-proxy/src/confirm.rs index e8374e5d..bd9309bc 100644 --- a/yazi-proxy/src/confirm.rs +++ b/yazi-proxy/src/confirm.rs @@ -1,7 +1,6 @@ use tokio::sync::oneshot; use yazi_config::popup::ConfirmCfg; -use yazi_macro::emit; -use yazi_shared::event::Cmd; +use yazi_macro::{emit, relay}; pub struct ConfirmProxy; @@ -10,7 +9,7 @@ impl ConfirmProxy { pub fn show_rx(cfg: ConfirmCfg) -> oneshot::Receiver { let (tx, rx) = oneshot::channel(); - emit!(Call(Cmd::new("confirm:show").with_any("tx", tx).with_any("cfg", cfg))); + emit!(Call(relay!(confirm:show).with_any("tx", tx).with_any("cfg", cfg))); rx } } diff --git a/yazi-proxy/src/input.rs b/yazi-proxy/src/input.rs index c23c210e..e23702b9 100644 --- a/yazi-proxy/src/input.rs +++ b/yazi-proxy/src/input.rs @@ -1,14 +1,14 @@ use tokio::sync::mpsc; use yazi_config::popup::InputCfg; -use yazi_macro::emit; -use yazi_shared::{errors::InputError, event::Cmd}; +use yazi_macro::{emit, relay}; +use yazi_shared::errors::InputError; pub struct InputProxy; impl InputProxy { pub fn show(cfg: InputCfg) -> mpsc::UnboundedReceiver> { let (tx, rx) = mpsc::unbounded_channel(); - emit!(Call(Cmd::new("input:show").with_any("tx", tx).with_any("cfg", cfg))); + emit!(Call(relay!(input:show).with_any("tx", tx).with_any("cfg", cfg))); rx } } diff --git a/yazi-proxy/src/mgr.rs b/yazi-proxy/src/mgr.rs index 0e4ca16a..b4ab30b0 100644 --- a/yazi-proxy/src/mgr.rs +++ b/yazi-proxy/src/mgr.rs @@ -1,64 +1,64 @@ use std::borrow::Cow; -use yazi_macro::emit; +use yazi_macro::{emit, relay}; use yazi_parser::mgr::{FilterOpt, FindDoOpt, OpenDoOpt, SearchOpt, UpdatePeekedOpt, UpdateSpottedOpt}; -use yazi_shared::{SStr, event::Cmd, url::Url}; +use yazi_shared::{SStr, url::Url}; pub struct MgrProxy; impl MgrProxy { pub fn cd(target: &Url) { - emit!(Call(Cmd::args("mgr:cd", [target]).with("raw", true))); + emit!(Call(relay!(mgr:cd, [target]).with("raw", true))); } pub fn reveal(target: &Url) { - emit!(Call(Cmd::args("mgr:reveal", [target]).with("raw", true).with("no-dummy", true))); + emit!(Call(relay!(mgr:reveal, [target]).with("raw", true).with("no-dummy", true))); } pub fn arrow(step: impl Into) { - emit!(Call(Cmd::args("mgr:arrow", [step.into()]))); + emit!(Call(relay!(mgr:arrow, [step.into()]))); } pub fn open_do(opt: OpenDoOpt) { - emit!(Call(Cmd::new("mgr:open_do").with_any("option", opt))); + emit!(Call(relay!(mgr:open_do).with_any("option", opt))); } pub fn remove_do(targets: Vec, permanently: bool) { emit!(Call( - Cmd::new("mgr:remove_do").with("permanently", permanently).with_any("targets", targets) + relay!(mgr:remove_do).with("permanently", permanently).with_any("targets", targets) )); } pub fn find_do(opt: FindDoOpt) { - emit!(Call(Cmd::new("mgr:find_do").with_any("opt", opt))); + emit!(Call(relay!(mgr:find_do).with_any("opt", opt))); } pub fn filter_do(opt: FilterOpt) { - emit!(Call(Cmd::new("mgr:filter_do").with_any("opt", opt))); + emit!(Call(relay!(mgr:filter_do).with_any("opt", opt))); } pub fn search_do(opt: SearchOpt) { emit!(Call( // TODO: use second positional argument instead of `args` parameter - Cmd::args("mgr:search_do", [opt.subject]) + relay!(mgr:search_do, [opt.subject]) .with("via", Cow::Borrowed(opt.via.into_str())) .with("args", opt.args_raw.into_owned()) )); } pub fn update_peeked(opt: UpdatePeekedOpt) { - emit!(Call(Cmd::new("mgr:update_peeked").with_any("opt", opt))); + emit!(Call(relay!(mgr:update_peeked).with_any("opt", opt))); } pub fn update_spotted(opt: UpdateSpottedOpt) { - emit!(Call(Cmd::new("mgr:update_spotted").with_any("opt", opt))); + emit!(Call(relay!(mgr:update_spotted).with_any("opt", opt))); } pub fn update_tasks(url: &Url) { - emit!(Call(Cmd::new("mgr:update_tasks").with_any("urls", vec![url.clone()]))); + emit!(Call(relay!(mgr:update_tasks).with_any("urls", vec![url.clone()]))); } pub fn update_paged_by(page: usize, only_if: &Url) { - emit!(Call(Cmd::args("mgr:update_paged", [page]).with_any("only-if", only_if.clone()))); + emit!(Call(relay!(mgr:update_paged, [page]).with_any("only-if", only_if.clone()))); } } diff --git a/yazi-proxy/src/pick.rs b/yazi-proxy/src/pick.rs index c1885109..1293fc2b 100644 --- a/yazi-proxy/src/pick.rs +++ b/yazi-proxy/src/pick.rs @@ -1,14 +1,13 @@ use tokio::sync::oneshot; use yazi_config::popup::PickCfg; -use yazi_macro::emit; -use yazi_shared::event::Cmd; +use yazi_macro::{emit, relay}; pub struct PickProxy; impl PickProxy { pub async fn show(cfg: PickCfg) -> anyhow::Result { let (tx, rx) = oneshot::channel(); - emit!(Call(Cmd::new("pick:show").with_any("tx", tx).with_any("cfg", cfg))); + emit!(Call(relay!(pick:show).with_any("tx", tx).with_any("cfg", cfg))); rx.await? } } diff --git a/yazi-proxy/src/tasks.rs b/yazi-proxy/src/tasks.rs index 5acfe6f2..5ed5bf0e 100644 --- a/yazi-proxy/src/tasks.rs +++ b/yazi-proxy/src/tasks.rs @@ -2,24 +2,20 @@ use std::{borrow::Cow, ffi::OsString}; use tokio::sync::oneshot; use yazi_config::opener::OpenerRule; -use yazi_macro::emit; +use yazi_macro::{emit, relay}; use yazi_parser::{mgr::OpenWithOpt, tasks::ProcessExecOpt}; -use yazi_shared::{event::Cmd, url::Url}; +use yazi_shared::url::Url; pub struct TasksProxy; impl TasksProxy { pub fn open_with(opener: Cow<'static, OpenerRule>, cwd: Url, targets: Vec) { - emit!(Call(Cmd::new("tasks:open_with").with_any("option", OpenWithOpt { - opener, - cwd, - targets - }))); + emit!(Call(relay!(tasks:open_with).with_any("option", OpenWithOpt { opener, cwd, targets }))); } pub async fn process_exec(opener: Cow<'static, OpenerRule>, cwd: Url, args: Vec) { let (tx, rx) = oneshot::channel(); - emit!(Call(Cmd::new("tasks:process_exec").with_any("option", ProcessExecOpt { + emit!(Call(relay!(tasks:process_exec).with_any("option", ProcessExecOpt { cwd, opener, args, diff --git a/yazi-proxy/src/which.rs b/yazi-proxy/src/which.rs index cf5c89a1..843d92c2 100644 --- a/yazi-proxy/src/which.rs +++ b/yazi-proxy/src/which.rs @@ -1,11 +1,10 @@ -use yazi_macro::emit; +use yazi_macro::{emit, relay}; use yazi_parser::which::ShowOpt; -use yazi_shared::event::Cmd; pub struct WhichProxy; impl WhichProxy { pub fn show(opt: ShowOpt) { - emit!(Call(Cmd::new("which:show").with_any("opt", opt))); + emit!(Call(relay!(which:show).with_any("opt", opt))); } } diff --git a/yazi-scheduler/src/plugin/plugin.rs b/yazi-scheduler/src/plugin/plugin.rs index 8f4feeb1..89c8e26f 100644 --- a/yazi-scheduler/src/plugin/plugin.rs +++ b/yazi-scheduler/src/plugin/plugin.rs @@ -1,3 +1,5 @@ +use std::fmt::Display; + use anyhow::{Result, anyhow}; use tokio::sync::mpsc; use yazi_plugin::isolate; @@ -32,7 +34,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!("Failed to run the plugin:\n{e}"))?; + self.fail(task.id, e)?; return Ok(()); } @@ -54,8 +56,8 @@ impl Plugin { fn succ(&self, id: Id) -> Result<()> { Ok(self.prog.send(TaskProg::Succ(id))?) } #[inline] - fn fail(&self, id: Id, reason: String) -> Result<()> { - Ok(self.prog.send(TaskProg::Fail(id, reason))?) + fn fail(&self, id: Id, reason: impl Display) -> Result<()> { + Ok(self.prog.send(TaskProg::Fail(id, reason.to_string()))?) } #[inline] diff --git a/yazi-shared/Cargo.toml b/yazi-shared/Cargo.toml index b09a73a6..1ea6c36e 100644 --- a/yazi-shared/Cargo.toml +++ b/yazi-shared/Cargo.toml @@ -14,7 +14,6 @@ yazi-macro = { path = "../yazi-macro", version = "25.6.11" } # External dependencies anyhow = { workspace = true } -bitflags = { workspace = true } crossterm = { workspace = true } foldhash = { workspace = true } futures = { workspace = true } diff --git a/yazi-shared/src/event/cmd.rs b/yazi-shared/src/event/cmd.rs index 30262acd..db5587a1 100644 --- a/yazi-shared/src/event/cmd.rs +++ b/yazi-shared/src/event/cmd.rs @@ -1,34 +1,27 @@ use std::{any::Any, borrow::Cow, collections::HashMap, fmt::{self, Display}, mem, str::FromStr}; -use anyhow::{Result, bail}; +use anyhow::{Result, anyhow, bail}; use serde::{Deserialize, de}; use super::{Data, DataKey}; -use crate::{Id, Layer, SStr, url::Url}; +use crate::{Id, Layer, SStr, Source, url::Url}; #[derive(Debug, Default)] pub struct Cmd { - pub name: SStr, - pub args: HashMap, - pub layer: Layer, + pub name: SStr, + pub args: HashMap, + pub layer: Layer, + pub source: Source, } impl Cmd { - pub fn new(name: N) -> Self - where - N: Into, - { - Self::new_or(name, Default::default()) - .unwrap_or_else(|_| Self { name: "null".into(), ..Default::default() }) - } - - pub fn new_or(name: N, default: Layer) -> Result + pub fn new(name: N, source: Source, default: Option) -> Result where N: Into, { let cow: SStr = name.into(); let (layer, name) = match cow.find(':') { - None => (default, cow), + None => (default.ok_or_else(|| anyhow!("Cannot infer layer from command name: {cow}"))?, cow), Some(i) => (cow[..i].parse()?, match cow { Cow::Borrowed(s) => Cow::Borrowed(&s[i + 1..]), Cow::Owned(mut s) => { @@ -38,21 +31,31 @@ impl Cmd { }), }; - Ok(Self { name, args: Default::default(), layer }) + Ok(Self { name, args: Default::default(), layer, source }) } - pub fn args(name: N, args: I) -> Self + pub fn new_relay(name: N) -> Self + where + N: Into, + { + Self::new(name, Source::Relay, None).unwrap_or(Self::null()) + } + + pub fn new_relay_args(name: N, args: I) -> Self where N: Into, D: Into, I: IntoIterator, { - let mut me = Self::new(name); - me.args = + let mut cmd = Self::new(name, Source::Relay, None).unwrap_or(Self::null()); + cmd.args = args.into_iter().enumerate().map(|(i, a)| (DataKey::Integer(i as i64), a.into())).collect(); - me + cmd } + #[inline] + fn null() -> Self { Self { name: Cow::Borrowed("null"), ..Default::default() } } + #[inline] pub fn len(&self) -> usize { self.args.len() } @@ -207,7 +210,7 @@ impl FromStr for Cmd { bail!("command name cannot be empty"); } - let mut me = Self::new(mem::take(&mut words[0])); + let mut me = Self::new(mem::take(&mut words[0]), Default::default(), Some(Default::default()))?; me.args = Cmd::parse_args(words.into_iter().skip(1), last, true)?; Ok(me) } diff --git a/yazi-shared/src/source.rs b/yazi-shared/src/source.rs index 86853a58..c3d5707c 100644 --- a/yazi-shared/src/source.rs +++ b/yazi-shared/src/source.rs @@ -1,13 +1,21 @@ -use bitflags::bitflags; use serde::{Deserialize, Serialize}; -bitflags! { - #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] - pub struct Source: u8 { - const KEY = 0b00000001; - const EMIT = 0b00000010; +#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] +pub enum Source { + #[default] + Unknown, - const ACTOR = 0b00000100; - const PROXY = 0b00001000; - } + Key, + Ind, + + Emit, + EmitInd, + + Relay, + RelayInd, +} + +impl Source { + #[inline] + pub fn is_key(self) -> bool { self == Source::Key } } diff --git a/yazi-shared/src/url/url.rs b/yazi-shared/src/url/url.rs index 1e9bfcb8..a12cb1ff 100644 --- a/yazi-shared/src/url/url.rs +++ b/yazi-shared/src/url/url.rs @@ -130,8 +130,8 @@ impl From for Cow<'_, Url> { fn from(url: Url) -> Self { Cow::Owned(url) } } -impl From> for Url { - fn from(url: Cow<'static, Url>) -> Self { url.into_owned() } +impl From> for Url { + fn from(url: Cow<'_, Url>) -> Self { url.into_owned() } } impl Url { diff --git a/yazi-widgets/Cargo.toml b/yazi-widgets/Cargo.toml index 504a6328..5bc5fc64 100644 --- a/yazi-widgets/Cargo.toml +++ b/yazi-widgets/Cargo.toml @@ -27,7 +27,7 @@ tokio = { workspace = true } unicode-width = { workspace = true } [target."cfg(windows)".dependencies] -clipboard-win = "5.4.0" +clipboard-win = "5.4.1" [target.'cfg(target_os = "macos")'.dependencies] crossterm = { workspace = true, features = [ "use-dev-tty", "libc" ] } diff --git a/yazi-widgets/src/input/commands/forward.rs b/yazi-widgets/src/input/commands/forward.rs index 2505aeb6..2e5f5b83 100644 --- a/yazi-widgets/src/input/commands/forward.rs +++ b/yazi-widgets/src/input/commands/forward.rs @@ -1,6 +1,6 @@ use anyhow::Result; use yazi_macro::act; -use yazi_parser::mgr::ForwardOpt; +use yazi_parser::input::ForwardOpt; use yazi_shared::{CharKind, event::Data}; use crate::input::{Input, op::InputOp};