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

View file

@ -19,7 +19,7 @@ impl Actor for Mouse {
const NAME: &str = "mouse";
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 result = Lives::scope(&cx.core, move || {

View file

@ -2,8 +2,9 @@ use std::mem;
use anyhow::Result;
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_widgets::input::parser::CompleteOpt;
use crate::{Actor, Ctx};
@ -17,7 +18,7 @@ impl Actor for Close {
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
let cmp = &mut cx.core.cmp;
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();

View file

@ -1,7 +1,8 @@
use anyhow::Result;
use yazi_macro::{act, render, succ};
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};

View file

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

View file

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

View file

@ -58,7 +58,7 @@ impl UserData for Core {
b"tasks" => reuse!(tasks, super::Tasks::make(&me.tasks)),
b"yanked" => reuse!(yanked, super::Yanked::make(&me.mgr.yanked)),
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)),
_ => Value::Nil,

View file

@ -1,9 +1,8 @@
use std::{ops::Deref, ptr};
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_plugin::bindings::Range;
use yazi_shared::{path::AsPath, url::UrlLike};
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_parser::mgr::CdOpt;
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_widgets::input::InputError;
use crate::{Actor, Ctx};

View file

@ -7,7 +7,8 @@ use yazi_config::popup::InputCfg;
use yazi_macro::succ;
use yazi_parser::mgr::FilterOpt;
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};

View file

@ -7,7 +7,8 @@ use yazi_config::popup::InputCfg;
use yazi_macro::succ;
use yazi_parser::mgr::{FindDoOpt, FindOpt};
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};

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-macro = { path = "../yazi-macro", 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
ansi-to-tui = { workspace = true }
crossterm = { workspace = true }
futures = { workspace = true }
hashbrown = { workspace = true }
mlua = { workspace = true }
@ -32,5 +35,9 @@ paste = { workspace = true }
ratatui = { workspace = true }
serde_json = { workspace = true }
tokio = { workspace = true }
tokio-stream = { workspace = true }
tracing = { 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 yazi_binding::Error;
use crate::Error;
pub enum SizeCalculator {
Local(yazi_fs::provider::local::SizeCalculator),

View file

@ -1,5 +1,6 @@
use mlua::{ExternalError, IntoLuaMulti, UserData, Value};
use yazi_binding::Error;
use crate::Error;
pub struct MpscTx(pub tokio::sync::mpsc::Sender<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 yazi_adapter::ADAPTOR;
use ratatui::widgets::Widget;
use super::Area;
pub static COLLISION: AtomicBool = AtomicBool::new(false);
#[derive(Clone, Copy, Debug, Default)]
pub struct Clear {
pub area: Area,
@ -23,28 +19,7 @@ impl Clear {
}
pub(super) fn render(self, rect: ratatui::layout::Rect, buf: &mut ratatui::buffer::Buffer) {
<Self as ratatui::widgets::Widget>::render(Default::default(), 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);
}
}
yazi_widgets::Clear.render(rect, buf);
}
}
@ -53,19 +28,3 @@ impl UserData for Clear {
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 tokio::pin;
use tokio_stream::StreamExt;
use yazi_shared::errors::InputError;
use yazi_widgets::input::InputError;
pub struct InputRx<T: StreamExt<Item = Result<String, InputError>>> {
inner: T,

View file

@ -2,4 +2,4 @@ mod macros;
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 yazi_config::popup::Position;
use yazi_shared::{Ids, errors::InputError};
use yazi_shared::Ids;
use yazi_widgets::input::InputError;
#[derive(Default)]
pub struct Input {

View file

@ -4,10 +4,9 @@ use yazi_config::{LAYOUT, YAZI};
use yazi_dds::Pubsub;
use yazi_fs::{File, Files, FilesOp, FolderStage, cha::Cha};
use yazi_macro::err;
use yazi_parser::Step;
use yazi_proxy::MgrProxy;
use yazi_shared::{Id, path::{AsPath, PathBufDyn, PathDyn}, url::UrlBuf};
use yazi_widgets::Scrollable;
use yazi_widgets::{Scrollable, Step};
pub struct Folder {
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-parser = { path = "../yazi-parser", version = "26.1.22" }
yazi-shared = { path = "../yazi-shared", version = "26.1.22" }
yazi-widgets = { path = "../yazi-widgets", version = "26.1.22" }
# External dependencies
anyhow = { workspace = true }

View file

@ -15,7 +15,7 @@ macro_rules! spark {
#[macro_export]
macro_rules! try_from_spark {
($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 = ();
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),
// Input
InputBackspace(yazi_parser::input::BackspaceOpt),
InputBackward(yazi_parser::input::BackwardOpt),
InputBackspace(yazi_widgets::input::parser::BackspaceOpt),
InputBackward(yazi_widgets::input::parser::BackwardOpt),
InputClose(yazi_parser::input::CloseOpt),
InputComplete(yazi_parser::input::CompleteOpt),
InputDelete(yazi_parser::input::DeleteOpt),
InputComplete(yazi_widgets::input::parser::CompleteOpt),
InputDelete(yazi_widgets::input::parser::DeleteOpt),
InputEscape(yazi_parser::VoidOpt),
InputForward(yazi_parser::input::ForwardOpt),
InputInsert(yazi_parser::input::InsertOpt),
InputKill(yazi_parser::input::KillOpt),
InputMove(yazi_parser::input::MoveOpt),
InputPaste(yazi_parser::input::PasteOpt),
InputForward(yazi_widgets::input::parser::ForwardOpt),
InputInsert(yazi_widgets::input::parser::InsertOpt),
InputKill(yazi_widgets::input::parser::KillOpt),
InputMove(yazi_widgets::input::parser::MoveOpt),
InputPaste(yazi_widgets::input::parser::PasteOpt),
InputShow(yazi_parser::input::ShowOpt),
// Notify
@ -323,7 +323,7 @@ impl<'a> IntoLua for Spark<'a> {
}
try_from_spark!(
VoidOpt,
yazi_parser::VoidOpt,
app:bootstrap,
app:focus,
mgr:back,
@ -345,81 +345,81 @@ try_from_spark!(
);
// App
try_from_spark!(ArrowOpt, mgr:arrow, mgr:tab_swap);
try_from_spark!(app::DeprecateOpt, app:deprecate);
try_from_spark!(app::MouseOpt, app:mouse);
try_from_spark!(app::PluginOpt, app:plugin, app:plugin_do);
try_from_spark!(app::QuitOpt, app:quit, mgr:quit);
try_from_spark!(app::ReflowOpt, app:reflow, app:resize);
try_from_spark!(app::ResumeOpt, app:resume);
try_from_spark!(app::StopOpt, app:stop);
try_from_spark!(app::UpdateProgressOpt, app:update_progress);
try_from_spark!(cmp::CloseOpt, cmp:close);
try_from_spark!(cmp::ShowOpt, cmp:show);
try_from_spark!(cmp::TriggerOpt, cmp:trigger);
try_from_spark!(confirm::CloseOpt, confirm:close);
try_from_spark!(confirm::ShowOpt, confirm:show);
try_from_spark!(help::ToggleOpt, help:toggle);
try_from_spark!(input::BackspaceOpt, input:backspace);
try_from_spark!(input::BackwardOpt, input:backward);
try_from_spark!(input::CloseOpt, input:close);
try_from_spark!(input::CompleteOpt, input:complete);
try_from_spark!(input::DeleteOpt, input:delete);
try_from_spark!(input::ForwardOpt, input:forward);
try_from_spark!(input::InsertOpt, input:insert);
try_from_spark!(input::KillOpt, input:kill);
try_from_spark!(input::MoveOpt, input:move);
try_from_spark!(input::PasteOpt, input:paste);
try_from_spark!(input::ShowOpt, input:show);
try_from_spark!(mgr::CdOpt, mgr:cd);
try_from_spark!(mgr::CloseOpt, mgr:close);
try_from_spark!(mgr::CopyOpt, mgr:copy);
try_from_spark!(mgr::CreateOpt, mgr:create);
try_from_spark!(mgr::DisplaceDoOpt, mgr:displace_do);
try_from_spark!(mgr::DownloadOpt, mgr:download);
try_from_spark!(mgr::EscapeOpt, mgr:escape);
try_from_spark!(mgr::FilterOpt, mgr:filter, mgr:filter_do);
try_from_spark!(mgr::FindArrowOpt, mgr:find_arrow);
try_from_spark!(mgr::FindDoOpt, mgr:find_do);
try_from_spark!(mgr::FindOpt, mgr:find);
try_from_spark!(mgr::HardlinkOpt, mgr:hardlink);
try_from_spark!(mgr::HiddenOpt, mgr:hidden);
try_from_spark!(mgr::HoverOpt, mgr:hover);
try_from_spark!(mgr::LinemodeOpt, mgr:linemode);
try_from_spark!(mgr::LinkOpt, mgr:link);
try_from_spark!(mgr::OpenDoOpt, mgr:open_do);
try_from_spark!(mgr::OpenOpt, mgr:open);
try_from_spark!(mgr::PasteOpt, mgr:paste);
try_from_spark!(mgr::PeekOpt, mgr:peek);
try_from_spark!(mgr::RemoveOpt, mgr:remove, mgr:remove_do);
try_from_spark!(mgr::RenameOpt, mgr:rename);
try_from_spark!(mgr::RevealOpt, mgr:reveal);
try_from_spark!(mgr::SearchOpt, mgr:search, mgr:search_do);
try_from_spark!(mgr::SeekOpt, mgr:seek);
try_from_spark!(mgr::ShellOpt, mgr:shell);
try_from_spark!(mgr::SortOpt, mgr:sort);
try_from_spark!(mgr::SpotOpt, mgr:spot);
try_from_spark!(mgr::StashOpt, mgr:stash);
try_from_spark!(mgr::TabCloseOpt, mgr:tab_close);
try_from_spark!(mgr::TabCreateOpt, mgr:tab_create);
try_from_spark!(mgr::TabSwitchOpt, mgr:tab_switch);
try_from_spark!(mgr::ToggleAllOpt, mgr:toggle_all);
try_from_spark!(mgr::ToggleOpt, mgr:toggle);
try_from_spark!(mgr::UpdateFilesOpt, mgr:update_files);
try_from_spark!(mgr::UpdateMimesOpt, mgr:update_mimes);
try_from_spark!(mgr::UpdatePagedOpt, mgr:update_paged);
try_from_spark!(mgr::UpdatePeekedOpt, mgr:update_peeked);
try_from_spark!(mgr::UpdateSpottedOpt, mgr:update_spotted);
try_from_spark!(mgr::UpdateYankedOpt<'a>, mgr:update_yanked);
try_from_spark!(mgr::UploadOpt, mgr:upload);
try_from_spark!(mgr::VisualModeOpt, mgr:visual_mode);
try_from_spark!(mgr::YankOpt, mgr:yank);
try_from_spark!(notify::PushOpt, notify:push);
try_from_spark!(notify::TickOpt, notify:tick);
try_from_spark!(pick::CloseOpt, pick:close);
try_from_spark!(pick::ShowOpt, pick:show);
try_from_spark!(spot::CopyOpt, spot:copy);
try_from_spark!(tasks::ProcessOpenOpt, tasks:process_open);
try_from_spark!(tasks::UpdateSucceedOpt, tasks:update_succeed);
try_from_spark!(which::ActivateOpt, which:activate);
try_from_spark!(which::CallbackOpt, which:callback);
try_from_spark!(yazi_parser::ArrowOpt, mgr:arrow, mgr:tab_swap);
try_from_spark!(yazi_parser::app::DeprecateOpt, app:deprecate);
try_from_spark!(yazi_parser::app::MouseOpt, app:mouse);
try_from_spark!(yazi_parser::app::PluginOpt, app:plugin, app:plugin_do);
try_from_spark!(yazi_parser::app::QuitOpt, app:quit, mgr:quit);
try_from_spark!(yazi_parser::app::ReflowOpt, app:reflow, app:resize);
try_from_spark!(yazi_parser::app::ResumeOpt, app:resume);
try_from_spark!(yazi_parser::app::StopOpt, app:stop);
try_from_spark!(yazi_parser::app::UpdateProgressOpt, app:update_progress);
try_from_spark!(yazi_parser::cmp::CloseOpt, cmp:close);
try_from_spark!(yazi_parser::cmp::ShowOpt, cmp:show);
try_from_spark!(yazi_parser::cmp::TriggerOpt, cmp:trigger);
try_from_spark!(yazi_parser::confirm::CloseOpt, confirm:close);
try_from_spark!(yazi_parser::confirm::ShowOpt, confirm:show);
try_from_spark!(yazi_parser::help::ToggleOpt, help:toggle);
try_from_spark!(yazi_parser::input::CloseOpt, input:close);
try_from_spark!(yazi_parser::input::ShowOpt, input:show);
try_from_spark!(yazi_parser::mgr::CdOpt, mgr:cd);
try_from_spark!(yazi_parser::mgr::CloseOpt, mgr:close);
try_from_spark!(yazi_parser::mgr::CopyOpt, mgr:copy);
try_from_spark!(yazi_parser::mgr::CreateOpt, mgr:create);
try_from_spark!(yazi_parser::mgr::DisplaceDoOpt, mgr:displace_do);
try_from_spark!(yazi_parser::mgr::DownloadOpt, mgr:download);
try_from_spark!(yazi_parser::mgr::EscapeOpt, mgr:escape);
try_from_spark!(yazi_parser::mgr::FilterOpt, mgr:filter, mgr:filter_do);
try_from_spark!(yazi_parser::mgr::FindArrowOpt, mgr:find_arrow);
try_from_spark!(yazi_parser::mgr::FindDoOpt, mgr:find_do);
try_from_spark!(yazi_parser::mgr::FindOpt, mgr:find);
try_from_spark!(yazi_parser::mgr::HardlinkOpt, mgr:hardlink);
try_from_spark!(yazi_parser::mgr::HiddenOpt, mgr:hidden);
try_from_spark!(yazi_parser::mgr::HoverOpt, mgr:hover);
try_from_spark!(yazi_parser::mgr::LinemodeOpt, mgr:linemode);
try_from_spark!(yazi_parser::mgr::LinkOpt, mgr:link);
try_from_spark!(yazi_parser::mgr::OpenDoOpt, mgr:open_do);
try_from_spark!(yazi_parser::mgr::OpenOpt, mgr:open);
try_from_spark!(yazi_parser::mgr::PasteOpt, mgr:paste);
try_from_spark!(yazi_parser::mgr::PeekOpt, mgr:peek);
try_from_spark!(yazi_parser::mgr::RemoveOpt, mgr:remove, mgr:remove_do);
try_from_spark!(yazi_parser::mgr::RenameOpt, mgr:rename);
try_from_spark!(yazi_parser::mgr::RevealOpt, mgr:reveal);
try_from_spark!(yazi_parser::mgr::SearchOpt, mgr:search, mgr:search_do);
try_from_spark!(yazi_parser::mgr::SeekOpt, mgr:seek);
try_from_spark!(yazi_parser::mgr::ShellOpt, mgr:shell);
try_from_spark!(yazi_parser::mgr::SortOpt, mgr:sort);
try_from_spark!(yazi_parser::mgr::SpotOpt, mgr:spot);
try_from_spark!(yazi_parser::mgr::StashOpt, mgr:stash);
try_from_spark!(yazi_parser::mgr::TabCloseOpt, mgr:tab_close);
try_from_spark!(yazi_parser::mgr::TabCreateOpt, mgr:tab_create);
try_from_spark!(yazi_parser::mgr::TabSwitchOpt, mgr:tab_switch);
try_from_spark!(yazi_parser::mgr::ToggleAllOpt, mgr:toggle_all);
try_from_spark!(yazi_parser::mgr::ToggleOpt, mgr:toggle);
try_from_spark!(yazi_parser::mgr::UpdateFilesOpt, mgr:update_files);
try_from_spark!(yazi_parser::mgr::UpdateMimesOpt, mgr:update_mimes);
try_from_spark!(yazi_parser::mgr::UpdatePagedOpt, mgr:update_paged);
try_from_spark!(yazi_parser::mgr::UpdatePeekedOpt, mgr:update_peeked);
try_from_spark!(yazi_parser::mgr::UpdateSpottedOpt, mgr:update_spotted);
try_from_spark!(yazi_parser::mgr::UpdateYankedOpt<'a>, mgr:update_yanked);
try_from_spark!(yazi_parser::mgr::UploadOpt, mgr:upload);
try_from_spark!(yazi_parser::mgr::VisualModeOpt, mgr:visual_mode);
try_from_spark!(yazi_parser::mgr::YankOpt, mgr:yank);
try_from_spark!(yazi_parser::notify::PushOpt, notify:push);
try_from_spark!(yazi_parser::notify::TickOpt, notify:tick);
try_from_spark!(yazi_parser::pick::CloseOpt, pick:close);
try_from_spark!(yazi_parser::pick::ShowOpt, pick:show);
try_from_spark!(yazi_parser::spot::CopyOpt, spot:copy);
try_from_spark!(yazi_parser::tasks::ProcessOpenOpt, tasks:process_open);
try_from_spark!(yazi_parser::tasks::UpdateSucceedOpt, tasks:update_succeed);
try_from_spark!(yazi_parser::which::ActivateOpt, which:activate);
try_from_spark!(yazi_parser::which::CallbackOpt, which:callback);
try_from_spark!(yazi_widgets::input::parser::BackspaceOpt, input:backspace);
try_from_spark!(yazi_widgets::input::parser::BackwardOpt, input:backward);
try_from_spark!(yazi_widgets::input::parser::CompleteOpt, input:complete);
try_from_spark!(yazi_widgets::input::parser::DeleteOpt, input:delete);
try_from_spark!(yazi_widgets::input::parser::ForwardOpt, input:forward);
try_from_spark!(yazi_widgets::input::parser::InsertOpt, input:insert);
try_from_spark!(yazi_widgets::input::parser::KillOpt, input:kill);
try_from_spark!(yazi_widgets::input::parser::MoveOpt, input:move);
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 ratatui::{CompletedFrame, backend::{Backend, CrosstermBackend}, buffer::Buffer, layout::Position};
use yazi_actor::{Ctx, lives::Lives};
use yazi_binding::elements::COLLISION;
use yazi_macro::{act, succ};
use yazi_shared::{data::Data, event::NEED_RENDER};
use yazi_tty::TTY;
use yazi_widgets::COLLISION;
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);
}
yazi_binding::elements::Clear::default().render(area, buf);
yazi_widgets::Clear.render(area, buf);
List::new(items)
.block(Block::bordered().border_type(BorderType::Rounded).border_style(THEME.cmp.border))
.render(area, buf);

View file

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

View file

@ -22,7 +22,7 @@ impl<'a> Help<'a> {
impl Widget for Help<'_> {
fn render(self, area: Rect, buf: &mut Buffer) {
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);
Line::styled(

View file

@ -15,7 +15,7 @@ impl Widget for Input<'_> {
let input = &self.core.input;
let area = self.core.mgr.area(input.position);
yazi_binding::elements::Clear::default().render(area, buf);
yazi_widgets::Clear.render(area, buf);
Block::bordered()
.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 });
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())
.wrap(Wrap { trim: false })
.block(

View file

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

View file

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

View file

@ -46,7 +46,7 @@ impl Widget for Which<'_> {
.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);
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-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
anyhow = { workspace = true }

View file

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

View file

@ -1,8 +1,6 @@
use std::path::MAIN_SEPARATOR_STR;
use anyhow::bail;
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)]
pub struct ShowOpt {
@ -38,9 +36,3 @@ pub struct CmpItem {
pub name: StrandBuf,
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 tokio::sync::mpsc;
use yazi_config::popup::InputCfg;
use yazi_shared::{errors::InputError, event::CmdCow};
use yazi_shared::event::CmdCow;
use yazi_widgets::input::InputError;
#[derive(Debug)]
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_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
anyhow = { workspace = true }
crossterm = { workspace = true }
futures = { workspace = true }
hashbrown = { 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 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_fs::{mounts::PARTITIONS, provider::{Attrs, DirReader, FileHolder}};
use yazi_shared::url::{UrlCow, UrlLike};
use yazi_vfs::{VfsFile, provider};
use crate::bindings::SizeCalculator;
pub fn compose() -> Composer<ComposerGet, ComposerSet> {
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
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);

View file

@ -1,11 +1,10 @@
use mlua::{Function, IntoLuaMulti, Lua, Value};
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_shared::url::{AsUrl, UrlLike};
use super::Utils;
use crate::bindings::ImageInfo;
impl Utils {
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 tokio::sync::mpsc;
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_macro::relay;
use yazi_parser::{notify::PushOpt, which::ActivateOpt};
@ -11,7 +11,6 @@ use yazi_proxy::{ConfirmProxy, InputProxy, NotifyProxy, WhichProxy};
use yazi_shared::Debounce;
use super::Utils;
use crate::bindings::InputRx;
impl Utils {
pub(super) fn which(lua: &Lua) -> mlua::Result<Function> {

View file

@ -4,14 +4,14 @@ use anyhow::Context;
use futures::future::join_all;
use mlua::{ExternalError, ExternalResult, Function, IntoLuaMulti, Lua, MultiValue, Table, Value, Variadic};
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_parser::app::PluginOpt;
use yazi_proxy::AppProxy;
use yazi_shared::{LOCAL_SET, data::Data};
use super::Utils;
use crate::{bindings::{MpscRx, MpscTx, MpscUnboundedRx, MpscUnboundedTx, OneshotRx, OneshotTx}, loader::LOADER};
use crate::loader::LOADER;
impl Utils {
pub(super) fn sync(lua: &Lua) -> mlua::Result<Function> {

View file

@ -12,10 +12,11 @@ repository = "https://github.com/sxyazi/yazi"
workspace = true
[dependencies]
yazi-config = { path = "../yazi-config", 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-config = { path = "../yazi-config", 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-widgets = { path = "../yazi-widgets", version = "26.1.22" }
# External dependencies
tokio = { workspace = true }
tokio = { workspace = true }

View file

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

View file

@ -4,7 +4,7 @@ use anyhow::{Result, bail};
use hashbrown::HashMap;
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
#[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 {
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),
}
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 {
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 {
pub fn take<'a, T>(&mut self, name: impl Into<DataKey>) -> Result<T>
where

View file

@ -148,3 +148,26 @@ where
{
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
[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-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-tty = { path = "../yazi-tty", version = "26.1.22" }
@ -24,6 +23,7 @@ anyhow = { workspace = true }
base64 = { workspace = true }
crossterm = { workspace = true }
futures = { workspace = true }
mlua = { workspace = true }
parking_lot = { workspace = true }
ratatui = { 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 yazi_macro::{act, render, succ};
use yazi_parser::input::BackspaceOpt;
use yazi_shared::data::Data;
use crate::input::Input;
use crate::input::{Input, parser::BackspaceOpt};
impl Input {
pub fn backspace(&mut self, opt: BackspaceOpt) -> Result<Data> {

View file

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

View file

@ -2,10 +2,9 @@ use std::ops::Range;
use anyhow::Result;
use yazi_macro::{act, render, succ};
use yazi_parser::input::CasefyOpt;
use yazi_shared::data::Data;
use crate::input::{Input, op::InputOp};
use crate::input::{Input, op::InputOp, parser::CasefyOpt};
impl Input {
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 yazi_macro::{act, render, succ};
use yazi_parser::input::CompleteOpt;
use yazi_shared::data::Data;
use crate::input::Input;
use crate::input::{Input, parser::CompleteOpt};
#[cfg(windows)]
const SEPARATOR: [char; 2] = ['/', '\\'];
@ -17,9 +16,9 @@ impl Input {
pub fn complete(&mut self, opt: CompleteOpt) -> Result<Data> {
let (before, after) = self.partition();
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 {
format!("{}{after}", opt.item.completable()).replace(SEPARATOR, MAIN_SEPARATOR_STR)
format!("{}{after}", opt.completable()).replace(SEPARATOR, MAIN_SEPARATOR_STR)
};
let snap = self.snap_mut();

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,9 +1,8 @@
use anyhow::Result;
use yazi_macro::{render, succ};
use yazi_parser::input::MoveOpt;
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 {
pub fn r#move(&mut self, opt: MoveOpt) -> Result<Data> {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
use std::{error::Error, fmt::{self, Display}};
use crate::Id;
use yazi_shared::Id;
#[derive(Debug)]
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 mlua::{ExternalError, FromLua, IntoLua, Lua, Value};
use yazi_shared::{Id, event::CmdCow};
use std::path::MAIN_SEPARATOR_STR;
use crate::cmp::CmpItem;
use mlua::{ExternalError, FromLua, IntoLua, Lua, Value};
use yazi_shared::{Id, event::CmdCow, strand::{StrandBuf, StrandLike}};
#[derive(Debug)]
pub struct CompleteOpt {
pub item: CmpItem,
pub name: StrandBuf,
pub is_dir: bool,
pub ticket: Id,
}
@ -14,11 +14,11 @@ impl TryFrom<CmdCow> for CompleteOpt {
type Error = anyhow::Error;
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
let Some(item) = c.take_any("item") else {
bail!("Invalid 'item' in CompleteOpt");
};
Ok(Self { item, ticket: c.get("ticket").unwrap_or_default() })
Ok(Self {
name: c.take("name")?,
is_dir: c.bool("is_dir"),
ticket: c.get("ticket").unwrap_or_default(),
})
}
}
@ -29,3 +29,9 @@ impl FromLua for CompleteOpt {
impl IntoLua for CompleteOpt {
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
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);

View file

@ -1,5 +1,5 @@
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); }

View file

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