mirror of
https://github.com/sxyazi/yazi.git
synced 2026-05-13 08:16:40 +00:00
refactor: invert the dependency relationship between yazi-parser and yazi-proxy (#2992)
This commit is contained in:
parent
548bb0d063
commit
5f8a1496fe
77 changed files with 640 additions and 544 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
|
@ -600,7 +600,7 @@ dependencies = [
|
|||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"rustix 1.0.7",
|
||||
"rustix 1.0.8",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
|
|
@ -2256,15 +2256,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.0.7"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
|
||||
checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.9.4",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3135,7 +3135,7 @@ checksum = "24d643ce3fd3e5b54854602a080f34fb10ab75e0b813ee32d00ca2b44fa74762"
|
|||
dependencies = [
|
||||
"either",
|
||||
"env_home",
|
||||
"rustix 1.0.7",
|
||||
"rustix 1.0.8",
|
||||
"winsafe",
|
||||
]
|
||||
|
||||
|
|
@ -3545,7 +3545,6 @@ dependencies = [
|
|||
"yazi-config",
|
||||
"yazi-fs",
|
||||
"yazi-macro",
|
||||
"yazi-proxy",
|
||||
"yazi-shared",
|
||||
]
|
||||
|
||||
|
|
@ -3776,7 +3775,6 @@ dependencies = [
|
|||
"yazi-dds",
|
||||
"yazi-fs",
|
||||
"yazi-macro",
|
||||
"yazi-proxy",
|
||||
"yazi-shared",
|
||||
]
|
||||
|
||||
|
|
@ -3833,6 +3831,7 @@ dependencies = [
|
|||
"tokio",
|
||||
"yazi-config",
|
||||
"yazi-macro",
|
||||
"yazi-parser",
|
||||
"yazi-shared",
|
||||
]
|
||||
|
||||
|
|
@ -3866,6 +3865,7 @@ name = "yazi-shared"
|
|||
version = "25.6.11"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.9.1",
|
||||
"crossterm 0.29.0",
|
||||
"foldhash",
|
||||
"futures",
|
||||
|
|
|
|||
12
flake.lock
generated
12
flake.lock
generated
|
|
@ -20,11 +20,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1747312588,
|
||||
"narHash": "sha256-MmJvj6mlWzeRwKGLcwmZpKaOPZ5nJb/6al5CXqJsgjo=",
|
||||
"lastModified": 1752596105,
|
||||
"narHash": "sha256-lFNVsu/mHLq3q11MuGkMhUUoSXEdQjCHvpReaGP1S2k=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b1bebd0fe266bbd1820019612ead889e96a8fa2d",
|
||||
"rev": "dab3a6e781554f965bde3def0aa2fda4eb8f1708",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -48,11 +48,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1747363019,
|
||||
"narHash": "sha256-N4dwkRBmpOosa4gfFkFf/LTD8oOcNkAyvZ07JvRDEf0=",
|
||||
"lastModified": 1752633862,
|
||||
"narHash": "sha256-Bj7ozT1+5P7NmvDcuAXJvj56txcXuAhk3Vd9FdWFQzk=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "0e624f2b1972a34be1a9b35290ed18ea4b419b6f",
|
||||
"rev": "8668ca94858206ac3db0860a9dec471de0d995f8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ use std::{mem, ops::ControlFlow};
|
|||
|
||||
use anyhow::Result;
|
||||
use yazi_macro::{render, succ};
|
||||
use yazi_parser::cmp::ShowOpt;
|
||||
use yazi_proxy::options::CmpItem;
|
||||
use yazi_parser::cmp::{CmpItem, ShowOpt};
|
||||
use yazi_shared::{event::Data, osstr_contains, osstr_starts_with};
|
||||
|
||||
use crate::{Actor, Ctx};
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@ use anyhow::Result;
|
|||
use tokio::fs;
|
||||
use yazi_fs::{CWD, expand_path};
|
||||
use yazi_macro::{act, emit, render, succ};
|
||||
use yazi_parser::cmp::{ShowOpt, TriggerOpt};
|
||||
use yazi_proxy::options::CmpItem;
|
||||
use yazi_parser::cmp::{CmpItem, ShowOpt, TriggerOpt};
|
||||
use yazi_shared::{event::{Cmd, Data}, natsort};
|
||||
|
||||
use crate::{Actor, Ctx};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::ops::{Deref, DerefMut};
|
|||
use anyhow::{Result, anyhow};
|
||||
use yazi_core::{Core, mgr::Tabs, tab::{Folder, Tab}, tasks::Tasks};
|
||||
use yazi_fs::File;
|
||||
use yazi_shared::{Id, url::Url};
|
||||
use yazi_shared::{event::Cmd, url::Url};
|
||||
|
||||
pub struct Ctx<'a> {
|
||||
pub core: &'a mut Core,
|
||||
|
|
@ -24,8 +24,8 @@ impl DerefMut for Ctx<'_> {
|
|||
|
||||
impl<'a> Ctx<'a> {
|
||||
#[inline]
|
||||
pub fn new(core: &'a mut Core, tab: Option<Id>) -> Result<Self> {
|
||||
let tab = if let Some(id) = tab {
|
||||
pub fn new(core: &'a mut Core, cmd: &Cmd) -> Result<Self> {
|
||||
let tab = if let Some(id) = cmd.id("tab") {
|
||||
core
|
||||
.mgr
|
||||
.tabs
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#![allow(clippy::if_same_then_else, clippy::option_map_unit_fn)]
|
||||
|
||||
extern crate self as yazi_actor;
|
||||
|
||||
yazi_macro::mod_pub!(cmp confirm help input mgr pick spot tasks which);
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ use yazi_config::{YAZI, popup::PickCfg};
|
|||
use yazi_core::tab::Folder;
|
||||
use yazi_fs::File;
|
||||
use yazi_macro::{act, succ};
|
||||
use yazi_parser::mgr::OpenOpt;
|
||||
use yazi_parser::mgr::{OpenDoOpt, OpenOpt};
|
||||
use yazi_plugin::isolate;
|
||||
use yazi_proxy::{MgrProxy, PickProxy, TasksProxy, options::OpenDoOpt};
|
||||
use yazi_proxy::{MgrProxy, PickProxy, TasksProxy};
|
||||
use yazi_shared::{MIME_DIR, event::{CmdCow, Data}, url::Url};
|
||||
|
||||
use crate::{Actor, Ctx, mgr::Quit};
|
||||
|
|
|
|||
|
|
@ -6,8 +6,9 @@ use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
|
|||
use yazi_config::popup::InputCfg;
|
||||
use yazi_fs::{FilesOp, cha::Cha};
|
||||
use yazi_macro::{act, succ};
|
||||
use yazi_parser::mgr::{SearchOpt, SearchOptVia};
|
||||
use yazi_plugin::external;
|
||||
use yazi_proxy::{InputProxy, MgrProxy, options::{SearchOpt, SearchOptVia}};
|
||||
use yazi_proxy::{InputProxy, MgrProxy};
|
||||
use yazi_shared::event::Data;
|
||||
|
||||
use crate::{Actor, Ctx};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use anyhow::Result;
|
||||
use yazi_macro::succ;
|
||||
use yazi_proxy::options::OpenWithOpt;
|
||||
use yazi_parser::mgr::OpenWithOpt;
|
||||
use yazi_shared::event::Data;
|
||||
|
||||
use crate::{Actor, Ctx};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use anyhow::Result;
|
||||
use yazi_macro::succ;
|
||||
use yazi_proxy::options::ProcessExecOpt;
|
||||
use yazi_parser::tasks::ProcessExecOpt;
|
||||
use yazi_shared::event::Data;
|
||||
|
||||
use crate::{Actor, Ctx};
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@ impl Dimension {
|
|||
_ = mem::replace(&mut size, s);
|
||||
}
|
||||
|
||||
if size.columns == 0 || size.rows == 0 {
|
||||
if let Ok((cols, rows)) = crossterm::terminal::size() {
|
||||
size.columns = cols;
|
||||
size.rows = rows;
|
||||
}
|
||||
if (size.columns == 0 || size.rows == 0)
|
||||
&& let Ok((cols, rows)) = crossterm::terminal::size()
|
||||
{
|
||||
size.columns = cols;
|
||||
size.rows = rows;
|
||||
}
|
||||
|
||||
size.into()
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ yazi-adapter = { path = "../yazi-adapter", version = "25.6.11" }
|
|||
yazi-config = { path = "../yazi-config", version = "25.6.11" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
|
||||
# External dependencies
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
use foldhash::HashMap;
|
||||
use mlua::{IntoLua, Lua, MetaMethod, UserData, UserDataMethods, Value};
|
||||
use mlua::{Lua, MetaMethod, UserData, UserDataMethods, Value};
|
||||
|
||||
pub type ComposerGet = fn(&Lua, &[u8]) -> mlua::Result<Value>;
|
||||
pub type ComposerSet = fn(&Lua, &[u8], Value) -> mlua::Result<Value>;
|
||||
|
||||
pub struct Composer<G, S> {
|
||||
get: G,
|
||||
set: S,
|
||||
cache: HashMap<Vec<u8>, Value>,
|
||||
get: G,
|
||||
set: S,
|
||||
parent: Option<(G, S)>,
|
||||
cache: HashMap<Vec<u8>, Value>,
|
||||
}
|
||||
|
||||
impl<G, S> Composer<G, S>
|
||||
|
|
@ -12,8 +16,12 @@ where
|
|||
G: Fn(&Lua, &[u8]) -> mlua::Result<Value> + 'static,
|
||||
S: Fn(&Lua, &[u8], Value) -> mlua::Result<Value> + 'static,
|
||||
{
|
||||
pub fn make(lua: &Lua, get: G, set: S) -> mlua::Result<Value> {
|
||||
Self { get, set, cache: Default::default() }.into_lua(lua)
|
||||
#[inline]
|
||||
pub fn new(get: G, set: S) -> Self { Self { get, set, parent: None, cache: Default::default() } }
|
||||
|
||||
#[inline]
|
||||
pub fn with_parent(get: G, set: S, p_get: G, p_set: S) -> Self {
|
||||
Self { get, set, parent: Some((p_get, p_set)), cache: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -29,19 +37,30 @@ where
|
|||
return Ok(v.clone());
|
||||
}
|
||||
|
||||
let v = (me.get)(lua, &key)?;
|
||||
me.cache.insert(key.to_owned(), v.clone());
|
||||
Ok(v)
|
||||
let mut value = (me.get)(lua, &key)?;
|
||||
if value.is_nil()
|
||||
&& let Some((p_get, _)) = &me.parent
|
||||
{
|
||||
value = p_get(lua, &key)?;
|
||||
}
|
||||
|
||||
me.cache.insert(key.to_owned(), value.clone());
|
||||
Ok(value)
|
||||
});
|
||||
|
||||
methods.add_meta_method_mut(
|
||||
MetaMethod::NewIndex,
|
||||
|lua, me, (key, value): (mlua::String, Value)| {
|
||||
let key = key.as_bytes();
|
||||
|
||||
let value = (me.set)(lua, key.as_ref(), value)?;
|
||||
|
||||
if value.is_nil() {
|
||||
me.cache.remove(key.as_ref());
|
||||
} else if let Some((_, p_set)) = &me.parent {
|
||||
match p_set(lua, key.as_ref(), value)? {
|
||||
Value::Nil => me.cache.remove(key.as_ref()),
|
||||
v => me.cache.insert(key.to_owned(), v),
|
||||
};
|
||||
} else {
|
||||
me.cache.insert(key.to_owned(), value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ use mlua::{AnyUserData, IntoLua, Lua, Value};
|
|||
use tracing::error;
|
||||
|
||||
use super::Renderable;
|
||||
use crate::Composer;
|
||||
use crate::{Composer, ComposerGet, ComposerSet};
|
||||
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
pub fn compose(p_get: ComposerGet, p_set: ComposerSet) -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
match key {
|
||||
b"Align" => super::Align::compose(lua)?,
|
||||
|
|
@ -26,13 +26,6 @@ pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
|||
b"Table" => super::Table::compose(lua)?,
|
||||
b"Text" => super::Text::compose(lua)?,
|
||||
b"Wrap" => super::Wrap::compose(lua)?,
|
||||
|
||||
b"area" => super::Utils::area(lua)?,
|
||||
b"hide" => super::Utils::hide(lua)?,
|
||||
b"width" => super::Utils::width(lua)?,
|
||||
b"redraw" => super::Utils::redraw(lua)?,
|
||||
b"render" => super::Utils::render(lua)?,
|
||||
b"truncate" => super::Utils::truncate(lua)?,
|
||||
_ => return Ok(Value::Nil),
|
||||
}
|
||||
.into_lua(lua)
|
||||
|
|
@ -40,7 +33,7 @@ pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::with_parent(get, set, p_get, p_set)
|
||||
}
|
||||
|
||||
pub fn render_once<F>(value: Value, buf: &mut ratatui::buffer::Buffer, trans: F)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{borrow::Cow, mem};
|
||||
use std::{borrow::Cow, mem, ops::{Deref, DerefMut}};
|
||||
|
||||
use ansi_to_tui::IntoText;
|
||||
use mlua::{AnyUserData, ExternalError, ExternalResult, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
|
||||
|
|
@ -17,6 +17,16 @@ pub struct Line {
|
|||
pub(super) inner: ratatui::text::Line<'static>,
|
||||
}
|
||||
|
||||
impl Deref for Line {
|
||||
type Target = ratatui::text::Line<'static>;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
|
||||
impl DerefMut for Line {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner }
|
||||
}
|
||||
|
||||
impl Line {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
let new = lua.create_function(|_, (_, value): (Table, Value)| Line::try_from(value))?;
|
||||
|
|
@ -101,23 +111,23 @@ impl From<Line> for ratatui::text::Line<'static> {
|
|||
impl UserData for Line {
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
crate::impl_area_method!(methods);
|
||||
crate::impl_style_method!(methods, inner.style);
|
||||
crate::impl_style_shorthands!(methods, inner.style);
|
||||
crate::impl_style_method!(methods, style);
|
||||
crate::impl_style_shorthands!(methods, style);
|
||||
|
||||
methods.add_method("width", |_, me, ()| Ok(me.inner.width()));
|
||||
methods.add_method("width", |_, me, ()| Ok(me.width()));
|
||||
methods.add_function_mut("align", |_, (ud, align): (AnyUserData, Align)| {
|
||||
ud.borrow_mut::<Self>()?.inner.alignment = Some(align.0);
|
||||
ud.borrow_mut::<Self>()?.alignment = Some(align.0);
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_method("visible", |_, me, ()| {
|
||||
Ok(me.inner.iter().flat_map(|s| s.content.chars()).any(|c| c.width().unwrap_or(0) > 0))
|
||||
Ok(me.iter().flat_map(|s| s.content.chars()).any(|c| c.width().unwrap_or(0) > 0))
|
||||
});
|
||||
methods.add_function_mut("truncate", |_, (ud, t): (AnyUserData, Table)| {
|
||||
let mut me = ud.borrow_mut::<Self>()?;
|
||||
|
||||
let max = t.raw_get("max")?;
|
||||
if max < 1 {
|
||||
me.inner.spans.clear();
|
||||
me.spans.clear();
|
||||
return Ok(ud);
|
||||
}
|
||||
|
||||
|
|
@ -151,8 +161,7 @@ impl UserData for Line {
|
|||
traverse(
|
||||
max,
|
||||
max - ellipsis.0,
|
||||
me.inner
|
||||
.iter()
|
||||
me.iter()
|
||||
.enumerate()
|
||||
.rev()
|
||||
.flat_map(|(x, s)| s.content.char_indices().rev().map(move |(y, c)| (x, y, c))),
|
||||
|
|
@ -161,23 +170,22 @@ impl UserData for Line {
|
|||
traverse(
|
||||
max,
|
||||
max - ellipsis.0,
|
||||
me.inner
|
||||
.iter()
|
||||
me.iter()
|
||||
.enumerate()
|
||||
.flat_map(|(x, s)| s.content.char_indices().map(move |(y, c)| (x, y, c))),
|
||||
)
|
||||
};
|
||||
|
||||
let Some((x, y, width)) = cut else {
|
||||
me.inner.spans.clear();
|
||||
me.inner.spans.push(ellipsis.1);
|
||||
me.spans.clear();
|
||||
me.spans.push(ellipsis.1);
|
||||
return Ok(ud);
|
||||
};
|
||||
if !remain {
|
||||
return Ok(ud);
|
||||
}
|
||||
|
||||
let spans = &mut me.inner.spans;
|
||||
let spans = &mut me.spans;
|
||||
let len = match (rtl, width == max) {
|
||||
(a, b) if a == b => spans[x].content[y..].chars().next().map_or(0, |c| c.len_utf8()),
|
||||
_ => 0,
|
||||
|
|
@ -219,7 +227,7 @@ mod tests {
|
|||
.call(())
|
||||
.unwrap();
|
||||
|
||||
line.inner.spans.iter().map(|s| s.content.as_ref()).collect()
|
||||
line.spans.iter().map(|s| s.content.as_ref()).collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
#![allow(clippy::module_inception)]
|
||||
|
||||
yazi_macro::mod_flat!(align area bar border cell clear constraint edge elements gauge layout line list pad pos rect renderable row span table text utils wrap);
|
||||
yazi_macro::mod_flat!(align area bar border cell clear constraint edge elements gauge layout line list pad pos rect renderable row span table text wrap);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use super::Pad;
|
|||
use crate::deprecate;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, FromLua)]
|
||||
pub struct Rect(pub(super) ratatui::layout::Rect);
|
||||
pub struct Rect(pub ratatui::layout::Rect);
|
||||
|
||||
impl Deref for Rect {
|
||||
type Target = ratatui::layout::Rect;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::borrow::Cow;
|
||||
use std::{borrow::Cow, ops::{Deref, DerefMut}};
|
||||
|
||||
use mlua::{AnyUserData, ExternalError, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
|
||||
use unicode_width::UnicodeWidthChar;
|
||||
|
|
@ -7,6 +7,16 @@ const EXPECTED: &str = "expected a string or Span";
|
|||
|
||||
pub struct Span(pub(super) ratatui::text::Span<'static>);
|
||||
|
||||
impl Deref for Span {
|
||||
type Target = ratatui::text::Span<'static>;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.0 }
|
||||
}
|
||||
|
||||
impl DerefMut for Span {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
|
||||
}
|
||||
|
||||
impl Span {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
let new = lua.create_function(|_, (_, value): (Table, Value)| Span::try_from(value))?;
|
||||
|
|
|
|||
|
|
@ -1,244 +0,0 @@
|
|||
use mlua::{AnyUserData, ExternalError, IntoLua, Lua, ObjectLike, Table, Value};
|
||||
use tracing::error;
|
||||
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
|
||||
use yazi_config::LAYOUT;
|
||||
use yazi_macro::render;
|
||||
use yazi_proxy::{AppProxy, HIDER};
|
||||
|
||||
use super::{Line, Rect, Span};
|
||||
use crate::{Permit, PermitRef};
|
||||
|
||||
pub(super) struct Utils;
|
||||
|
||||
impl Utils {
|
||||
pub(super) fn area(lua: &Lua) -> mlua::Result<Value> {
|
||||
let f = lua.create_function(|_, s: mlua::String| {
|
||||
let layout = LAYOUT.get();
|
||||
Ok(match s.as_bytes().as_ref() {
|
||||
b"current" => Rect(layout.current),
|
||||
b"preview" => Rect(layout.preview),
|
||||
b"progress" => Rect(layout.progress),
|
||||
_ => Err(format!("unknown area: {}", s.display()).into_lua_err())?,
|
||||
})
|
||||
})?;
|
||||
|
||||
f.into_lua(lua)
|
||||
}
|
||||
|
||||
pub(super) fn hide(lua: &Lua) -> mlua::Result<Value> {
|
||||
let f = lua.create_async_function(|lua, ()| async move {
|
||||
if lua.named_registry_value::<PermitRef<fn()>>("HIDE_PERMIT").is_ok_and(|h| h.is_some()) {
|
||||
return Err("Cannot hide while already hidden".into_lua_err());
|
||||
}
|
||||
|
||||
let permit = HIDER.acquire().await.unwrap();
|
||||
AppProxy::stop().await;
|
||||
|
||||
lua.set_named_registry_value("HIDE_PERMIT", Permit::new(permit, AppProxy::resume as fn()))?;
|
||||
lua.named_registry_value::<AnyUserData>("HIDE_PERMIT")
|
||||
})?;
|
||||
|
||||
f.into_lua(lua)
|
||||
}
|
||||
|
||||
pub(super) fn width(lua: &Lua) -> mlua::Result<Value> {
|
||||
let f = lua.create_function(|_, v: Value| match v {
|
||||
Value::String(s) => {
|
||||
let (mut acc, b) = (0, s.as_bytes());
|
||||
for c in b.utf8_chunks() {
|
||||
acc += c.valid().width();
|
||||
if !c.invalid().is_empty() {
|
||||
acc += 1;
|
||||
}
|
||||
}
|
||||
Ok(acc)
|
||||
}
|
||||
Value::UserData(ud) => {
|
||||
if let Ok(line) = ud.borrow::<Line>() {
|
||||
Ok(line.inner.width())
|
||||
} else if let Ok(span) = ud.borrow::<Span>() {
|
||||
Ok(span.0.width())
|
||||
} else {
|
||||
Err("expected a string, Line, or Span".into_lua_err())?
|
||||
}
|
||||
}
|
||||
_ => Err("expected a string, Line, or Span".into_lua_err())?,
|
||||
})?;
|
||||
|
||||
f.into_lua(lua)
|
||||
}
|
||||
|
||||
pub(super) fn redraw(lua: &Lua) -> mlua::Result<Value> {
|
||||
let f = lua.create_function(|lua, c: Table| {
|
||||
let id: mlua::String = c.get("_id")?;
|
||||
|
||||
let mut layout = LAYOUT.get();
|
||||
match id.as_bytes().as_ref() {
|
||||
b"current" => layout.current = *c.raw_get::<crate::elements::Rect>("_area")?,
|
||||
b"preview" => layout.preview = *c.raw_get::<crate::elements::Rect>("_area")?,
|
||||
b"progress" => layout.progress = *c.raw_get::<crate::elements::Rect>("_area")?,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
LAYOUT.set(layout);
|
||||
match c.call_method::<Value>("redraw", ())? {
|
||||
Value::Table(tbl) => Ok(tbl),
|
||||
Value::UserData(ud) => lua.create_sequence_from([ud]),
|
||||
_ => {
|
||||
error!(
|
||||
"Failed to `redraw()` the `{}` component: expected a table or UserData",
|
||||
id.display(),
|
||||
);
|
||||
lua.create_table()
|
||||
}
|
||||
}
|
||||
})?;
|
||||
|
||||
f.into_lua(lua)
|
||||
}
|
||||
|
||||
pub(super) fn render(lua: &Lua) -> mlua::Result<Value> {
|
||||
let f = lua.create_function(|_, ()| {
|
||||
render!();
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
f.into_lua(lua)
|
||||
}
|
||||
|
||||
pub(super) fn truncate(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn traverse(
|
||||
it: impl Iterator<Item = (usize, char)>,
|
||||
max: usize,
|
||||
) -> (Option<usize>, usize, bool) {
|
||||
let (mut adv, mut last) = (0, 0);
|
||||
let idx = it
|
||||
.take_while(|&(_, c)| {
|
||||
(last, adv) = (adv, adv + c.width().unwrap_or(0));
|
||||
adv <= max
|
||||
})
|
||||
.map(|(i, _)| i)
|
||||
.last();
|
||||
(idx, last, adv > max)
|
||||
}
|
||||
|
||||
let f = lua.create_function(|lua, (s, t): (mlua::String, Table)| {
|
||||
let b = s.as_bytes();
|
||||
if b.is_empty() {
|
||||
return Ok(s);
|
||||
}
|
||||
|
||||
let max = t.raw_get("max")?;
|
||||
if b.len() <= max {
|
||||
return Ok(s);
|
||||
} else if max < 1 {
|
||||
return lua.create_string("");
|
||||
}
|
||||
|
||||
let lossy = String::from_utf8_lossy(&b);
|
||||
let rtl = t.raw_get("rtl").unwrap_or(false);
|
||||
let (idx, width, remain) = if rtl {
|
||||
traverse(lossy.char_indices().rev(), max)
|
||||
} else {
|
||||
traverse(lossy.char_indices(), max)
|
||||
};
|
||||
|
||||
let Some(idx) = idx else { return lua.create_string("…") };
|
||||
if !remain {
|
||||
return Ok(s);
|
||||
}
|
||||
|
||||
let result: Vec<_> = match (rtl, width == max) {
|
||||
(false, false) => {
|
||||
let len = lossy[idx..].chars().next().map_or(0, |c| c.len_utf8());
|
||||
lossy[..idx + len].bytes().chain("…".bytes()).collect()
|
||||
}
|
||||
(false, true) => lossy[..idx].bytes().chain("…".bytes()).collect(),
|
||||
(true, false) => "…".bytes().chain(lossy[idx..].bytes()).collect(),
|
||||
(true, true) => {
|
||||
let len = lossy[idx..].chars().next().map_or(0, |c| c.len_utf8());
|
||||
"…".bytes().chain(lossy[idx + len..].bytes()).collect()
|
||||
}
|
||||
};
|
||||
lua.create_string(result)
|
||||
})?;
|
||||
|
||||
f.into_lua(lua)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use mlua::chunk;
|
||||
|
||||
use super::*;
|
||||
|
||||
fn truncate(s: &str, max: usize, rtl: bool) -> String {
|
||||
let lua = Lua::new();
|
||||
let f = Utils::truncate(&lua).unwrap();
|
||||
|
||||
lua
|
||||
.load(chunk! {
|
||||
return $f($s, { max = $max, rtl = $rtl })
|
||||
})
|
||||
.call(())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate() {
|
||||
assert_eq!(truncate("你好,world", 0, false), "");
|
||||
assert_eq!(truncate("你好,world", 1, false), "…");
|
||||
assert_eq!(truncate("你好,world", 2, false), "…");
|
||||
|
||||
assert_eq!(truncate("你好,世界", 3, false), "你…");
|
||||
assert_eq!(truncate("你好,世界", 4, false), "你…");
|
||||
assert_eq!(truncate("你好,世界", 5, false), "你好…");
|
||||
|
||||
assert_eq!(truncate("Hello, world", 5, false), "Hell…");
|
||||
assert_eq!(truncate("Ni好,世界", 3, false), "Ni…");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate_rtl() {
|
||||
assert_eq!(truncate("world,你好", 0, true), "");
|
||||
assert_eq!(truncate("world,你好", 1, true), "…");
|
||||
assert_eq!(truncate("world,你好", 2, true), "…");
|
||||
|
||||
assert_eq!(truncate("你好,世界", 3, true), "…界");
|
||||
assert_eq!(truncate("你好,世界", 4, true), "…界");
|
||||
assert_eq!(truncate("你好,世界", 5, true), "…世界");
|
||||
|
||||
assert_eq!(truncate("Hello, world", 5, true), "…orld");
|
||||
assert_eq!(truncate("你好,Shi界", 3, true), "…界");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate_oboe() {
|
||||
assert_eq!(truncate("Hello, world", 11, false), "Hello, wor…");
|
||||
assert_eq!(truncate("你好,世界", 9, false), "你好,世…");
|
||||
assert_eq!(truncate("你好,世Jie", 9, false), "你好,世…");
|
||||
|
||||
assert_eq!(truncate("Hello, world", 11, true), "…llo, world");
|
||||
assert_eq!(truncate("你好,世界", 9, true), "…好,世界");
|
||||
assert_eq!(truncate("Ni好,世界", 9, true), "…好,世界");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate_exact() {
|
||||
assert_eq!(truncate("Hello, world", 12, false), "Hello, world");
|
||||
assert_eq!(truncate("你好,世界", 10, false), "你好,世界");
|
||||
|
||||
assert_eq!(truncate("Hello, world", 12, true), "Hello, world");
|
||||
assert_eq!(truncate("你好,世界", 10, true), "你好,世界");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate_overflow() {
|
||||
assert_eq!(truncate("Hello, world", 13, false), "Hello, world");
|
||||
assert_eq!(truncate("你好,世界", 11, false), "你好,世界");
|
||||
|
||||
assert_eq!(truncate("Hello, world", 13, true), "Hello, world");
|
||||
assert_eq!(truncate("你好,世界", 11, true), "你好,世界");
|
||||
}
|
||||
}
|
||||
|
|
@ -17,11 +17,16 @@ macro_rules! runtime_mut {
|
|||
#[macro_export]
|
||||
macro_rules! deprecate {
|
||||
($lua:ident, $tt:tt) => {{
|
||||
let id = match $crate::runtime!($lua)?.current() {
|
||||
Some(id) => &format!("`{id}.yazi` plugin"),
|
||||
None => "`init.lua` config",
|
||||
};
|
||||
yazi_proxy::deprecate!(format!($tt, id));
|
||||
static WARNED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
|
||||
if !WARNED.swap(true, std::sync::atomic::Ordering::Relaxed) {
|
||||
let id = match $crate::runtime!($lua)?.current() {
|
||||
Some(id) => &format!("`{id}.yazi` plugin"),
|
||||
None => "`init.lua` config",
|
||||
};
|
||||
yazi_macro::emit!(Call(
|
||||
yazi_shared::event::Cmd::new("app:deprecate").with("content", format!($tt, id))
|
||||
));
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ async fn main() -> ExitCode {
|
|||
Ok(()) => ExitCode::SUCCESS,
|
||||
Err(e) => {
|
||||
for cause in e.chain() {
|
||||
if let Some(ioerr) = cause.downcast_ref::<std::io::Error>() {
|
||||
if ioerr.kind() == std::io::ErrorKind::BrokenPipe {
|
||||
return ExitCode::from(0);
|
||||
}
|
||||
if let Some(ioerr) = cause.downcast_ref::<std::io::Error>()
|
||||
&& ioerr.kind() == std::io::ErrorKind::BrokenPipe
|
||||
{
|
||||
return ExitCode::from(0);
|
||||
}
|
||||
}
|
||||
errln!("{e:#}").ok();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
use yazi_proxy::options::CmpItem;
|
||||
use yazi_parser::cmp::CmpItem;
|
||||
use yazi_shared::Id;
|
||||
use yazi_widgets::Scrollable;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::time::{Duration, Instant};
|
||||
|
||||
use yazi_proxy::{AppProxy, options::NotifyOpt};
|
||||
use yazi_parser::app::NotifyOpt;
|
||||
use yazi_proxy::AppProxy;
|
||||
|
||||
use crate::notify::{Message, Notify};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::time::{Duration, Instant};
|
||||
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
use yazi_proxy::options::{NotifyLevel, NotifyOpt};
|
||||
use yazi_parser::app::{NotifyLevel, NotifyOpt};
|
||||
|
||||
use super::NOTIFY_BORDER;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use yazi_proxy::options::PluginOpt;
|
||||
use yazi_parser::app::PluginOpt;
|
||||
|
||||
use super::Tasks;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::{borrow::Cow, collections::HashMap, ffi::OsString, mem};
|
||||
|
||||
use yazi_config::{YAZI, opener::OpenerRule};
|
||||
use yazi_proxy::options::ProcessExecOpt;
|
||||
use yazi_parser::tasks::ProcessExecOpt;
|
||||
use yazi_shared::url::Url;
|
||||
|
||||
use super::Tasks;
|
||||
|
|
|
|||
|
|
@ -92,10 +92,10 @@ impl Server {
|
|||
let Ok(payload) = Payload::from_str(&s) else { return };
|
||||
let Body::Hi(hi) = payload.body else { return };
|
||||
|
||||
if id.is_none() {
|
||||
if let Some(ref state) = *STATE.read() {
|
||||
state.values().for_each(|s| _ = tx.send(s.clone()));
|
||||
}
|
||||
if id.is_none()
|
||||
&& let Some(ref state) = *STATE.read()
|
||||
{
|
||||
state.values().for_each(|s| _ = tx.send(s.clone()));
|
||||
}
|
||||
|
||||
let mut clients = CLIENTS.write();
|
||||
|
|
|
|||
17
yazi-fm/src/app/commands/deprecate.rs
Normal file
17
yazi-fm/src/app/commands/deprecate.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
use anyhow::Result;
|
||||
use yazi_macro::succ;
|
||||
use yazi_parser::app::{DeprecateOpt, NotifyLevel, NotifyOpt};
|
||||
use yazi_shared::event::Data;
|
||||
|
||||
use crate::app::App;
|
||||
|
||||
impl App {
|
||||
pub(crate) fn deprecate(&mut self, opt: DeprecateOpt) -> Result<Data> {
|
||||
succ!(self.core.notify.push(NotifyOpt {
|
||||
title: "Deprecated API".to_owned(),
|
||||
content: opt.content,
|
||||
level: NotifyLevel::Warn,
|
||||
timeout: std::time::Duration::from_secs(20),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
yazi_macro::mod_flat!(
|
||||
accept_payload
|
||||
bootstrap
|
||||
deprecate
|
||||
mouse
|
||||
notify
|
||||
plugin
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use anyhow::Result;
|
||||
use yazi_macro::succ;
|
||||
use yazi_proxy::options::NotifyOpt;
|
||||
use yazi_parser::app::NotifyOpt;
|
||||
use yazi_shared::event::Data;
|
||||
|
||||
use crate::app::App;
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ use tracing::{error, warn};
|
|||
use yazi_binding::runtime_mut;
|
||||
use yazi_dds::Sendable;
|
||||
use yazi_macro::succ;
|
||||
use yazi_parser::app::{PluginMode, PluginOpt};
|
||||
use yazi_plugin::{LUA, loader::{LOADER, Loader}};
|
||||
use yazi_proxy::{AppProxy, options::{PluginMode, PluginOpt}};
|
||||
use yazi_proxy::AppProxy;
|
||||
use yazi_shared::event::Data;
|
||||
|
||||
use crate::{app::App, lives::Lives};
|
||||
|
|
|
|||
|
|
@ -48,12 +48,13 @@ impl<'a> Executor<'a> {
|
|||
on!(resize);
|
||||
on!(stop);
|
||||
on!(resume);
|
||||
on!(deprecate);
|
||||
|
||||
succ!();
|
||||
}
|
||||
|
||||
fn mgr(&mut self, cmd: CmdCow) -> Result<Data> {
|
||||
let cx = &mut Ctx::new(&mut self.app.core, cmd.id("tab"))?;
|
||||
let cx = &mut Ctx::new(&mut self.app.core, &cmd)?;
|
||||
|
||||
macro_rules! on {
|
||||
($name:ident) => {
|
||||
|
|
@ -143,7 +144,7 @@ impl<'a> Executor<'a> {
|
|||
}
|
||||
|
||||
fn tasks(&mut self, cmd: CmdCow) -> Result<Data> {
|
||||
let cx = &mut Ctx::new(&mut self.app.core, cmd.id("tab"))?;
|
||||
let cx = &mut Ctx::new(&mut self.app.core, &cmd)?;
|
||||
|
||||
macro_rules! on {
|
||||
($name:ident) => {
|
||||
|
|
@ -171,7 +172,7 @@ impl<'a> Executor<'a> {
|
|||
}
|
||||
|
||||
fn spot(&mut self, cmd: CmdCow) -> Result<Data> {
|
||||
let cx = &mut Ctx::new(&mut self.app.core, cmd.id("tab"))?;
|
||||
let cx = &mut Ctx::new(&mut self.app.core, &cmd)?;
|
||||
|
||||
macro_rules! on {
|
||||
($name:ident) => {
|
||||
|
|
@ -196,7 +197,7 @@ impl<'a> Executor<'a> {
|
|||
}
|
||||
|
||||
fn pick(&mut self, cmd: CmdCow) -> Result<Data> {
|
||||
let cx = &mut Ctx::new(&mut self.app.core, cmd.id("tab"))?;
|
||||
let cx = &mut Ctx::new(&mut self.app.core, &cmd)?;
|
||||
|
||||
macro_rules! on {
|
||||
($name:ident) => {
|
||||
|
|
@ -221,7 +222,7 @@ impl<'a> Executor<'a> {
|
|||
|
||||
fn input(&mut self, cmd: CmdCow) -> Result<Data> {
|
||||
let mode = self.app.core.input.mode();
|
||||
let cx = &mut Ctx::new(&mut self.app.core, cmd.id("tab"))?;
|
||||
let cx = &mut Ctx::new(&mut self.app.core, &cmd)?;
|
||||
|
||||
macro_rules! on {
|
||||
($name:ident) => {
|
||||
|
|
@ -252,7 +253,7 @@ impl<'a> Executor<'a> {
|
|||
}
|
||||
|
||||
fn confirm(&mut self, cmd: CmdCow) -> Result<Data> {
|
||||
let cx = &mut Ctx::new(&mut self.app.core, cmd.id("tab"))?;
|
||||
let cx = &mut Ctx::new(&mut self.app.core, &cmd)?;
|
||||
|
||||
macro_rules! on {
|
||||
($name:ident) => {
|
||||
|
|
@ -270,7 +271,7 @@ impl<'a> Executor<'a> {
|
|||
}
|
||||
|
||||
fn help(&mut self, cmd: CmdCow) -> Result<Data> {
|
||||
let cx = &mut Ctx::new(&mut self.app.core, cmd.id("tab"))?;
|
||||
let cx = &mut Ctx::new(&mut self.app.core, &cmd)?;
|
||||
|
||||
macro_rules! on {
|
||||
($name:ident) => {
|
||||
|
|
@ -294,7 +295,7 @@ impl<'a> Executor<'a> {
|
|||
}
|
||||
|
||||
fn cmp(&mut self, cmd: CmdCow) -> Result<Data> {
|
||||
let cx = &mut Ctx::new(&mut self.app.core, cmd.id("tab"))?;
|
||||
let cx = &mut Ctx::new(&mut self.app.core, &cmd)?;
|
||||
|
||||
macro_rules! on {
|
||||
($name:ident) => {
|
||||
|
|
@ -319,7 +320,7 @@ impl<'a> Executor<'a> {
|
|||
}
|
||||
|
||||
fn which(&mut self, cmd: CmdCow) -> Result<Data> {
|
||||
let cx = &mut Ctx::new(&mut self.app.core, cmd.id("tab"))?;
|
||||
let cx = &mut Ctx::new(&mut self.app.core, &cmd)?;
|
||||
|
||||
macro_rules! on {
|
||||
($name:ident) => {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ yazi-config = { path = "../yazi-config", version = "25.6.11" }
|
|||
yazi-dds = { path = "../yazi-dds", version = "25.6.11" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
|
||||
# External dependencies
|
||||
|
|
|
|||
18
yazi-parser/src/app/deprecate.rs
Normal file
18
yazi-parser/src/app/deprecate.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
use anyhow::bail;
|
||||
use yazi_shared::event::CmdCow;
|
||||
|
||||
pub struct DeprecateOpt {
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
impl TryFrom<CmdCow> for DeprecateOpt {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
|
||||
let Some(content) = c.take_str("content") else {
|
||||
bail!("Invalid 'content' in DeprecateOpt");
|
||||
};
|
||||
|
||||
Ok(Self { content: content.into_owned() })
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
yazi_macro::mod_flat!(accept_payload mouse stop update_progress);
|
||||
yazi_macro::mod_flat!(accept_payload deprecate mouse notify plugin stop update_progress);
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ impl TryFrom<mlua::Table> for NotifyOpt {
|
|||
}
|
||||
}
|
||||
|
||||
// --- Level
|
||||
#[derive(Clone, Copy, Default, Deserialize, Eq, PartialEq)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum NotifyLevel {
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
use std::path::PathBuf;
|
||||
use std::{ffi::OsString, path::{MAIN_SEPARATOR_STR, PathBuf}};
|
||||
|
||||
use yazi_proxy::options::CmpItem;
|
||||
use yazi_shared::{Id, SStr, event::{Cmd, CmdCow}};
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
@ -25,3 +24,16 @@ impl From<CmdCow> for ShowOpt {
|
|||
impl From<Cmd> for ShowOpt {
|
||||
fn from(c: Cmd) -> Self { Self::from(CmdCow::from(c)) }
|
||||
}
|
||||
|
||||
// --- Item
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CmpItem {
|
||||
pub name: OsString,
|
||||
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 { "" })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use anyhow::bail;
|
||||
use yazi_proxy::options::CmpItem;
|
||||
use yazi_shared::{Id, event::CmdCow};
|
||||
|
||||
use crate::cmp::CmpItem;
|
||||
|
||||
pub struct CompleteOpt {
|
||||
pub item: CmpItem,
|
||||
pub _ticket: Id, // FIXME: not used
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ yazi_macro::mod_flat!(
|
|||
quit
|
||||
remove
|
||||
rename
|
||||
search
|
||||
seek
|
||||
spot
|
||||
tab_close
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
use yazi_shared::event::CmdCow;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use yazi_config::opener::OpenerRule;
|
||||
use yazi_shared::{event::CmdCow, url::Url};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct OpenOpt {
|
||||
|
|
@ -11,3 +15,31 @@ impl From<CmdCow> for OpenOpt {
|
|||
Self { interactive: c.bool("interactive"), hovered: c.bool("hovered") }
|
||||
}
|
||||
}
|
||||
|
||||
// --- Do
|
||||
#[derive(Default)]
|
||||
pub struct OpenDoOpt {
|
||||
pub cwd: Url,
|
||||
pub hovered: Url,
|
||||
pub targets: Vec<(Url, &'static str)>,
|
||||
pub interactive: bool,
|
||||
}
|
||||
|
||||
impl From<CmdCow> for OpenDoOpt {
|
||||
fn from(mut c: CmdCow) -> Self { c.take_any("option").unwrap_or_default() }
|
||||
}
|
||||
|
||||
// --- Open with
|
||||
pub struct OpenWithOpt {
|
||||
pub opener: Cow<'static, OpenerRule>,
|
||||
pub cwd: Url,
|
||||
pub targets: Vec<Url>,
|
||||
}
|
||||
|
||||
impl TryFrom<CmdCow> for OpenWithOpt {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
|
||||
c.take_any("option").ok_or_else(|| anyhow!("Missing 'option' in OpenWithOpt"))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,22 @@
|
|||
use std::{borrow::Cow, ffi::OsString};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use tokio::sync::oneshot;
|
||||
use yazi_config::opener::OpenerRule;
|
||||
use yazi_shared::{event::CmdCow, url::Url};
|
||||
|
||||
// --- Exec
|
||||
pub struct ProcessExecOpt {
|
||||
pub cwd: Url,
|
||||
pub opener: Cow<'static, OpenerRule>,
|
||||
pub args: Vec<OsString>,
|
||||
pub done: Option<oneshot::Sender<()>>,
|
||||
}
|
||||
|
||||
impl TryFrom<CmdCow> for ProcessExecOpt {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
|
||||
c.take_any("option").ok_or_else(|| anyhow!("Missing 'option' in ProcessExecOpt"))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
251
yazi-plugin/src/elements/elements.rs
Normal file
251
yazi-plugin/src/elements/elements.rs
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
use mlua::{AnyUserData, ExternalError, IntoLua, Lua, ObjectLike, Table, Value};
|
||||
use tracing::error;
|
||||
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
|
||||
use yazi_binding::{Composer, ComposerGet, ComposerSet, Permit, PermitRef, elements::{Line, Rect, Span}};
|
||||
use yazi_config::LAYOUT;
|
||||
use yazi_proxy::{AppProxy, HIDER};
|
||||
|
||||
pub fn compose() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
match key {
|
||||
b"area" => area(lua)?,
|
||||
b"hide" => hide(lua)?,
|
||||
b"width" => width(lua)?,
|
||||
b"redraw" => redraw(lua)?,
|
||||
b"render" => render(lua)?,
|
||||
b"truncate" => truncate(lua)?,
|
||||
_ => return Ok(Value::Nil),
|
||||
}
|
||||
.into_lua(lua)
|
||||
}
|
||||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
yazi_binding::elements::compose(get, set)
|
||||
}
|
||||
|
||||
pub(super) fn area(lua: &Lua) -> mlua::Result<Value> {
|
||||
let f = lua.create_function(|_, s: mlua::String| {
|
||||
let layout = LAYOUT.get();
|
||||
Ok(match s.as_bytes().as_ref() {
|
||||
b"current" => Rect(layout.current),
|
||||
b"preview" => Rect(layout.preview),
|
||||
b"progress" => Rect(layout.progress),
|
||||
_ => Err(format!("unknown area: {}", s.display()).into_lua_err())?,
|
||||
})
|
||||
})?;
|
||||
|
||||
f.into_lua(lua)
|
||||
}
|
||||
|
||||
pub(super) fn hide(lua: &Lua) -> mlua::Result<Value> {
|
||||
let f = lua.create_async_function(|lua, ()| async move {
|
||||
if lua.named_registry_value::<PermitRef<fn()>>("HIDE_PERMIT").is_ok_and(|h| h.is_some()) {
|
||||
return Err("Cannot hide while already hidden".into_lua_err());
|
||||
}
|
||||
|
||||
let permit = HIDER.acquire().await.unwrap();
|
||||
AppProxy::stop().await;
|
||||
|
||||
lua.set_named_registry_value("HIDE_PERMIT", Permit::new(permit, AppProxy::resume as fn()))?;
|
||||
lua.named_registry_value::<AnyUserData>("HIDE_PERMIT")
|
||||
})?;
|
||||
|
||||
f.into_lua(lua)
|
||||
}
|
||||
|
||||
pub(super) fn width(lua: &Lua) -> mlua::Result<Value> {
|
||||
let f = lua.create_function(|_, v: Value| match v {
|
||||
Value::String(s) => {
|
||||
let (mut acc, b) = (0, s.as_bytes());
|
||||
for c in b.utf8_chunks() {
|
||||
acc += c.valid().width();
|
||||
if !c.invalid().is_empty() {
|
||||
acc += 1;
|
||||
}
|
||||
}
|
||||
Ok(acc)
|
||||
}
|
||||
Value::UserData(ud) => {
|
||||
if let Ok(line) = ud.borrow::<Line>() {
|
||||
Ok(line.width())
|
||||
} else if let Ok(span) = ud.borrow::<Span>() {
|
||||
Ok(span.width())
|
||||
} else {
|
||||
Err("expected a string, Line, or Span".into_lua_err())?
|
||||
}
|
||||
}
|
||||
_ => Err("expected a string, Line, or Span".into_lua_err())?,
|
||||
})?;
|
||||
|
||||
f.into_lua(lua)
|
||||
}
|
||||
|
||||
pub(super) fn redraw(lua: &Lua) -> mlua::Result<Value> {
|
||||
let f = lua.create_function(|lua, c: Table| {
|
||||
let id: mlua::String = c.get("_id")?;
|
||||
|
||||
let mut layout = LAYOUT.get();
|
||||
match id.as_bytes().as_ref() {
|
||||
b"current" => layout.current = *c.raw_get::<Rect>("_area")?,
|
||||
b"preview" => layout.preview = *c.raw_get::<Rect>("_area")?,
|
||||
b"progress" => layout.progress = *c.raw_get::<Rect>("_area")?,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
LAYOUT.set(layout);
|
||||
match c.call_method::<Value>("redraw", ())? {
|
||||
Value::Table(tbl) => Ok(tbl),
|
||||
Value::UserData(ud) => lua.create_sequence_from([ud]),
|
||||
_ => {
|
||||
error!(
|
||||
"Failed to `redraw()` the `{}` component: expected a table or UserData",
|
||||
id.display(),
|
||||
);
|
||||
lua.create_table()
|
||||
}
|
||||
}
|
||||
})?;
|
||||
|
||||
f.into_lua(lua)
|
||||
}
|
||||
|
||||
pub(super) fn render(lua: &Lua) -> mlua::Result<Value> {
|
||||
let f = lua.create_function(|_, ()| {
|
||||
yazi_macro::render!();
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
f.into_lua(lua)
|
||||
}
|
||||
|
||||
pub(super) fn truncate(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn traverse(it: impl Iterator<Item = (usize, char)>, max: usize) -> (Option<usize>, usize, bool) {
|
||||
let (mut adv, mut last) = (0, 0);
|
||||
let idx = it
|
||||
.take_while(|&(_, c)| {
|
||||
(last, adv) = (adv, adv + c.width().unwrap_or(0));
|
||||
adv <= max
|
||||
})
|
||||
.map(|(i, _)| i)
|
||||
.last();
|
||||
(idx, last, adv > max)
|
||||
}
|
||||
|
||||
let f = lua.create_function(|lua, (s, t): (mlua::String, Table)| {
|
||||
let b = s.as_bytes();
|
||||
if b.is_empty() {
|
||||
return Ok(s);
|
||||
}
|
||||
|
||||
let max = t.raw_get("max")?;
|
||||
if b.len() <= max {
|
||||
return Ok(s);
|
||||
} else if max < 1 {
|
||||
return lua.create_string("");
|
||||
}
|
||||
|
||||
let lossy = String::from_utf8_lossy(&b);
|
||||
let rtl = t.raw_get("rtl").unwrap_or(false);
|
||||
let (idx, width, remain) = if rtl {
|
||||
traverse(lossy.char_indices().rev(), max)
|
||||
} else {
|
||||
traverse(lossy.char_indices(), max)
|
||||
};
|
||||
|
||||
let Some(idx) = idx else { return lua.create_string("…") };
|
||||
if !remain {
|
||||
return Ok(s);
|
||||
}
|
||||
|
||||
let result: Vec<_> = match (rtl, width == max) {
|
||||
(false, false) => {
|
||||
let len = lossy[idx..].chars().next().map_or(0, |c| c.len_utf8());
|
||||
lossy[..idx + len].bytes().chain("…".bytes()).collect()
|
||||
}
|
||||
(false, true) => lossy[..idx].bytes().chain("…".bytes()).collect(),
|
||||
(true, false) => "…".bytes().chain(lossy[idx..].bytes()).collect(),
|
||||
(true, true) => {
|
||||
let len = lossy[idx..].chars().next().map_or(0, |c| c.len_utf8());
|
||||
"…".bytes().chain(lossy[idx + len..].bytes()).collect()
|
||||
}
|
||||
};
|
||||
lua.create_string(result)
|
||||
})?;
|
||||
|
||||
f.into_lua(lua)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use mlua::{Lua, chunk};
|
||||
|
||||
fn truncate(s: &str, max: usize, rtl: bool) -> String {
|
||||
let lua = Lua::new();
|
||||
let f = super::truncate(&lua).unwrap();
|
||||
|
||||
lua
|
||||
.load(chunk! {
|
||||
return $f($s, { max = $max, rtl = $rtl })
|
||||
})
|
||||
.call(())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate() {
|
||||
assert_eq!(truncate("你好,world", 0, false), "");
|
||||
assert_eq!(truncate("你好,world", 1, false), "…");
|
||||
assert_eq!(truncate("你好,world", 2, false), "…");
|
||||
|
||||
assert_eq!(truncate("你好,世界", 3, false), "你…");
|
||||
assert_eq!(truncate("你好,世界", 4, false), "你…");
|
||||
assert_eq!(truncate("你好,世界", 5, false), "你好…");
|
||||
|
||||
assert_eq!(truncate("Hello, world", 5, false), "Hell…");
|
||||
assert_eq!(truncate("Ni好,世界", 3, false), "Ni…");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate_rtl() {
|
||||
assert_eq!(truncate("world,你好", 0, true), "");
|
||||
assert_eq!(truncate("world,你好", 1, true), "…");
|
||||
assert_eq!(truncate("world,你好", 2, true), "…");
|
||||
|
||||
assert_eq!(truncate("你好,世界", 3, true), "…界");
|
||||
assert_eq!(truncate("你好,世界", 4, true), "…界");
|
||||
assert_eq!(truncate("你好,世界", 5, true), "…世界");
|
||||
|
||||
assert_eq!(truncate("Hello, world", 5, true), "…orld");
|
||||
assert_eq!(truncate("你好,Shi界", 3, true), "…界");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate_oboe() {
|
||||
assert_eq!(truncate("Hello, world", 11, false), "Hello, wor…");
|
||||
assert_eq!(truncate("你好,世界", 9, false), "你好,世…");
|
||||
assert_eq!(truncate("你好,世Jie", 9, false), "你好,世…");
|
||||
|
||||
assert_eq!(truncate("Hello, world", 11, true), "…llo, world");
|
||||
assert_eq!(truncate("你好,世界", 9, true), "…好,世界");
|
||||
assert_eq!(truncate("Ni好,世界", 9, true), "…好,世界");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate_exact() {
|
||||
assert_eq!(truncate("Hello, world", 12, false), "Hello, world");
|
||||
assert_eq!(truncate("你好,世界", 10, false), "你好,世界");
|
||||
|
||||
assert_eq!(truncate("Hello, world", 12, true), "Hello, world");
|
||||
assert_eq!(truncate("你好,世界", 10, true), "你好,世界");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate_overflow() {
|
||||
assert_eq!(truncate("Hello, world", 13, false), "Hello, world");
|
||||
assert_eq!(truncate("你好,世界", 11, false), "你好,世界");
|
||||
|
||||
assert_eq!(truncate("Hello, world", 13, true), "Hello, world");
|
||||
assert_eq!(truncate("你好,世界", 11, true), "你好,世界");
|
||||
}
|
||||
}
|
||||
1
yazi-plugin/src/elements/mod.rs
Normal file
1
yazi-plugin/src/elements/mod.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
yazi_macro::mod_flat!(elements);
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
use globset::GlobBuilder;
|
||||
use mlua::{ExternalError, ExternalResult, Function, IntoLua, IntoLuaMulti, Lua, Table, Value};
|
||||
use tokio::fs;
|
||||
use yazi_binding::{Cha, Composer, Error, File, Url, UrlRef};
|
||||
use yazi_binding::{Cha, Composer, ComposerGet, ComposerSet, Error, File, Url, UrlRef};
|
||||
use yazi_fs::{mounts::PARTITIONS, remove_dir_clean};
|
||||
|
||||
use crate::bindings::SizeCalculator;
|
||||
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
pub fn compose() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
match key {
|
||||
b"op" => op(lua)?,
|
||||
|
|
@ -27,7 +27,7 @@ pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn op(lua: &Lua) -> mlua::Result<Function> {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use mlua::{ExternalResult, ObjectLike};
|
||||
use tokio::runtime::Handle;
|
||||
use yazi_dds::Sendable;
|
||||
use yazi_proxy::options::PluginOpt;
|
||||
use yazi_parser::app::PluginOpt;
|
||||
|
||||
use super::slim_lua;
|
||||
use crate::loader::LOADER;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use mlua::Lua;
|
||||
use mlua::{IntoLua, Lua};
|
||||
use yazi_binding::Runtime;
|
||||
use yazi_macro::plugin_preset as preset;
|
||||
|
||||
|
|
@ -8,11 +8,11 @@ pub fn slim_lua(name: &str) -> mlua::Result<Lua> {
|
|||
|
||||
// Base
|
||||
let globals = lua.globals();
|
||||
globals.raw_set("ui", yazi_binding::elements::compose(&lua)?)?;
|
||||
globals.raw_set("ya", crate::utils::compose(&lua, true)?)?;
|
||||
globals.raw_set("fs", crate::fs::compose(&lua)?)?;
|
||||
globals.raw_set("rt", crate::runtime::compose(&lua)?)?;
|
||||
globals.raw_set("th", crate::theme::compose(&lua)?)?;
|
||||
globals.raw_set("ui", crate::elements::compose())?;
|
||||
globals.raw_set("ya", crate::utils::compose(true))?;
|
||||
globals.raw_set("fs", crate::fs::compose())?;
|
||||
globals.raw_set("rt", crate::runtime::compose())?;
|
||||
globals.raw_set("th", crate::theme::compose().into_lua(&lua)?)?;
|
||||
|
||||
yazi_binding::Cha::install(&lua)?;
|
||||
yazi_binding::File::install(&lua)?;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ use tracing::error;
|
|||
use yazi_binding::{File, elements::Rect};
|
||||
use yazi_config::LAYOUT;
|
||||
use yazi_dds::Sendable;
|
||||
use yazi_proxy::{AppProxy, options::{PluginCallback, PluginOpt}};
|
||||
use yazi_parser::app::{PluginCallback, PluginOpt};
|
||||
use yazi_proxy::AppProxy;
|
||||
use yazi_shared::{SStr, event::Cmd};
|
||||
|
||||
use super::slim_lua;
|
||||
|
|
@ -102,10 +103,10 @@ fn peek_async(
|
|||
}
|
||||
});
|
||||
|
||||
if let Err(e) = result {
|
||||
if !e.to_string().contains("Peek task cancelled") {
|
||||
error!("{e}");
|
||||
}
|
||||
if let Err(e) = result
|
||||
&& !e.to_string().contains("Peek task cancelled")
|
||||
{
|
||||
error!("{e}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use mlua::{IntoLua, ObjectLike};
|
||||
use yazi_binding::{File, elements::Rect};
|
||||
use yazi_config::LAYOUT;
|
||||
use yazi_proxy::{AppProxy, options::{PluginCallback, PluginOpt}};
|
||||
use yazi_parser::app::{PluginCallback, PluginOpt};
|
||||
use yazi_proxy::AppProxy;
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
pub fn seek_sync(cmd: &'static Cmd, file: yazi_fs::File, units: i16) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#![allow(clippy::if_same_then_else, clippy::unit_arg)]
|
||||
|
||||
yazi_macro::mod_pub!(bindings external fs isolate loader process pubsub runtime theme utils);
|
||||
yazi_macro::mod_pub!(bindings elements external fs isolate loader process pubsub runtime theme utils);
|
||||
|
||||
yazi_macro::mod_flat!(lua twox);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ fn stage_1(lua: &'static Lua) -> Result<()> {
|
|||
|
||||
// Base
|
||||
let globals = lua.globals();
|
||||
globals.raw_set("ui", yazi_binding::elements::compose(lua)?)?;
|
||||
globals.raw_set("ya", crate::utils::compose(lua, false)?)?;
|
||||
globals.raw_set("fs", crate::fs::compose(lua)?)?;
|
||||
globals.raw_set("ps", crate::pubsub::compose(lua)?)?;
|
||||
globals.raw_set("rt", crate::runtime::compose(lua)?)?;
|
||||
globals.raw_set("th", crate::theme::compose(lua)?)?;
|
||||
globals.raw_set("ui", crate::elements::compose())?;
|
||||
globals.raw_set("ya", crate::utils::compose(false))?;
|
||||
globals.raw_set("fs", crate::fs::compose())?;
|
||||
globals.raw_set("ps", crate::pubsub::compose())?;
|
||||
globals.raw_set("rt", crate::runtime::compose())?;
|
||||
globals.raw_set("th", crate::theme::compose())?;
|
||||
|
||||
yazi_binding::Error::install(lua)?;
|
||||
yazi_binding::Cha::install(lua)?;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
#![allow(clippy::module_inception)]
|
||||
|
||||
use mlua::{IntoLua, Lua, Value};
|
||||
use yazi_binding::Composer;
|
||||
use yazi_binding::{Composer, ComposerGet, ComposerSet};
|
||||
|
||||
yazi_macro::mod_flat!(pubsub);
|
||||
|
||||
pub(super) fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
pub(super) fn compose() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
match key {
|
||||
b"pub" => Pubsub::r#pub(lua)?,
|
||||
|
|
@ -21,5 +21,5 @@ pub(super) fn compose(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use mlua::{Function, IntoLua, Lua, UserData, Value};
|
||||
use yazi_binding::{Composer, FileRef, UrlRef, cached_field};
|
||||
use yazi_binding::{Composer, ComposerGet, ComposerSet, FileRef, UrlRef, cached_field};
|
||||
use yazi_config::YAZI;
|
||||
|
||||
pub(super) fn plugin(lua: &Lua) -> mlua::Result<Value> {
|
||||
pub(super) fn plugin() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
match key {
|
||||
b"fetchers" => fetchers(lua)?,
|
||||
|
|
@ -16,7 +16,7 @@ pub(super) fn plugin(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn fetchers(lua: &Lua) -> mlua::Result<Function> {
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
use mlua::{IntoLua, Lua, LuaSerdeExt, SerializeOptions, Value};
|
||||
use yazi_binding::{Composer, Url};
|
||||
use yazi_binding::{Composer, ComposerGet, ComposerSet, Url};
|
||||
use yazi_boot::ARGS;
|
||||
use yazi_config::YAZI;
|
||||
|
||||
pub const OPTS: SerializeOptions =
|
||||
SerializeOptions::new().serialize_none_to_null(false).serialize_unit_to_null(false);
|
||||
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
pub fn compose() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
match key {
|
||||
b"args" => args(lua)?,
|
||||
b"term" => super::term(lua)?,
|
||||
b"mgr" => mgr(lua)?,
|
||||
b"plugin" => super::plugin(lua)?,
|
||||
b"preview" => preview(lua)?,
|
||||
b"tasks" => tasks(lua)?,
|
||||
b"args" => args().into_lua(lua)?,
|
||||
b"term" => super::term().into_lua(lua)?,
|
||||
b"mgr" => mgr().into_lua(lua)?,
|
||||
b"plugin" => super::plugin().into_lua(lua)?,
|
||||
b"preview" => preview().into_lua(lua)?,
|
||||
b"tasks" => tasks().into_lua(lua)?,
|
||||
_ => return Ok(Value::Nil),
|
||||
}
|
||||
.into_lua(lua)
|
||||
|
|
@ -22,10 +22,10 @@ pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn args(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn args() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
match key {
|
||||
b"entries" => lua.create_sequence_from(ARGS.entries.iter().map(Url::new))?.into_lua(lua),
|
||||
|
|
@ -37,10 +37,10 @@ fn args(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn mgr(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn mgr() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
let m = &YAZI.mgr;
|
||||
match key {
|
||||
|
|
@ -74,10 +74,10 @@ fn mgr(lua: &Lua) -> mlua::Result<Value> {
|
|||
})
|
||||
}
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn preview(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn preview() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
let p = &YAZI.preview;
|
||||
match key {
|
||||
|
|
@ -101,10 +101,10 @@ fn preview(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn tasks(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn tasks() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
let t = &YAZI.tasks;
|
||||
match key {
|
||||
|
|
@ -123,5 +123,5 @@ fn tasks(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use mlua::{Function, IntoLua, IntoLuaMulti, Lua, Value};
|
||||
use yazi_adapter::{Dimension, EMULATOR};
|
||||
use yazi_binding::Composer;
|
||||
use yazi_binding::{Composer, ComposerGet, ComposerSet};
|
||||
|
||||
pub(super) fn term(lua: &Lua) -> mlua::Result<Value> {
|
||||
pub(super) fn term() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
match key {
|
||||
b"light" => EMULATOR.get().light.into_lua(lua),
|
||||
|
|
@ -13,7 +13,7 @@ pub(super) fn term(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn cell_size(lua: &Lua) -> mlua::Result<Function> {
|
||||
|
|
|
|||
|
|
@ -1,33 +1,34 @@
|
|||
use mlua::{IntoLua, Lua, Value};
|
||||
use yazi_binding::{Composer, Style, Url};
|
||||
use yazi_binding::{Composer, ComposerGet, ComposerSet, Style, Url};
|
||||
use yazi_config::THEME;
|
||||
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
pub fn compose() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
match key {
|
||||
b"mgr" => mgr(lua),
|
||||
b"tabs" => tabs(lua),
|
||||
b"mode" => mode(lua),
|
||||
b"status" => status(lua),
|
||||
b"which" => which(lua),
|
||||
b"confirm" => confirm(lua),
|
||||
b"spot" => spot(lua),
|
||||
b"notify" => notify(lua),
|
||||
b"pick" => pick(lua),
|
||||
b"input" => input(lua),
|
||||
b"cmp" => cmp(lua),
|
||||
b"tasks" => tasks(lua),
|
||||
b"help" => help(lua),
|
||||
_ => Ok(Value::Nil),
|
||||
b"mgr" => mgr(),
|
||||
b"tabs" => tabs(),
|
||||
b"mode" => mode(),
|
||||
b"status" => status(),
|
||||
b"which" => which(),
|
||||
b"confirm" => confirm(),
|
||||
b"spot" => spot(),
|
||||
b"notify" => notify(),
|
||||
b"pick" => pick(),
|
||||
b"input" => input(),
|
||||
b"cmp" => cmp(),
|
||||
b"tasks" => tasks(),
|
||||
b"help" => help(),
|
||||
_ => return Ok(Value::Nil),
|
||||
}
|
||||
.into_lua(lua)
|
||||
}
|
||||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn mgr(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn mgr() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
let m = &THEME.mgr;
|
||||
match key {
|
||||
|
|
@ -60,10 +61,10 @@ fn mgr(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn tabs(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn tabs() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
let t = &THEME.tabs;
|
||||
match key {
|
||||
|
|
@ -89,10 +90,10 @@ fn tabs(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn mode(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn mode() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
let t = &THEME.mode;
|
||||
match key {
|
||||
|
|
@ -111,10 +112,10 @@ fn mode(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn status(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn status() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
let t = &THEME.status;
|
||||
match key {
|
||||
|
|
@ -148,10 +149,10 @@ fn status(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn which(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn which() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
let t = &THEME.which;
|
||||
match key {
|
||||
|
|
@ -170,10 +171,10 @@ fn which(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn confirm(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn confirm() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
let t = &THEME.confirm;
|
||||
match key {
|
||||
|
|
@ -197,10 +198,10 @@ fn confirm(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn spot(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn spot() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
let t = &THEME.spot;
|
||||
match key {
|
||||
|
|
@ -216,10 +217,10 @@ fn spot(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn notify(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn notify() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
let t = &THEME.notify;
|
||||
match key {
|
||||
|
|
@ -237,10 +238,10 @@ fn notify(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn pick(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn pick() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
let t = &THEME.pick;
|
||||
match key {
|
||||
|
|
@ -254,10 +255,10 @@ fn pick(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn input(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn input() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
let t = &THEME.input;
|
||||
match key {
|
||||
|
|
@ -272,10 +273,10 @@ fn input(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn cmp(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn cmp() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
let t = &THEME.cmp;
|
||||
match key {
|
||||
|
|
@ -293,10 +294,10 @@ fn cmp(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn tasks(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn tasks() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
let t = &THEME.tasks;
|
||||
match key {
|
||||
|
|
@ -310,10 +311,10 @@ fn tasks(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
||||
fn help(lua: &Lua) -> mlua::Result<Value> {
|
||||
fn help() -> Composer<ComposerGet, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||
let t = &THEME.help;
|
||||
match key {
|
||||
|
|
@ -330,5 +331,5 @@ fn help(lua: &Lua) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, get, set)
|
||||
Composer::new(get, set)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ use mlua::{ExternalError, ExternalResult, Function, IntoLuaMulti, Lua, MultiValu
|
|||
use tokio::sync::oneshot;
|
||||
use yazi_binding::{runtime, runtime_mut};
|
||||
use yazi_dds::Sendable;
|
||||
use yazi_proxy::{AppProxy, options::{PluginCallback, PluginOpt}};
|
||||
use yazi_parser::app::{PluginCallback, PluginOpt};
|
||||
use yazi_proxy::AppProxy;
|
||||
use yazi_shared::event::Data;
|
||||
|
||||
use super::Utils;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
use mlua::{IntoLua, Lua, Value};
|
||||
use yazi_binding::Composer;
|
||||
use yazi_binding::{Composer, ComposerSet};
|
||||
|
||||
pub(super) struct Utils;
|
||||
|
||||
pub fn compose(lua: &Lua, isolate: bool) -> mlua::Result<Value> {
|
||||
pub fn compose(
|
||||
isolate: bool,
|
||||
) -> Composer<impl Fn(&Lua, &[u8]) -> mlua::Result<Value>, ComposerSet> {
|
||||
fn get(lua: &Lua, key: &[u8], isolate: bool) -> mlua::Result<Value> {
|
||||
match key {
|
||||
// App
|
||||
|
|
@ -88,5 +90,5 @@ pub fn compose(lua: &Lua, isolate: bool) -> mlua::Result<Value> {
|
|||
|
||||
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||
|
||||
Composer::make(lua, move |lua, key| get(lua, key, isolate), set)
|
||||
Composer::new(move |lua, key| get(lua, key, isolate), set)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ vendored-lua = [ "mlua/vendored" ]
|
|||
[dependencies]
|
||||
yazi-config = { path = "../yazi-config", version = "25.6.11" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
yazi-parser = { path = "../yazi-parser", version = "25.6.11" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
|
||||
# External dependencies
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@ use std::time::Duration;
|
|||
|
||||
use tokio::sync::oneshot;
|
||||
use yazi_macro::emit;
|
||||
use yazi_parser::app::{NotifyLevel, NotifyOpt, PluginOpt};
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
use crate::options::{NotifyLevel, NotifyOpt, PluginOpt};
|
||||
|
||||
pub struct AppProxy;
|
||||
|
||||
impl AppProxy {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
mod macros;
|
||||
|
||||
yazi_macro::mod_pub!(options);
|
||||
|
||||
yazi_macro::mod_flat!(app cmp confirm input mgr pick semaphore tasks);
|
||||
|
||||
pub fn init() { crate::init_semaphore(); }
|
||||
|
|
|
|||
|
|
@ -3,12 +3,9 @@ macro_rules! deprecate {
|
|||
($content:expr) => {{
|
||||
static WARNED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
|
||||
if !WARNED.swap(true, std::sync::atomic::Ordering::Relaxed) {
|
||||
$crate::AppProxy::notify($crate::options::NotifyOpt {
|
||||
title: "Deprecated API".to_owned(),
|
||||
content: $content.to_owned(),
|
||||
level: $crate::options::NotifyLevel::Warn,
|
||||
timeout: std::time::Duration::from_secs(20),
|
||||
});
|
||||
$crate::emit!(Call(
|
||||
yazi_shared::event::Cmd::new("app:deprecate").with("content", format!($tt, id))
|
||||
));
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use yazi_macro::emit;
|
||||
use yazi_parser::mgr::{OpenDoOpt, SearchOpt};
|
||||
use yazi_shared::{SStr, event::Cmd, url::Url};
|
||||
|
||||
use crate::options::{OpenDoOpt, SearchOpt};
|
||||
|
||||
pub struct MgrProxy;
|
||||
|
||||
impl MgrProxy {
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
use std::{ffi::OsString, path::MAIN_SEPARATOR_STR};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CmpItem {
|
||||
pub name: OsString,
|
||||
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 { "" })
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
yazi_macro::mod_flat!(cmp notify open plugin process search);
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use yazi_config::opener::OpenerRule;
|
||||
use yazi_shared::{event::CmdCow, url::Url};
|
||||
|
||||
// --- Open
|
||||
#[derive(Default)]
|
||||
pub struct OpenDoOpt {
|
||||
pub cwd: Url,
|
||||
pub hovered: Url,
|
||||
pub targets: Vec<(Url, &'static str)>,
|
||||
pub interactive: bool,
|
||||
}
|
||||
|
||||
impl From<CmdCow> for OpenDoOpt {
|
||||
fn from(mut c: CmdCow) -> Self { c.take_any("option").unwrap_or_default() }
|
||||
}
|
||||
|
||||
// --- Open with
|
||||
pub struct OpenWithOpt {
|
||||
pub opener: Cow<'static, OpenerRule>,
|
||||
pub cwd: Url,
|
||||
pub targets: Vec<Url>,
|
||||
}
|
||||
|
||||
impl TryFrom<CmdCow> for OpenWithOpt {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
|
||||
c.take_any("option").ok_or_else(|| anyhow!("Missing 'option' in OpenWithOpt"))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
use std::{borrow::Cow, ffi::OsString};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use tokio::sync::oneshot;
|
||||
use yazi_config::opener::OpenerRule;
|
||||
use yazi_shared::{event::CmdCow, url::Url};
|
||||
|
||||
// --- Exec
|
||||
pub struct ProcessExecOpt {
|
||||
pub cwd: Url,
|
||||
pub opener: Cow<'static, OpenerRule>,
|
||||
pub args: Vec<OsString>,
|
||||
pub done: Option<oneshot::Sender<()>>,
|
||||
}
|
||||
|
||||
impl TryFrom<CmdCow> for ProcessExecOpt {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
|
||||
c.take_any("option").ok_or_else(|| anyhow!("Missing 'option' in ProcessExecOpt"))
|
||||
}
|
||||
}
|
||||
|
|
@ -3,10 +3,9 @@ use std::{borrow::Cow, ffi::OsString};
|
|||
use tokio::sync::oneshot;
|
||||
use yazi_config::opener::OpenerRule;
|
||||
use yazi_macro::emit;
|
||||
use yazi_parser::{mgr::OpenWithOpt, tasks::ProcessExecOpt};
|
||||
use yazi_shared::{event::Cmd, url::Url};
|
||||
|
||||
use crate::options::{OpenWithOpt, ProcessExecOpt};
|
||||
|
||||
pub struct TasksProxy;
|
||||
|
||||
impl TasksProxy {
|
||||
|
|
|
|||
|
|
@ -120,11 +120,12 @@ impl File {
|
|||
self.prog.send(TaskProg::Adv(task.id, 1, cha.len))?;
|
||||
}
|
||||
FileIn::Delete(task) => {
|
||||
if let Err(e) = fs::remove_file(&task.target).await {
|
||||
if e.kind() != NotFound && maybe_exists(&task.target).await {
|
||||
self.fail(task.id, format!("Delete task failed: {task:?}, {e}"))?;
|
||||
Err(e)?
|
||||
}
|
||||
if let Err(e) = fs::remove_file(&task.target).await
|
||||
&& e.kind() != NotFound
|
||||
&& maybe_exists(&task.target).await
|
||||
{
|
||||
self.fail(task.id, format!("Delete task failed: {task:?}, {e}"))?;
|
||||
Err(e)?
|
||||
}
|
||||
self.prog.send(TaskProg::Adv(task.id, 1, task.length))?
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use yazi_proxy::options::PluginOpt;
|
||||
use yazi_parser::app::PluginOpt;
|
||||
use yazi_shared::Id;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ use tokio::{fs, select, sync::mpsc::{self, UnboundedReceiver}, task::JoinHandle}
|
|||
use yazi_config::{YAZI, plugin::{Fetcher, Preloader}};
|
||||
use yazi_dds::Pump;
|
||||
use yazi_fs::{must_be_dir, remove_dir_clean, unique_name};
|
||||
use yazi_proxy::{MgrProxy, options::{PluginOpt, ProcessExecOpt}};
|
||||
use yazi_parser::{app::PluginOpt, tasks::ProcessExecOpt};
|
||||
use yazi_proxy::MgrProxy;
|
||||
use yazi_shared::{Id, Throttle, url::Url};
|
||||
|
||||
use super::{Ongoing, TaskProg, TaskStage};
|
||||
|
|
@ -376,10 +377,10 @@ impl Scheduler {
|
|||
task.succ += succ;
|
||||
task.processed += processed;
|
||||
}
|
||||
if succ > 0 {
|
||||
if let Some(fut) = ongoing.try_remove(id, TaskStage::Pending) {
|
||||
micro.try_send(fut, LOW).ok();
|
||||
}
|
||||
if succ > 0
|
||||
&& let Some(fut) = ongoing.try_remove(id, TaskStage::Pending)
|
||||
{
|
||||
micro.try_send(fut, LOW).ok();
|
||||
}
|
||||
}
|
||||
TaskProg::Succ(id) => {
|
||||
|
|
|
|||
|
|
@ -7,13 +7,14 @@ authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
|||
description = "Yazi shared library"
|
||||
homepage = "https://yazi-rs.github.io"
|
||||
repository = "https://github.com/sxyazi/yazi"
|
||||
rust-version = "1.87.0"
|
||||
rust-version = "1.88.0"
|
||||
|
||||
[dependencies]
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
bitflags = { workspace = true }
|
||||
crossterm = { workspace = true }
|
||||
foldhash = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@ where
|
|||
(Pin::new(&mut me.stream), me.interval, Pin::new_unchecked(&mut me.sleep), &mut me.last)
|
||||
};
|
||||
|
||||
if sleep.poll_unpin(cx).is_ready() {
|
||||
if let Some(last) = last.take() {
|
||||
return Poll::Ready(Some(last));
|
||||
}
|
||||
if sleep.poll_unpin(cx).is_ready()
|
||||
&& let Some(last) = last.take()
|
||||
{
|
||||
return Poll::Ready(Some(last));
|
||||
}
|
||||
|
||||
while let Poll::Ready(next) = stream.poll_next_unpin(cx) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
yazi_macro::mod_pub!(errors event shell translit url);
|
||||
|
||||
yazi_macro::mod_flat!(alias bytes chars condition debounce either env id layer natsort os osstr rand ro_cell sync_cell terminal throttle time utf8);
|
||||
yazi_macro::mod_flat!(alias bytes chars condition debounce either env id layer natsort os osstr rand ro_cell source sync_cell terminal throttle time utf8);
|
||||
|
||||
pub fn init() {
|
||||
LOG_LEVEL.replace(<_>::from(std::env::var("YAZI_LOG").unwrap_or_default()));
|
||||
|
|
|
|||
12
yazi-shared/src/source.rs
Normal file
12
yazi-shared/src/source.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
use bitflags::bitflags;
|
||||
|
||||
bitflags! {
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||
pub struct Source: u8 {
|
||||
const KEY = 0b00000001;
|
||||
const EMIT = 0b00000010;
|
||||
|
||||
const ACTOR = 0b00000100;
|
||||
const PROXY = 0b00001000;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
#![allow(clippy::if_same_then_else)]
|
||||
|
||||
yazi_macro::mod_pub!(input);
|
||||
|
||||
yazi_macro::mod_flat!(clipboard scrollable);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue