refactor: move Lua bindings into their own yazi-binding crate (#3636)

This commit is contained in:
三咲雅 misaki masa 2026-01-29 23:12:29 +08:00 committed by GitHub
parent eaeda8b4fa
commit 1ea0ea072c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
90 changed files with 334 additions and 273 deletions

View file

@ -1,5 +1,8 @@
blank_issues_enabled: false blank_issues_enabled: false
contact_links: contact_links:
- name: 🚧 Build Issues
url: https://github.com/sxyazi/yazi/discussions/new?category=3-build-issues
about: If you have issues building Yazi from source code
- name: 📝 Documentation Improvement - name: 📝 Documentation Improvement
url: https://github.com/yazi-rs/yazi-rs.github.io url: https://github.com/yazi-rs/yazi-rs.github.io
about: If you'd like to help improve the documentation about: If you'd like to help improve the documentation

43
Cargo.lock generated
View file

@ -143,7 +143,7 @@ version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [ dependencies = [
"windows-sys 0.60.2", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -154,7 +154,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [ dependencies = [
"anstyle", "anstyle",
"once_cell_polyfill", "once_cell_polyfill",
"windows-sys 0.60.2", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -1267,7 +1267,7 @@ dependencies = [
"libc", "libc",
"option-ext", "option-ext",
"redox_users", "redox_users",
"windows-sys 0.59.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -1419,7 +1419,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys 0.52.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -1914,9 +1914,9 @@ dependencies = [
[[package]] [[package]]
name = "iana-time-zone" name = "iana-time-zone"
version = "0.1.64" version = "0.1.65"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
dependencies = [ dependencies = [
"android_system_properties", "android_system_properties",
"core-foundation-sys", "core-foundation-sys",
@ -1962,7 +1962,7 @@ dependencies = [
"rgb", "rgb",
"tiff", "tiff",
"zune-core 0.5.1", "zune-core 0.5.1",
"zune-jpeg 0.5.11", "zune-jpeg 0.5.12",
] ]
[[package]] [[package]]
@ -2599,7 +2599,7 @@ version = "0.50.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
dependencies = [ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -3832,7 +3832,7 @@ dependencies = [
"errno", "errno",
"libc", "libc",
"linux-raw-sys 0.11.0", "linux-raw-sys 0.11.0",
"windows-sys 0.52.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -5162,7 +5162,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -5596,6 +5596,7 @@ name = "yazi-binding"
version = "26.1.22" version = "26.1.22"
dependencies = [ dependencies = [
"ansi-to-tui", "ansi-to-tui",
"crossterm 0.29.0",
"futures", "futures",
"hashbrown 0.16.1", "hashbrown 0.16.1",
"mlua", "mlua",
@ -5603,6 +5604,7 @@ dependencies = [
"ratatui", "ratatui",
"serde_json", "serde_json",
"tokio", "tokio",
"tokio-stream",
"tracing", "tracing",
"unicode-width", "unicode-width",
"yazi-adapter", "yazi-adapter",
@ -5611,6 +5613,8 @@ dependencies = [
"yazi-fs", "yazi-fs",
"yazi-macro", "yazi-macro",
"yazi-shared", "yazi-shared",
"yazi-vfs",
"yazi-widgets",
] ]
[[package]] [[package]]
@ -5751,6 +5755,7 @@ dependencies = [
"yazi-macro", "yazi-macro",
"yazi-parser", "yazi-parser",
"yazi-shared", "yazi-shared",
"yazi-widgets",
] ]
[[package]] [[package]]
@ -5881,6 +5886,7 @@ dependencies = [
"yazi-macro", "yazi-macro",
"yazi-shared", "yazi-shared",
"yazi-vfs", "yazi-vfs",
"yazi-widgets",
] ]
[[package]] [[package]]
@ -5938,6 +5944,7 @@ dependencies = [
"yazi-macro", "yazi-macro",
"yazi-parser", "yazi-parser",
"yazi-shared", "yazi-shared",
"yazi-widgets",
] ]
[[package]] [[package]]
@ -6092,32 +6099,32 @@ dependencies = [
"clipboard-win", "clipboard-win",
"crossterm 0.29.0", "crossterm 0.29.0",
"futures", "futures",
"mlua",
"parking_lot", "parking_lot",
"ratatui", "ratatui",
"tokio", "tokio",
"unicode-width", "unicode-width",
"yazi-binding", "yazi-adapter",
"yazi-config", "yazi-config",
"yazi-macro", "yazi-macro",
"yazi-parser",
"yazi-shared", "yazi-shared",
"yazi-tty", "yazi-tty",
] ]
[[package]] [[package]]
name = "zerocopy" name = "zerocopy"
version = "0.8.34" version = "0.8.35"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71ddd76bcebeed25db614f82bf31a9f4222d3fbba300e6fb6c00afa26cbd4d9d" checksum = "fdea86ddd5568519879b8187e1cf04e24fce28f7fe046ceecbce472ff19a2572"
dependencies = [ dependencies = [
"zerocopy-derive", "zerocopy-derive",
] ]
[[package]] [[package]]
name = "zerocopy-derive" name = "zerocopy-derive"
version = "0.8.34" version = "0.8.35"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8187381b52e32220d50b255276aa16a084ec0a9017a0ca2152a1f55c539758d" checksum = "0c15e1b46eff7c6c91195752e0eeed8ef040e391cdece7c25376957d5f15df22"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -6182,9 +6189,9 @@ dependencies = [
[[package]] [[package]]
name = "zune-jpeg" name = "zune-jpeg"
version = "0.5.11" version = "0.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2959ca473aae96a14ecedf501d20b3608d2825ba280d5adb57d651721885b0c2" checksum = "410e9ecef634c709e3831c2cfdb8d9c32164fae1c67496d5b68fff728eec37fe"
dependencies = [ dependencies = [
"zune-core 0.5.1", "zune-core 0.5.1",
] ]

View file

@ -19,7 +19,7 @@ impl Actor for Mouse {
const NAME: &str = "mouse"; const NAME: &str = "mouse";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
let event = yazi_plugin::bindings::MouseEvent::from(opt.event); let event = yazi_binding::MouseEvent::from(opt.event);
let Some(size) = cx.term.as_ref().and_then(|t| t.size().ok()) else { succ!() }; let Some(size) = cx.term.as_ref().and_then(|t| t.size().ok()) else { succ!() };
let result = Lives::scope(&cx.core, move || { let result = Lives::scope(&cx.core, move || {

View file

@ -2,8 +2,9 @@ use std::mem;
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::{cmp::CloseOpt, input::CompleteOpt}; use yazi_parser::cmp::CloseOpt;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use yazi_widgets::input::parser::CompleteOpt;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};
@ -17,7 +18,7 @@ impl Actor for Close {
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> { fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
let cmp = &mut cx.core.cmp; let cmp = &mut cx.core.cmp;
if let Some(item) = cmp.selected().filter(|_| opt.submit).cloned() { if let Some(item) = cmp.selected().filter(|_| opt.submit).cloned() {
return act!(input:complete, cx, CompleteOpt { item, ticket: cmp.ticket }); return act!(input:complete, cx, CompleteOpt { name: item.name, is_dir: item.is_dir, ticket: cmp.ticket });
} }
cmp.caches.clear(); cmp.caches.clear();

View file

@ -1,7 +1,8 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::input::CloseOpt; use yazi_parser::input::CloseOpt;
use yazi_shared::{data::Data, errors::InputError}; use yazi_shared::data::Data;
use yazi_widgets::input::InputError;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};

View file

@ -1,7 +1,7 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, succ}; use yazi_macro::{act, succ};
use yazi_parser::input::CompleteOpt;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use yazi_widgets::input::parser::CompleteOpt;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};

View file

@ -4,8 +4,8 @@ use anyhow::Result;
use yazi_config::YAZI; use yazi_config::YAZI;
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::input::ShowOpt; use yazi_parser::input::ShowOpt;
use yazi_shared::{data::Data, errors::InputError}; use yazi_shared::data::Data;
use yazi_widgets::input::InputCallback; use yazi_widgets::input::{InputCallback, InputError};
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};

View file

@ -58,7 +58,7 @@ impl UserData for Core {
b"tasks" => reuse!(tasks, super::Tasks::make(&me.tasks)), b"tasks" => reuse!(tasks, super::Tasks::make(&me.tasks)),
b"yanked" => reuse!(yanked, super::Yanked::make(&me.mgr.yanked)), b"yanked" => reuse!(yanked, super::Yanked::make(&me.mgr.yanked)),
b"layer" => { b"layer" => {
reuse!(layer, Ok::<_, mlua::Error>(yazi_plugin::bindings::Layer::from(me.layer()))) reuse!(layer, Ok::<_, mlua::Error>(yazi_binding::Layer::from(me.layer())))
} }
b"which" => reuse!(which, super::Which::make(&me.which)), b"which" => reuse!(which, super::Which::make(&me.which)),
_ => Value::Nil, _ => Value::Nil,

View file

@ -1,9 +1,8 @@
use std::{ops::Deref, ptr}; use std::{ops::Deref, ptr};
use mlua::{AnyUserData, IntoLua, UserData, UserDataFields, UserDataMethods, Value}; use mlua::{AnyUserData, IntoLua, UserData, UserDataFields, UserDataMethods, Value};
use yazi_binding::{Style, cached_field}; use yazi_binding::{Range, Style, cached_field};
use yazi_config::THEME; use yazi_config::THEME;
use yazi_plugin::bindings::Range;
use yazi_shared::{path::AsPath, url::UrlLike}; use yazi_shared::{path::AsPath, url::UrlLike};
use super::Lives; use super::Lives;

View file

@ -9,8 +9,9 @@ use yazi_fs::{File, FilesOp, path::{clean_url, expand_url}};
use yazi_macro::{act, err, render, succ}; use yazi_macro::{act, err, render, succ};
use yazi_parser::mgr::CdOpt; use yazi_parser::mgr::CdOpt;
use yazi_proxy::{CmpProxy, InputProxy, MgrProxy}; use yazi_proxy::{CmpProxy, InputProxy, MgrProxy};
use yazi_shared::{Debounce, data::Data, errors::InputError, url::{AsUrl, UrlBuf, UrlLike}}; use yazi_shared::{Debounce, data::Data, url::{AsUrl, UrlBuf, UrlLike}};
use yazi_vfs::{VfsFile, provider}; use yazi_vfs::{VfsFile, provider};
use yazi_widgets::input::InputError;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};

View file

@ -7,7 +7,8 @@ use yazi_config::popup::InputCfg;
use yazi_macro::succ; use yazi_macro::succ;
use yazi_parser::mgr::FilterOpt; use yazi_parser::mgr::FilterOpt;
use yazi_proxy::{InputProxy, MgrProxy}; use yazi_proxy::{InputProxy, MgrProxy};
use yazi_shared::{Debounce, data::Data, errors::InputError}; use yazi_shared::{Debounce, data::Data};
use yazi_widgets::input::InputError;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};

View file

@ -7,7 +7,8 @@ use yazi_config::popup::InputCfg;
use yazi_macro::succ; use yazi_macro::succ;
use yazi_parser::mgr::{FindDoOpt, FindOpt}; use yazi_parser::mgr::{FindDoOpt, FindOpt};
use yazi_proxy::{InputProxy, MgrProxy}; use yazi_proxy::{InputProxy, MgrProxy};
use yazi_shared::{Debounce, data::Data, errors::InputError}; use yazi_shared::{Debounce, data::Data};
use yazi_widgets::input::InputError;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};

View file

@ -22,9 +22,12 @@ yazi-config = { path = "../yazi-config", version = "26.1.22" }
yazi-fs = { path = "../yazi-fs", version = "26.1.22" } yazi-fs = { path = "../yazi-fs", version = "26.1.22" }
yazi-macro = { path = "../yazi-macro", version = "26.1.22" } yazi-macro = { path = "../yazi-macro", version = "26.1.22" }
yazi-shared = { path = "../yazi-shared", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" }
yazi-vfs = { path = "../yazi-vfs", version = "26.1.22" }
yazi-widgets = { path = "../yazi-widgets", version = "26.1.22" }
# External dependencies # External dependencies
ansi-to-tui = { workspace = true } ansi-to-tui = { workspace = true }
crossterm = { workspace = true }
futures = { workspace = true } futures = { workspace = true }
hashbrown = { workspace = true } hashbrown = { workspace = true }
mlua = { workspace = true } mlua = { workspace = true }
@ -32,5 +35,9 @@ paste = { workspace = true }
ratatui = { workspace = true } ratatui = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }
tokio-stream = { workspace = true }
tracing = { workspace = true } tracing = { workspace = true }
unicode-width = { workspace = true } unicode-width = { workspace = true }
[target.'cfg(target_os = "macos")'.dependencies]
crossterm = { workspace = true, features = [ "use-dev-tty", "libc" ] }

View file

@ -1,5 +1,6 @@
use mlua::{IntoLuaMulti, UserData, UserDataMethods, Value}; use mlua::{IntoLuaMulti, UserData, UserDataMethods, Value};
use yazi_binding::Error;
use crate::Error;
pub enum SizeCalculator { pub enum SizeCalculator {
Local(yazi_fs::provider::local::SizeCalculator), Local(yazi_fs::provider::local::SizeCalculator),

View file

@ -1,5 +1,6 @@
use mlua::{ExternalError, IntoLuaMulti, UserData, Value}; use mlua::{ExternalError, IntoLuaMulti, UserData, Value};
use yazi_binding::Error;
use crate::Error;
pub struct MpscTx(pub tokio::sync::mpsc::Sender<Value>); pub struct MpscTx(pub tokio::sync::mpsc::Sender<Value>);
pub struct MpscRx(pub tokio::sync::mpsc::Receiver<Value>); pub struct MpscRx(pub tokio::sync::mpsc::Receiver<Value>);

View file

@ -1,12 +1,8 @@
use std::sync::atomic::{AtomicBool, Ordering};
use mlua::{IntoLua, Lua, MetaMethod, Table, UserData, Value}; use mlua::{IntoLua, Lua, MetaMethod, Table, UserData, Value};
use yazi_adapter::ADAPTOR; use ratatui::widgets::Widget;
use super::Area; use super::Area;
pub static COLLISION: AtomicBool = AtomicBool::new(false);
#[derive(Clone, Copy, Debug, Default)] #[derive(Clone, Copy, Debug, Default)]
pub struct Clear { pub struct Clear {
pub area: Area, pub area: Area,
@ -23,28 +19,7 @@ impl Clear {
} }
pub(super) fn render(self, rect: ratatui::layout::Rect, buf: &mut ratatui::buffer::Buffer) { pub(super) fn render(self, rect: ratatui::layout::Rect, buf: &mut ratatui::buffer::Buffer) {
<Self as ratatui::widgets::Widget>::render(Default::default(), rect, buf); yazi_widgets::Clear.render(rect, buf);
}
}
impl ratatui::widgets::Widget for Clear {
fn render(self, area: ratatui::layout::Rect, buf: &mut ratatui::prelude::Buffer)
where
Self: Sized,
{
ratatui::widgets::Clear.render(area, buf);
let Some(r) = ADAPTOR.get().shown_load().and_then(|r| overlap(area, r)) else {
return;
};
ADAPTOR.get().image_erase(r).ok();
COLLISION.store(true, Ordering::Relaxed);
for y in r.top()..r.bottom() {
for x in r.left()..r.right() {
buf[(x, y)].set_skip(true);
}
}
} }
} }
@ -53,19 +28,3 @@ impl UserData for Clear {
crate::impl_area_method!(methods); crate::impl_area_method!(methods);
} }
} }
const fn is_overlapping(a: ratatui::layout::Rect, b: ratatui::layout::Rect) -> bool {
a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y
}
fn overlap(a: ratatui::layout::Rect, b: ratatui::layout::Rect) -> Option<ratatui::layout::Rect> {
if !is_overlapping(a, b) {
return None;
}
let x = a.x.max(b.x);
let y = a.y.max(b.y);
let width = (a.x + a.width).min(b.x + b.width) - x;
let height = (a.y + a.height).min(b.y + b.height) - y;
Some(ratatui::layout::Rect { x, y, width, height })
}

View file

@ -3,7 +3,7 @@ use std::pin::Pin;
use mlua::{UserData, prelude::LuaUserDataMethods}; use mlua::{UserData, prelude::LuaUserDataMethods};
use tokio::pin; use tokio::pin;
use tokio_stream::StreamExt; use tokio_stream::StreamExt;
use yazi_shared::errors::InputError; use yazi_widgets::input::InputError;
pub struct InputRx<T: StreamExt<Item = Result<String, InputError>>> { pub struct InputRx<T: StreamExt<Item = Result<String, InputError>>> {
inner: T, inner: T,

View file

@ -2,4 +2,4 @@ mod macros;
yazi_macro::mod_pub!(elements); yazi_macro::mod_pub!(elements);
yazi_macro::mod_flat!(cha chord_cow color composer error file handle icon id iter path permit runtime scheme stage style url utils); yazi_macro::mod_flat!(calculator cha chan chord_cow color composer error file handle icon id image input iter layer mouse path permit range runtime scheme stage style url utils);

View file

@ -2,7 +2,8 @@ use std::{ops::{Deref, DerefMut}, rc::Rc};
use tokio::sync::mpsc::UnboundedSender; use tokio::sync::mpsc::UnboundedSender;
use yazi_config::popup::Position; use yazi_config::popup::Position;
use yazi_shared::{Ids, errors::InputError}; use yazi_shared::Ids;
use yazi_widgets::input::InputError;
#[derive(Default)] #[derive(Default)]
pub struct Input { pub struct Input {

View file

@ -4,10 +4,9 @@ use yazi_config::{LAYOUT, YAZI};
use yazi_dds::Pubsub; use yazi_dds::Pubsub;
use yazi_fs::{File, Files, FilesOp, FolderStage, cha::Cha}; use yazi_fs::{File, Files, FilesOp, FolderStage, cha::Cha};
use yazi_macro::err; use yazi_macro::err;
use yazi_parser::Step;
use yazi_proxy::MgrProxy; use yazi_proxy::MgrProxy;
use yazi_shared::{Id, path::{AsPath, PathBufDyn, PathDyn}, url::UrlBuf}; use yazi_shared::{Id, path::{AsPath, PathBufDyn, PathDyn}, url::UrlBuf};
use yazi_widgets::Scrollable; use yazi_widgets::{Scrollable, Step};
pub struct Folder { pub struct Folder {
pub url: UrlBuf, pub url: UrlBuf,

View file

@ -22,6 +22,7 @@ yazi-fs = { path = "../yazi-fs", version = "26.1.22" }
yazi-macro = { path = "../yazi-macro", version = "26.1.22" } yazi-macro = { path = "../yazi-macro", version = "26.1.22" }
yazi-parser = { path = "../yazi-parser", version = "26.1.22" } yazi-parser = { path = "../yazi-parser", version = "26.1.22" }
yazi-shared = { path = "../yazi-shared", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" }
yazi-widgets = { path = "../yazi-widgets", version = "26.1.22" }
# External dependencies # External dependencies
anyhow = { workspace = true } anyhow = { workspace = true }

View file

@ -15,7 +15,7 @@ macro_rules! spark {
#[macro_export] #[macro_export]
macro_rules! try_from_spark { macro_rules! try_from_spark {
($opt:ty, $($($layer:ident)? : $name:ident),+) => { ($opt:ty, $($($layer:ident)? : $name:ident),+) => {
impl<'a> std::convert::TryFrom<$crate::spark::Spark<'a>> for paste::paste! { yazi_parser::$opt } { impl<'a> std::convert::TryFrom<$crate::spark::Spark<'a>> for $opt {
type Error = (); type Error = ();
fn try_from(value: $crate::spark::Spark<'a>) -> Result<Self, Self::Error> { fn try_from(value: $crate::spark::Spark<'a>) -> Result<Self, Self::Error> {

View file

@ -108,17 +108,17 @@ pub enum Spark<'a> {
HelpToggle(yazi_parser::help::ToggleOpt), HelpToggle(yazi_parser::help::ToggleOpt),
// Input // Input
InputBackspace(yazi_parser::input::BackspaceOpt), InputBackspace(yazi_widgets::input::parser::BackspaceOpt),
InputBackward(yazi_parser::input::BackwardOpt), InputBackward(yazi_widgets::input::parser::BackwardOpt),
InputClose(yazi_parser::input::CloseOpt), InputClose(yazi_parser::input::CloseOpt),
InputComplete(yazi_parser::input::CompleteOpt), InputComplete(yazi_widgets::input::parser::CompleteOpt),
InputDelete(yazi_parser::input::DeleteOpt), InputDelete(yazi_widgets::input::parser::DeleteOpt),
InputEscape(yazi_parser::VoidOpt), InputEscape(yazi_parser::VoidOpt),
InputForward(yazi_parser::input::ForwardOpt), InputForward(yazi_widgets::input::parser::ForwardOpt),
InputInsert(yazi_parser::input::InsertOpt), InputInsert(yazi_widgets::input::parser::InsertOpt),
InputKill(yazi_parser::input::KillOpt), InputKill(yazi_widgets::input::parser::KillOpt),
InputMove(yazi_parser::input::MoveOpt), InputMove(yazi_widgets::input::parser::MoveOpt),
InputPaste(yazi_parser::input::PasteOpt), InputPaste(yazi_widgets::input::parser::PasteOpt),
InputShow(yazi_parser::input::ShowOpt), InputShow(yazi_parser::input::ShowOpt),
// Notify // Notify
@ -323,7 +323,7 @@ impl<'a> IntoLua for Spark<'a> {
} }
try_from_spark!( try_from_spark!(
VoidOpt, yazi_parser::VoidOpt,
app:bootstrap, app:bootstrap,
app:focus, app:focus,
mgr:back, mgr:back,
@ -345,81 +345,81 @@ try_from_spark!(
); );
// App // App
try_from_spark!(ArrowOpt, mgr:arrow, mgr:tab_swap); try_from_spark!(yazi_parser::ArrowOpt, mgr:arrow, mgr:tab_swap);
try_from_spark!(app::DeprecateOpt, app:deprecate); try_from_spark!(yazi_parser::app::DeprecateOpt, app:deprecate);
try_from_spark!(app::MouseOpt, app:mouse); try_from_spark!(yazi_parser::app::MouseOpt, app:mouse);
try_from_spark!(app::PluginOpt, app:plugin, app:plugin_do); try_from_spark!(yazi_parser::app::PluginOpt, app:plugin, app:plugin_do);
try_from_spark!(app::QuitOpt, app:quit, mgr:quit); try_from_spark!(yazi_parser::app::QuitOpt, app:quit, mgr:quit);
try_from_spark!(app::ReflowOpt, app:reflow, app:resize); try_from_spark!(yazi_parser::app::ReflowOpt, app:reflow, app:resize);
try_from_spark!(app::ResumeOpt, app:resume); try_from_spark!(yazi_parser::app::ResumeOpt, app:resume);
try_from_spark!(app::StopOpt, app:stop); try_from_spark!(yazi_parser::app::StopOpt, app:stop);
try_from_spark!(app::UpdateProgressOpt, app:update_progress); try_from_spark!(yazi_parser::app::UpdateProgressOpt, app:update_progress);
try_from_spark!(cmp::CloseOpt, cmp:close); try_from_spark!(yazi_parser::cmp::CloseOpt, cmp:close);
try_from_spark!(cmp::ShowOpt, cmp:show); try_from_spark!(yazi_parser::cmp::ShowOpt, cmp:show);
try_from_spark!(cmp::TriggerOpt, cmp:trigger); try_from_spark!(yazi_parser::cmp::TriggerOpt, cmp:trigger);
try_from_spark!(confirm::CloseOpt, confirm:close); try_from_spark!(yazi_parser::confirm::CloseOpt, confirm:close);
try_from_spark!(confirm::ShowOpt, confirm:show); try_from_spark!(yazi_parser::confirm::ShowOpt, confirm:show);
try_from_spark!(help::ToggleOpt, help:toggle); try_from_spark!(yazi_parser::help::ToggleOpt, help:toggle);
try_from_spark!(input::BackspaceOpt, input:backspace); try_from_spark!(yazi_parser::input::CloseOpt, input:close);
try_from_spark!(input::BackwardOpt, input:backward); try_from_spark!(yazi_parser::input::ShowOpt, input:show);
try_from_spark!(input::CloseOpt, input:close); try_from_spark!(yazi_parser::mgr::CdOpt, mgr:cd);
try_from_spark!(input::CompleteOpt, input:complete); try_from_spark!(yazi_parser::mgr::CloseOpt, mgr:close);
try_from_spark!(input::DeleteOpt, input:delete); try_from_spark!(yazi_parser::mgr::CopyOpt, mgr:copy);
try_from_spark!(input::ForwardOpt, input:forward); try_from_spark!(yazi_parser::mgr::CreateOpt, mgr:create);
try_from_spark!(input::InsertOpt, input:insert); try_from_spark!(yazi_parser::mgr::DisplaceDoOpt, mgr:displace_do);
try_from_spark!(input::KillOpt, input:kill); try_from_spark!(yazi_parser::mgr::DownloadOpt, mgr:download);
try_from_spark!(input::MoveOpt, input:move); try_from_spark!(yazi_parser::mgr::EscapeOpt, mgr:escape);
try_from_spark!(input::PasteOpt, input:paste); try_from_spark!(yazi_parser::mgr::FilterOpt, mgr:filter, mgr:filter_do);
try_from_spark!(input::ShowOpt, input:show); try_from_spark!(yazi_parser::mgr::FindArrowOpt, mgr:find_arrow);
try_from_spark!(mgr::CdOpt, mgr:cd); try_from_spark!(yazi_parser::mgr::FindDoOpt, mgr:find_do);
try_from_spark!(mgr::CloseOpt, mgr:close); try_from_spark!(yazi_parser::mgr::FindOpt, mgr:find);
try_from_spark!(mgr::CopyOpt, mgr:copy); try_from_spark!(yazi_parser::mgr::HardlinkOpt, mgr:hardlink);
try_from_spark!(mgr::CreateOpt, mgr:create); try_from_spark!(yazi_parser::mgr::HiddenOpt, mgr:hidden);
try_from_spark!(mgr::DisplaceDoOpt, mgr:displace_do); try_from_spark!(yazi_parser::mgr::HoverOpt, mgr:hover);
try_from_spark!(mgr::DownloadOpt, mgr:download); try_from_spark!(yazi_parser::mgr::LinemodeOpt, mgr:linemode);
try_from_spark!(mgr::EscapeOpt, mgr:escape); try_from_spark!(yazi_parser::mgr::LinkOpt, mgr:link);
try_from_spark!(mgr::FilterOpt, mgr:filter, mgr:filter_do); try_from_spark!(yazi_parser::mgr::OpenDoOpt, mgr:open_do);
try_from_spark!(mgr::FindArrowOpt, mgr:find_arrow); try_from_spark!(yazi_parser::mgr::OpenOpt, mgr:open);
try_from_spark!(mgr::FindDoOpt, mgr:find_do); try_from_spark!(yazi_parser::mgr::PasteOpt, mgr:paste);
try_from_spark!(mgr::FindOpt, mgr:find); try_from_spark!(yazi_parser::mgr::PeekOpt, mgr:peek);
try_from_spark!(mgr::HardlinkOpt, mgr:hardlink); try_from_spark!(yazi_parser::mgr::RemoveOpt, mgr:remove, mgr:remove_do);
try_from_spark!(mgr::HiddenOpt, mgr:hidden); try_from_spark!(yazi_parser::mgr::RenameOpt, mgr:rename);
try_from_spark!(mgr::HoverOpt, mgr:hover); try_from_spark!(yazi_parser::mgr::RevealOpt, mgr:reveal);
try_from_spark!(mgr::LinemodeOpt, mgr:linemode); try_from_spark!(yazi_parser::mgr::SearchOpt, mgr:search, mgr:search_do);
try_from_spark!(mgr::LinkOpt, mgr:link); try_from_spark!(yazi_parser::mgr::SeekOpt, mgr:seek);
try_from_spark!(mgr::OpenDoOpt, mgr:open_do); try_from_spark!(yazi_parser::mgr::ShellOpt, mgr:shell);
try_from_spark!(mgr::OpenOpt, mgr:open); try_from_spark!(yazi_parser::mgr::SortOpt, mgr:sort);
try_from_spark!(mgr::PasteOpt, mgr:paste); try_from_spark!(yazi_parser::mgr::SpotOpt, mgr:spot);
try_from_spark!(mgr::PeekOpt, mgr:peek); try_from_spark!(yazi_parser::mgr::StashOpt, mgr:stash);
try_from_spark!(mgr::RemoveOpt, mgr:remove, mgr:remove_do); try_from_spark!(yazi_parser::mgr::TabCloseOpt, mgr:tab_close);
try_from_spark!(mgr::RenameOpt, mgr:rename); try_from_spark!(yazi_parser::mgr::TabCreateOpt, mgr:tab_create);
try_from_spark!(mgr::RevealOpt, mgr:reveal); try_from_spark!(yazi_parser::mgr::TabSwitchOpt, mgr:tab_switch);
try_from_spark!(mgr::SearchOpt, mgr:search, mgr:search_do); try_from_spark!(yazi_parser::mgr::ToggleAllOpt, mgr:toggle_all);
try_from_spark!(mgr::SeekOpt, mgr:seek); try_from_spark!(yazi_parser::mgr::ToggleOpt, mgr:toggle);
try_from_spark!(mgr::ShellOpt, mgr:shell); try_from_spark!(yazi_parser::mgr::UpdateFilesOpt, mgr:update_files);
try_from_spark!(mgr::SortOpt, mgr:sort); try_from_spark!(yazi_parser::mgr::UpdateMimesOpt, mgr:update_mimes);
try_from_spark!(mgr::SpotOpt, mgr:spot); try_from_spark!(yazi_parser::mgr::UpdatePagedOpt, mgr:update_paged);
try_from_spark!(mgr::StashOpt, mgr:stash); try_from_spark!(yazi_parser::mgr::UpdatePeekedOpt, mgr:update_peeked);
try_from_spark!(mgr::TabCloseOpt, mgr:tab_close); try_from_spark!(yazi_parser::mgr::UpdateSpottedOpt, mgr:update_spotted);
try_from_spark!(mgr::TabCreateOpt, mgr:tab_create); try_from_spark!(yazi_parser::mgr::UpdateYankedOpt<'a>, mgr:update_yanked);
try_from_spark!(mgr::TabSwitchOpt, mgr:tab_switch); try_from_spark!(yazi_parser::mgr::UploadOpt, mgr:upload);
try_from_spark!(mgr::ToggleAllOpt, mgr:toggle_all); try_from_spark!(yazi_parser::mgr::VisualModeOpt, mgr:visual_mode);
try_from_spark!(mgr::ToggleOpt, mgr:toggle); try_from_spark!(yazi_parser::mgr::YankOpt, mgr:yank);
try_from_spark!(mgr::UpdateFilesOpt, mgr:update_files); try_from_spark!(yazi_parser::notify::PushOpt, notify:push);
try_from_spark!(mgr::UpdateMimesOpt, mgr:update_mimes); try_from_spark!(yazi_parser::notify::TickOpt, notify:tick);
try_from_spark!(mgr::UpdatePagedOpt, mgr:update_paged); try_from_spark!(yazi_parser::pick::CloseOpt, pick:close);
try_from_spark!(mgr::UpdatePeekedOpt, mgr:update_peeked); try_from_spark!(yazi_parser::pick::ShowOpt, pick:show);
try_from_spark!(mgr::UpdateSpottedOpt, mgr:update_spotted); try_from_spark!(yazi_parser::spot::CopyOpt, spot:copy);
try_from_spark!(mgr::UpdateYankedOpt<'a>, mgr:update_yanked); try_from_spark!(yazi_parser::tasks::ProcessOpenOpt, tasks:process_open);
try_from_spark!(mgr::UploadOpt, mgr:upload); try_from_spark!(yazi_parser::tasks::UpdateSucceedOpt, tasks:update_succeed);
try_from_spark!(mgr::VisualModeOpt, mgr:visual_mode); try_from_spark!(yazi_parser::which::ActivateOpt, which:activate);
try_from_spark!(mgr::YankOpt, mgr:yank); try_from_spark!(yazi_parser::which::CallbackOpt, which:callback);
try_from_spark!(notify::PushOpt, notify:push); try_from_spark!(yazi_widgets::input::parser::BackspaceOpt, input:backspace);
try_from_spark!(notify::TickOpt, notify:tick); try_from_spark!(yazi_widgets::input::parser::BackwardOpt, input:backward);
try_from_spark!(pick::CloseOpt, pick:close); try_from_spark!(yazi_widgets::input::parser::CompleteOpt, input:complete);
try_from_spark!(pick::ShowOpt, pick:show); try_from_spark!(yazi_widgets::input::parser::DeleteOpt, input:delete);
try_from_spark!(spot::CopyOpt, spot:copy); try_from_spark!(yazi_widgets::input::parser::ForwardOpt, input:forward);
try_from_spark!(tasks::ProcessOpenOpt, tasks:process_open); try_from_spark!(yazi_widgets::input::parser::InsertOpt, input:insert);
try_from_spark!(tasks::UpdateSucceedOpt, tasks:update_succeed); try_from_spark!(yazi_widgets::input::parser::KillOpt, input:kill);
try_from_spark!(which::ActivateOpt, which:activate); try_from_spark!(yazi_widgets::input::parser::MoveOpt, input:move);
try_from_spark!(which::CallbackOpt, which:callback); try_from_spark!(yazi_widgets::input::parser::PasteOpt, input:paste);

View file

@ -4,10 +4,10 @@ use anyhow::Result;
use crossterm::{cursor::{MoveTo, SetCursorStyle, Show}, execute, queue, terminal::{BeginSynchronizedUpdate, EndSynchronizedUpdate}}; use crossterm::{cursor::{MoveTo, SetCursorStyle, Show}, execute, queue, terminal::{BeginSynchronizedUpdate, EndSynchronizedUpdate}};
use ratatui::{CompletedFrame, backend::{Backend, CrosstermBackend}, buffer::Buffer, layout::Position}; use ratatui::{CompletedFrame, backend::{Backend, CrosstermBackend}, buffer::Buffer, layout::Position};
use yazi_actor::{Ctx, lives::Lives}; use yazi_actor::{Ctx, lives::Lives};
use yazi_binding::elements::COLLISION;
use yazi_macro::{act, succ}; use yazi_macro::{act, succ};
use yazi_shared::{data::Data, event::NEED_RENDER}; use yazi_shared::{data::Data, event::NEED_RENDER};
use yazi_tty::TTY; use yazi_tty::TTY;
use yazi_widgets::COLLISION;
use crate::{app::App, root::Root}; use crate::{app::App, root::Root};

View file

@ -52,7 +52,7 @@ impl Widget for Cmp<'_> {
area.height = rect.height.saturating_sub(area.y).min(area.height); area.height = rect.height.saturating_sub(area.y).min(area.height);
} }
yazi_binding::elements::Clear::default().render(area, buf); yazi_widgets::Clear.render(area, buf);
List::new(items) List::new(items)
.block(Block::bordered().border_type(BorderType::Rounded).border_style(THEME.cmp.border)) .block(Block::bordered().border_type(BorderType::Rounded).border_style(THEME.cmp.border))
.render(area, buf); .render(area, buf);

View file

@ -15,7 +15,7 @@ impl Widget for Confirm<'_> {
let confirm = &self.core.confirm; let confirm = &self.core.confirm;
let area = self.core.mgr.area(confirm.position); let area = self.core.mgr.area(confirm.position);
yazi_binding::elements::Clear::default().render(area, buf); yazi_widgets::Clear.render(area, buf);
Block::bordered() Block::bordered()
.border_type(BorderType::Rounded) .border_type(BorderType::Rounded)

View file

@ -22,7 +22,7 @@ impl<'a> Help<'a> {
impl Widget for Help<'_> { impl Widget for Help<'_> {
fn render(self, area: Rect, buf: &mut Buffer) { fn render(self, area: Rect, buf: &mut Buffer) {
let help = &self.core.help; let help = &self.core.help;
yazi_binding::elements::Clear::default().render(area, buf); yazi_widgets::Clear.render(area, buf);
let chunks = layout::Layout::vertical([Constraint::Fill(1), Constraint::Length(1)]).split(area); let chunks = layout::Layout::vertical([Constraint::Fill(1), Constraint::Length(1)]).split(area);
Line::styled( Line::styled(

View file

@ -15,7 +15,7 @@ impl Widget for Input<'_> {
let input = &self.core.input; let input = &self.core.input;
let area = self.core.mgr.area(input.position); let area = self.core.mgr.area(input.position);
yazi_binding::elements::Clear::default().render(area, buf); yazi_widgets::Clear.render(area, buf);
Block::bordered() Block::bordered()
.border_type(BorderType::Rounded) .border_type(BorderType::Rounded)

View file

@ -43,7 +43,7 @@ impl Widget for Notify<'_> {
tiles[i].offset(Offset { x: (100 - m.percent) as i32 * tiles[i].width as i32 / 100, y: 0 }); tiles[i].offset(Offset { x: (100 - m.percent) as i32 * tiles[i].width as i32 / 100, y: 0 });
rect.width -= rect.x - tiles[i].x; rect.width -= rect.x - tiles[i].x;
yazi_binding::elements::Clear::default().render(rect, buf); yazi_widgets::Clear.render(rect, buf);
Paragraph::new(m.content.as_str()) Paragraph::new(m.content.as_str())
.wrap(Wrap { trim: false }) .wrap(Wrap { trim: false })
.block( .block(

View file

@ -17,7 +17,7 @@ impl Widget for Pick<'_> {
let pick = &self.core.pick; let pick = &self.core.pick;
let area = self.core.mgr.area(pick.position); let area = self.core.mgr.area(pick.position);
yazi_binding::elements::Clear::default().render(area, buf); yazi_widgets::Clear.render(area, buf);
Block::bordered() Block::bordered()
.title(pick.title()) .title(pick.title())

View file

@ -32,7 +32,7 @@ impl Widget for Tasks<'_> {
fn render(self, area: Rect, buf: &mut Buffer) { fn render(self, area: Rect, buf: &mut Buffer) {
let area = Self::area(area); let area = Self::area(area);
yazi_binding::elements::Clear::default().render(area, buf); yazi_widgets::Clear.render(area, buf);
let block = Block::bordered() let block = Block::bordered()
.title(Line::styled("Tasks", THEME.tasks.title)) .title(Line::styled("Tasks", THEME.tasks.title))

View file

@ -46,7 +46,7 @@ impl Widget for Which<'_> {
.split(area) .split(area)
}; };
yazi_binding::elements::Clear::default().render(area, buf); yazi_widgets::Clear.render(area, buf);
Block::new().style(THEME.which.mask).render(area, buf); Block::new().style(THEME.which.mask).render(area, buf);
for y in 0..area.height { for y in 0..area.height {

View file

@ -23,6 +23,7 @@ yazi-fs = { path = "../yazi-fs", version = "26.1.22" }
yazi-macro = { path = "../yazi-macro", version = "26.1.22" } yazi-macro = { path = "../yazi-macro", version = "26.1.22" }
yazi-shared = { path = "../yazi-shared", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" }
yazi-vfs = { path = "../yazi-vfs", version = "26.1.22" } yazi-vfs = { path = "../yazi-vfs", version = "26.1.22" }
yazi-widgets = { path = "../yazi-widgets", version = "26.1.22" }
# External dependencies # External dependencies
anyhow = { workspace = true } anyhow = { workspace = true }

View file

@ -1,8 +1,7 @@
use anyhow::bail; use anyhow::bail;
use mlua::{ExternalError, IntoLua, Lua, Value}; use mlua::{ExternalError, IntoLua, Lua, Value};
use yazi_shared::event::CmdCow; use yazi_shared::event::CmdCow;
use yazi_widgets::Step;
use crate::Step;
#[derive(Clone, Copy, Debug, Default)] #[derive(Clone, Copy, Debug, Default)]
pub struct ArrowOpt { pub struct ArrowOpt {

View file

@ -1,8 +1,6 @@
use std::path::MAIN_SEPARATOR_STR;
use anyhow::bail; use anyhow::bail;
use mlua::{ExternalError, FromLua, IntoLua, Lua, Value}; use mlua::{ExternalError, FromLua, IntoLua, Lua, Value};
use yazi_shared::{Id, event::CmdCow, path::PathBufDyn, strand::{StrandBuf, StrandLike}, url::UrlBuf}; use yazi_shared::{Id, event::CmdCow, path::PathBufDyn, strand::StrandBuf, url::UrlBuf};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ShowOpt { pub struct ShowOpt {
@ -38,9 +36,3 @@ pub struct CmpItem {
pub name: StrandBuf, pub name: StrandBuf,
pub is_dir: bool, pub is_dir: bool,
} }
impl CmpItem {
pub fn completable(&self) -> String {
format!("{}{}", self.name.to_string_lossy(), if self.is_dir { MAIN_SEPARATOR_STR } else { "" })
}
}

View file

@ -1 +1 @@
yazi_macro::mod_flat!(backspace backward casefy close complete delete forward insert kill paste r#move show); yazi_macro::mod_flat!(close show);

View file

@ -2,7 +2,8 @@ use anyhow::bail;
use mlua::{ExternalError, FromLua, IntoLua, Lua, Value}; use mlua::{ExternalError, FromLua, IntoLua, Lua, Value};
use tokio::sync::mpsc; use tokio::sync::mpsc;
use yazi_config::popup::InputCfg; use yazi_config::popup::InputCfg;
use yazi_shared::{errors::InputError, event::CmdCow}; use yazi_shared::event::CmdCow;
use yazi_widgets::input::InputError;
#[derive(Debug)] #[derive(Debug)]
pub struct ShowOpt { pub struct ShowOpt {

View file

@ -1,3 +1,3 @@
yazi_macro::mod_pub!(app cmp confirm help input 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!(arrow step void); yazi_macro::mod_flat!(arrow void);

View file

@ -33,7 +33,6 @@ yazi-widgets = { path = "../yazi-widgets", version = "26.1.22" }
# External dependencies # External dependencies
anyhow = { workspace = true } anyhow = { workspace = true }
crossterm = { workspace = true }
futures = { workspace = true } futures = { workspace = true }
hashbrown = { workspace = true } hashbrown = { workspace = true }
mlua = { workspace = true } mlua = { workspace = true }

View file

@ -1 +0,0 @@
yazi_macro::mod_flat!(calculator chan image input layer mouse range);

View file

@ -1,14 +1,12 @@
use std::str::FromStr; use std::str::FromStr;
use mlua::{ExternalError, Function, IntoLua, IntoLuaMulti, Lua, Table, Value}; use mlua::{ExternalError, Function, IntoLua, IntoLuaMulti, Lua, Table, Value};
use yazi_binding::{Cha, Composer, ComposerGet, ComposerSet, Error, File, Url, UrlRef}; use yazi_binding::{Cha, Composer, ComposerGet, ComposerSet, Error, File, SizeCalculator, Url, UrlRef};
use yazi_config::Pattern; use yazi_config::Pattern;
use yazi_fs::{mounts::PARTITIONS, provider::{Attrs, DirReader, FileHolder}}; use yazi_fs::{mounts::PARTITIONS, provider::{Attrs, DirReader, FileHolder}};
use yazi_shared::url::{UrlCow, UrlLike}; use yazi_shared::url::{UrlCow, UrlLike};
use yazi_vfs::{VfsFile, provider}; use yazi_vfs::{VfsFile, provider};
use crate::bindings::SizeCalculator;
pub fn compose() -> Composer<ComposerGet, ComposerSet> { pub fn compose() -> Composer<ComposerGet, ComposerSet> {
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> { fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
match key { match key {

View file

@ -1,4 +1,4 @@
yazi_macro::mod_pub!(bindings elements external fs isolate loader process pubsub runtime theme utils); yazi_macro::mod_pub!(elements external fs isolate loader process pubsub runtime theme utils);
yazi_macro::mod_flat!(lua); yazi_macro::mod_flat!(lua);

View file

@ -1,11 +1,10 @@
use mlua::{Function, IntoLuaMulti, Lua, Value}; use mlua::{Function, IntoLuaMulti, Lua, Value};
use yazi_adapter::{ADAPTOR, Image}; use yazi_adapter::{ADAPTOR, Image};
use yazi_binding::{Error, UrlRef, elements::Rect}; use yazi_binding::{Error, ImageInfo, UrlRef, elements::Rect};
use yazi_fs::FsUrl; use yazi_fs::FsUrl;
use yazi_shared::url::{AsUrl, UrlLike}; use yazi_shared::url::{AsUrl, UrlLike};
use super::Utils; use super::Utils;
use crate::bindings::ImageInfo;
impl Utils { impl Utils {
pub(super) fn image_info(lua: &Lua) -> mlua::Result<Function> { pub(super) fn image_info(lua: &Lua) -> mlua::Result<Function> {

View file

@ -3,7 +3,7 @@ use std::{str::FromStr, time::Duration};
use mlua::{ExternalError, ExternalResult, Function, IntoLuaMulti, Lua, Table, Value}; use mlua::{ExternalError, ExternalResult, Function, IntoLuaMulti, Lua, Table, Value};
use tokio::sync::mpsc; use tokio::sync::mpsc;
use tokio_stream::wrappers::UnboundedReceiverStream; use tokio_stream::wrappers::UnboundedReceiverStream;
use yazi_binding::{elements::{Line, Pos, Text}, runtime}; use yazi_binding::{InputRx, elements::{Line, Pos, Text}, runtime};
use yazi_config::{keymap::{Chord, ChordCow, Key}, popup::{ConfirmCfg, InputCfg}}; use yazi_config::{keymap::{Chord, ChordCow, Key}, popup::{ConfirmCfg, InputCfg}};
use yazi_macro::relay; use yazi_macro::relay;
use yazi_parser::{notify::PushOpt, which::ActivateOpt}; use yazi_parser::{notify::PushOpt, which::ActivateOpt};
@ -11,7 +11,6 @@ use yazi_proxy::{ConfirmProxy, InputProxy, NotifyProxy, WhichProxy};
use yazi_shared::Debounce; use yazi_shared::Debounce;
use super::Utils; use super::Utils;
use crate::bindings::InputRx;
impl Utils { impl Utils {
pub(super) fn which(lua: &Lua) -> mlua::Result<Function> { pub(super) fn which(lua: &Lua) -> mlua::Result<Function> {

View file

@ -4,14 +4,14 @@ use anyhow::Context;
use futures::future::join_all; use futures::future::join_all;
use mlua::{ExternalError, ExternalResult, Function, IntoLuaMulti, Lua, MultiValue, Table, Value, Variadic}; use mlua::{ExternalError, ExternalResult, Function, IntoLuaMulti, Lua, MultiValue, Table, Value, Variadic};
use tokio::sync::mpsc; use tokio::sync::mpsc;
use yazi_binding::{Handle, runtime, runtime_mut}; use yazi_binding::{Handle, MpscRx, MpscTx, MpscUnboundedRx, MpscUnboundedTx, OneshotRx, OneshotTx, runtime, runtime_mut};
use yazi_dds::Sendable; use yazi_dds::Sendable;
use yazi_parser::app::PluginOpt; use yazi_parser::app::PluginOpt;
use yazi_proxy::AppProxy; use yazi_proxy::AppProxy;
use yazi_shared::{LOCAL_SET, data::Data}; use yazi_shared::{LOCAL_SET, data::Data};
use super::Utils; use super::Utils;
use crate::{bindings::{MpscRx, MpscTx, MpscUnboundedRx, MpscUnboundedTx, OneshotRx, OneshotTx}, loader::LOADER}; use crate::loader::LOADER;
impl Utils { impl Utils {
pub(super) fn sync(lua: &Lua) -> mlua::Result<Function> { pub(super) fn sync(lua: &Lua) -> mlua::Result<Function> {

View file

@ -12,10 +12,11 @@ repository = "https://github.com/sxyazi/yazi"
workspace = true workspace = true
[dependencies] [dependencies]
yazi-config = { path = "../yazi-config", version = "26.1.22" } yazi-config = { path = "../yazi-config", version = "26.1.22" }
yazi-macro = { path = "../yazi-macro", version = "26.1.22" } yazi-macro = { path = "../yazi-macro", version = "26.1.22" }
yazi-parser = { path = "../yazi-parser", version = "26.1.22" } yazi-parser = { path = "../yazi-parser", version = "26.1.22" }
yazi-shared = { path = "../yazi-shared", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" }
yazi-widgets = { path = "../yazi-widgets", version = "26.1.22" }
# External dependencies # External dependencies
tokio = { workspace = true } tokio = { workspace = true }

View file

@ -1,7 +1,7 @@
use tokio::sync::mpsc; use tokio::sync::mpsc;
use yazi_config::popup::InputCfg; use yazi_config::popup::InputCfg;
use yazi_macro::{emit, relay}; use yazi_macro::{emit, relay};
use yazi_shared::errors::InputError; use yazi_widgets::input::InputError;
pub struct InputProxy; pub struct InputProxy;

View file

@ -4,7 +4,7 @@ use anyhow::{Result, bail};
use hashbrown::HashMap; use hashbrown::HashMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{Id, SStr, data::{DataAny, DataKey}, path::PathBufDyn, url::{UrlBuf, UrlCow}}; use crate::{Id, SStr, data::{DataAny, DataKey}, path::PathBufDyn, strand::{IntoStrand, StrandBuf}, url::{UrlBuf, UrlCow}};
// --- Data // --- Data
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
@ -178,6 +178,32 @@ impl<'a> TryFrom<&'a Data> for &'a [u8] {
} }
} }
impl TryFrom<Data> for StrandBuf {
type Error = anyhow::Error;
fn try_from(value: Data) -> Result<Self, Self::Error> {
Ok(match value {
Data::String(s) => s.into_owned().into(),
Data::Path(p) => p.into_strand(),
Data::Bytes(b) => StrandBuf::Bytes(b),
_ => bail!("cannot convert to StrandBuf"),
})
}
}
impl TryFrom<&Data> for StrandBuf {
type Error = anyhow::Error;
fn try_from(value: &Data) -> Result<Self, Self::Error> {
Ok(match value {
Data::String(s) => s.to_string().into(),
Data::Path(p) => p.into_strand(),
Data::Bytes(b) => StrandBuf::Bytes(b.clone()),
_ => bail!("cannot convert to StrandBuf"),
})
}
}
impl PartialEq<bool> for Data { impl PartialEq<bool> for Data {
fn eq(&self, other: &bool) -> bool { self.try_into().is_ok_and(|b| *other == b) } fn eq(&self, other: &bool) -> bool { self.try_into().is_ok_and(|b| *other == b) }
} }

View file

@ -1 +1 @@
yazi_macro::mod_flat!(input peek); yazi_macro::mod_flat!(peek);

View file

@ -11,14 +11,6 @@ pub enum CmdCow {
Borrowed(&'static Cmd), Borrowed(&'static Cmd),
} }
impl From<Cmd> for CmdCow {
fn from(c: Cmd) -> Self { Self::Owned(c) }
}
impl From<&'static Cmd> for CmdCow {
fn from(c: &'static Cmd) -> Self { Self::Borrowed(c) }
}
impl Deref for CmdCow { impl Deref for CmdCow {
type Target = Cmd; type Target = Cmd;
@ -30,6 +22,18 @@ impl Deref for CmdCow {
} }
} }
impl From<CmdCow> for () {
fn from(_: CmdCow) -> Self { () }
}
impl From<Cmd> for CmdCow {
fn from(c: Cmd) -> Self { Self::Owned(c) }
}
impl From<&'static Cmd> for CmdCow {
fn from(c: &'static Cmd) -> Self { Self::Borrowed(c) }
}
impl CmdCow { impl CmdCow {
pub fn take<'a, T>(&mut self, name: impl Into<DataKey>) -> Result<T> pub fn take<'a, T>(&mut self, name: impl Into<DataKey>) -> Result<T>
where where

View file

@ -148,3 +148,26 @@ where
{ {
fn to_strand(&self) -> StrandCow<'_> { self.as_url().components().strand() } fn to_strand(&self) -> StrandCow<'_> { self.as_url().components().strand() }
} }
// --- IntoStrand
pub trait IntoStrand {
fn into_strand(self) -> StrandBuf;
}
impl IntoStrand for PathBufDyn {
fn into_strand(self) -> StrandBuf {
match self {
Self::Os(p) => StrandBuf::Os(p.into_os_string()),
Self::Unix(p) => StrandBuf::Bytes(p.into_vec()),
}
}
}
impl IntoStrand for &PathBufDyn {
fn into_strand(self) -> StrandBuf {
match self {
PathBufDyn::Os(p) => StrandBuf::Os(p.as_os_str().to_owned()),
PathBufDyn::Unix(p) => StrandBuf::Bytes(p.as_bytes().to_owned()),
}
}
}

View file

@ -12,10 +12,9 @@ repository = "https://github.com/sxyazi/yazi"
workspace = true workspace = true
[dependencies] [dependencies]
yazi-binding = { path = "../yazi-binding", version = "26.1.22" } yazi-adapter = { path = "../yazi-adapter", version = "26.1.22" }
yazi-config = { path = "../yazi-config", version = "26.1.22" } yazi-config = { path = "../yazi-config", version = "26.1.22" }
yazi-macro = { path = "../yazi-macro", version = "26.1.22" } yazi-macro = { path = "../yazi-macro", version = "26.1.22" }
yazi-parser = { path = "../yazi-parser", version = "26.1.22" }
yazi-shared = { path = "../yazi-shared", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" }
yazi-tty = { path = "../yazi-tty", version = "26.1.22" } yazi-tty = { path = "../yazi-tty", version = "26.1.22" }
@ -24,6 +23,7 @@ anyhow = { workspace = true }
base64 = { workspace = true } base64 = { workspace = true }
crossterm = { workspace = true } crossterm = { workspace = true }
futures = { workspace = true } futures = { workspace = true }
mlua = { workspace = true }
parking_lot = { workspace = true } parking_lot = { workspace = true }
ratatui = { workspace = true } ratatui = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }

46
yazi-widgets/src/clear.rs Normal file
View file

@ -0,0 +1,46 @@
use std::sync::atomic::{AtomicBool, Ordering};
use ratatui::widgets::Widget;
use yazi_adapter::ADAPTOR;
pub static COLLISION: AtomicBool = AtomicBool::new(false);
#[derive(Clone, Copy, Debug, Default)]
pub struct Clear;
impl Widget for Clear {
fn render(self, area: ratatui::layout::Rect, buf: &mut ratatui::prelude::Buffer)
where
Self: Sized,
{
ratatui::widgets::Clear.render(area, buf);
let Some(r) = ADAPTOR.get().shown_load().and_then(|r| overlap(area, r)) else {
return;
};
ADAPTOR.get().image_erase(r).ok();
COLLISION.store(true, Ordering::Relaxed);
for y in r.top()..r.bottom() {
for x in r.left()..r.right() {
buf[(x, y)].set_skip(true);
}
}
}
}
const fn is_overlapping(a: ratatui::layout::Rect, b: ratatui::layout::Rect) -> bool {
a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y
}
fn overlap(a: ratatui::layout::Rect, b: ratatui::layout::Rect) -> Option<ratatui::layout::Rect> {
if !is_overlapping(a, b) {
return None;
}
let x = a.x.max(b.x);
let y = a.y.max(b.y);
let width = (a.x + a.width).min(b.x + b.width) - x;
let height = (a.y + a.height).min(b.y + b.height) - y;
Some(ratatui::layout::Rect { x, y, width, height })
}

View file

@ -1,9 +1,8 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::input::BackspaceOpt;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::input::Input; use crate::input::{Input, parser::BackspaceOpt};
impl Input { impl Input {
pub fn backspace(&mut self, opt: BackspaceOpt) -> Result<Data> { pub fn backspace(&mut self, opt: BackspaceOpt) -> Result<Data> {

View file

@ -1,9 +1,8 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, succ}; use yazi_macro::{act, succ};
use yazi_parser::input::BackwardOpt;
use yazi_shared::{CharKind, data::Data}; use yazi_shared::{CharKind, data::Data};
use crate::input::Input; use crate::input::{Input, parser::BackwardOpt};
impl Input { impl Input {
pub fn backward(&mut self, opt: BackwardOpt) -> Result<Data> { pub fn backward(&mut self, opt: BackwardOpt) -> Result<Data> {

View file

@ -2,10 +2,9 @@ use std::ops::Range;
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::input::CasefyOpt;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::input::{Input, op::InputOp}; use crate::input::{Input, op::InputOp, parser::CasefyOpt};
impl Input { impl Input {
pub fn casefy(&mut self, opt: CasefyOpt) -> Result<Data> { pub fn casefy(&mut self, opt: CasefyOpt) -> Result<Data> {

View file

@ -2,10 +2,9 @@ use std::path::MAIN_SEPARATOR_STR;
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::input::CompleteOpt;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::input::Input; use crate::input::{Input, parser::CompleteOpt};
#[cfg(windows)] #[cfg(windows)]
const SEPARATOR: [char; 2] = ['/', '\\']; const SEPARATOR: [char; 2] = ['/', '\\'];
@ -17,9 +16,9 @@ impl Input {
pub fn complete(&mut self, opt: CompleteOpt) -> Result<Data> { pub fn complete(&mut self, opt: CompleteOpt) -> Result<Data> {
let (before, after) = self.partition(); let (before, after) = self.partition();
let new = if let Some((prefix, _)) = before.rsplit_once(SEPARATOR) { let new = if let Some((prefix, _)) = before.rsplit_once(SEPARATOR) {
format!("{prefix}/{}{after}", opt.item.completable()).replace(SEPARATOR, MAIN_SEPARATOR_STR) format!("{prefix}/{}{after}", opt.completable()).replace(SEPARATOR, MAIN_SEPARATOR_STR)
} else { } else {
format!("{}{after}", opt.item.completable()).replace(SEPARATOR, MAIN_SEPARATOR_STR) format!("{}{after}", opt.completable()).replace(SEPARATOR, MAIN_SEPARATOR_STR)
}; };
let snap = self.snap_mut(); let snap = self.snap_mut();

View file

@ -1,9 +1,8 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::input::DeleteOpt;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::input::{Input, op::InputOp}; use crate::input::{Input, op::InputOp, parser::DeleteOpt};
impl Input { impl Input {
pub fn delete(&mut self, opt: DeleteOpt) -> Result<Data> { pub fn delete(&mut self, opt: DeleteOpt) -> Result<Data> {

View file

@ -1,12 +1,11 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, succ}; use yazi_macro::{act, succ};
use yazi_parser::VoidOpt;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::input::{Input, InputMode, op::InputOp}; use crate::input::{Input, InputMode, op::InputOp};
impl Input { impl Input {
pub fn escape(&mut self, _: VoidOpt) -> Result<Data> { pub fn escape(&mut self, _: ()) -> Result<Data> {
let snap = self.snap_mut(); let snap = self.snap_mut();
match snap.mode { match snap.mode {
InputMode::Normal => { InputMode::Normal => {

View file

@ -1,9 +1,8 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::act; use yazi_macro::act;
use yazi_parser::input::ForwardOpt;
use yazi_shared::{CharKind, data::Data}; use yazi_shared::{CharKind, data::Data};
use crate::input::{Input, op::InputOp}; use crate::input::{Input, op::InputOp, parser::ForwardOpt};
impl Input { impl Input {
pub fn forward(&mut self, opt: ForwardOpt) -> Result<Data> { pub fn forward(&mut self, opt: ForwardOpt) -> Result<Data> {

View file

@ -1,9 +1,8 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::input::InsertOpt;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::input::{Input, InputMode, op::InputOp}; use crate::input::{Input, InputMode, op::InputOp, parser::InsertOpt};
impl Input { impl Input {
pub fn insert(&mut self, opt: InsertOpt) -> Result<Data> { pub fn insert(&mut self, opt: InsertOpt) -> Result<Data> {

View file

@ -2,10 +2,9 @@ use std::ops::RangeBounds;
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::input::KillOpt;
use yazi_shared::{CharKind, data::Data}; use yazi_shared::{CharKind, data::Data};
use crate::input::Input; use crate::input::{Input, parser::KillOpt};
impl Input { impl Input {
pub fn kill(&mut self, opt: KillOpt) -> Result<Data> { pub fn kill(&mut self, opt: KillOpt) -> Result<Data> {

View file

@ -1,9 +1,8 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{render, succ}; use yazi_macro::{render, succ};
use yazi_parser::input::MoveOpt;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::input::{Input, op::InputOp, snap::InputSnap}; use crate::input::{Input, op::InputOp, parser::MoveOpt, snap::InputSnap};
impl Input { impl Input {
pub fn r#move(&mut self, opt: MoveOpt) -> Result<Data> { pub fn r#move(&mut self, opt: MoveOpt) -> Result<Data> {

View file

@ -1,9 +1,8 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::input::PasteOpt;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::{CLIPBOARD, input::{Input, op::InputOp}}; use crate::{CLIPBOARD, input::{Input, op::InputOp, parser::PasteOpt}};
impl Input { impl Input {
pub fn paste(&mut self, opt: PasteOpt) -> Result<Data> { pub fn paste(&mut self, opt: PasteOpt) -> Result<Data> {

View file

@ -1,12 +1,11 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, render}; use yazi_macro::{act, render};
use yazi_parser::VoidOpt;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::input::Input; use crate::input::Input;
impl Input { impl Input {
pub fn redo(&mut self, _: VoidOpt) -> Result<Data> { pub fn redo(&mut self, _: ()) -> Result<Data> {
render!(self.snaps.redo()); render!(self.snaps.redo());
act!(r#move, self) act!(r#move, self)

View file

@ -1,12 +1,11 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{render, succ}; use yazi_macro::{render, succ};
use yazi_parser::VoidOpt;
use yazi_shared::{data::Data, replace_cow}; use yazi_shared::{data::Data, replace_cow};
use crate::input::{Input, InputMode, op::InputOp}; use crate::input::{Input, InputMode, op::InputOp};
impl Input { impl Input {
pub fn replace(&mut self, _: VoidOpt) -> Result<Data> { pub fn replace(&mut self, _: ()) -> Result<Data> {
let snap = self.snap_mut(); let snap = self.snap_mut();
if snap.mode == InputMode::Normal { if snap.mode == InputMode::Normal {
snap.op = InputOp::None; snap.op = InputOp::None;

View file

@ -1,12 +1,11 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::VoidOpt;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::input::{Input, InputMode, InputOp}; use crate::input::{Input, InputMode, InputOp};
impl Input { impl Input {
pub fn undo(&mut self, _: VoidOpt) -> Result<Data> { pub fn undo(&mut self, _: ()) -> Result<Data> {
if self.snap().op != InputOp::None { if self.snap().op != InputOp::None {
succ!(); succ!();
} }

View file

@ -1,12 +1,11 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::VoidOpt;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::input::{Input, InputMode, op::InputOp}; use crate::input::{Input, InputMode, op::InputOp};
impl Input { impl Input {
pub fn visual(&mut self, _: VoidOpt) -> Result<Data> { pub fn visual(&mut self, _: ()) -> Result<Data> {
if self.snap().mode != InputMode::Normal { if self.snap().mode != InputMode::Normal {
act!(escape, self)?; act!(escape, self)?;
} }

View file

@ -1,12 +1,11 @@
use anyhow::Result; use anyhow::Result;
use yazi_macro::{act, render, succ}; use yazi_macro::{act, render, succ};
use yazi_parser::VoidOpt;
use yazi_shared::data::Data; use yazi_shared::data::Data;
use crate::input::{Input, op::InputOp}; use crate::input::{Input, op::InputOp};
impl Input { impl Input {
pub fn yank(&mut self, _: VoidOpt) -> Result<Data> { pub fn yank(&mut self, _: ()) -> Result<Data> {
match self.snap().op { match self.snap().op {
InputOp::None => { InputOp::None => {
self.snap_mut().op = InputOp::Yank(self.snap().cursor); self.snap_mut().op = InputOp::Yank(self.snap().cursor);

View file

@ -1,6 +1,6 @@
use std::{error::Error, fmt::{self, Display}}; use std::{error::Error, fmt::{self, Display}};
use crate::Id; use yazi_shared::Id;
#[derive(Debug)] #[derive(Debug)]
pub enum InputError { pub enum InputError {

View file

@ -1,3 +1,3 @@
yazi_macro::mod_pub!(commands); yazi_macro::mod_pub!(commands parser);
yazi_macro::mod_flat!(input mode op snap snaps widget); yazi_macro::mod_flat!(error input mode op snap snaps widget);

View file

@ -1,12 +1,12 @@
use anyhow::bail; use std::path::MAIN_SEPARATOR_STR;
use mlua::{ExternalError, FromLua, IntoLua, Lua, Value};
use yazi_shared::{Id, event::CmdCow};
use crate::cmp::CmpItem; use mlua::{ExternalError, FromLua, IntoLua, Lua, Value};
use yazi_shared::{Id, event::CmdCow, strand::{StrandBuf, StrandLike}};
#[derive(Debug)] #[derive(Debug)]
pub struct CompleteOpt { pub struct CompleteOpt {
pub item: CmpItem, pub name: StrandBuf,
pub is_dir: bool,
pub ticket: Id, pub ticket: Id,
} }
@ -14,11 +14,11 @@ impl TryFrom<CmdCow> for CompleteOpt {
type Error = anyhow::Error; type Error = anyhow::Error;
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> { fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
let Some(item) = c.take_any("item") else { Ok(Self {
bail!("Invalid 'item' in CompleteOpt"); name: c.take("name")?,
}; is_dir: c.bool("is_dir"),
ticket: c.get("ticket").unwrap_or_default(),
Ok(Self { item, ticket: c.get("ticket").unwrap_or_default() }) })
} }
} }
@ -29,3 +29,9 @@ impl FromLua for CompleteOpt {
impl IntoLua for CompleteOpt { impl IntoLua for CompleteOpt {
fn into_lua(self, _: &Lua) -> mlua::Result<Value> { Err("unsupported".into_lua_err()) } fn into_lua(self, _: &Lua) -> mlua::Result<Value> { Err("unsupported".into_lua_err()) }
} }
impl CompleteOpt {
pub(crate) fn completable(&self) -> String {
format!("{}{}", self.name.to_string_lossy(), if self.is_dir { MAIN_SEPARATOR_STR } else { "" })
}
}

View file

@ -0,0 +1 @@
yazi_macro::mod_flat!(backspace backward casefy complete delete forward insert kill paste r#move);

View file

@ -10,7 +10,7 @@ impl Widget for &Input {
where where
Self: Sized, Self: Sized,
{ {
yazi_binding::elements::Clear::default().render(area, buf); crate::Clear::default().render(area, buf);
Line::styled(self.display(), THEME.input.value).render(area, buf); Line::styled(self.display(), THEME.input.value).render(area, buf);

View file

@ -1,5 +1,5 @@
yazi_macro::mod_pub!(input); yazi_macro::mod_pub!(input);
yazi_macro::mod_flat!(clipboard scrollable); yazi_macro::mod_flat!(clear clipboard scrollable step);
pub fn init() { CLIPBOARD.with(<_>::default); } pub fn init() { CLIPBOARD.with(<_>::default); }

View file

@ -1,4 +1,4 @@
use yazi_parser::Step; use crate::Step;
pub trait Scrollable { pub trait Scrollable {
fn total(&self) -> usize; fn total(&self) -> usize;