mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: new relay-notify-push DDS event to allow custom notification handlers
This commit is contained in:
parent
dfdb235d74
commit
03aa3e93ca
32 changed files with 110 additions and 140 deletions
|
|
@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
|||
### Added
|
||||
|
||||
- Allow using `ps.sub()` in `init.lua` directly without a plugin ([#3638])
|
||||
- New `relay-notify-push` DDS event to allow custom notification handlers ([#3642])
|
||||
- New `cx.which` API to access the which component state ([#3617])
|
||||
- New `ind-which-activate` DDS event to change the which component behavior ([#3608])
|
||||
|
||||
|
|
@ -1636,3 +1637,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
|||
[#3633]: https://github.com/sxyazi/yazi/pull/3633
|
||||
[#3634]: https://github.com/sxyazi/yazi/pull/3634
|
||||
[#3638]: https://github.com/sxyazi/yazi/pull/3638
|
||||
[#3642]: https://github.com/sxyazi/yazi/pull/3642
|
||||
|
|
|
|||
8
Cargo.lock
generated
8
Cargo.lock
generated
|
|
@ -1329,6 +1329,9 @@ name = "either"
|
|||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "elliptic-curve"
|
||||
|
|
@ -5538,6 +5541,7 @@ version = "26.1.22"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"crossterm 0.29.0",
|
||||
"either",
|
||||
"futures",
|
||||
"hashbrown 0.16.1",
|
||||
"libc",
|
||||
|
|
@ -5656,6 +5660,7 @@ dependencies = [
|
|||
"clap_complete_fig",
|
||||
"clap_complete_nushell",
|
||||
"crossterm 0.29.0",
|
||||
"either",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
|
|
@ -5765,6 +5770,7 @@ version = "26.1.22"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"crossterm 0.29.0",
|
||||
"either",
|
||||
"scopeguard",
|
||||
"tokio",
|
||||
"tracing",
|
||||
|
|
@ -5835,6 +5841,7 @@ dependencies = [
|
|||
"bitflags 2.10.0",
|
||||
"core-foundation-sys",
|
||||
"dirs",
|
||||
"either",
|
||||
"foldhash",
|
||||
"hashbrown 0.16.1",
|
||||
"libc",
|
||||
|
|
@ -6056,6 +6063,7 @@ version = "26.1.22"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"deadpool",
|
||||
"either",
|
||||
"futures",
|
||||
"hashbrown 0.16.1",
|
||||
"parking_lot",
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ core-foundation-sys = "0.8.7"
|
|||
crossterm = { version = "0.29.0", features = [ "event-stream" ] }
|
||||
dirs = "6.0.0"
|
||||
dyn-clone = "1.0.20"
|
||||
either = { version = "1.15.0", features = [ "serde" ] }
|
||||
foldhash = "0.2.0"
|
||||
futures = "0.3.31"
|
||||
globset = "0.4.18"
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ yazi-widgets = { path = "../yazi-widgets", version = "26.1.22" }
|
|||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
crossterm = { workspace = true }
|
||||
either = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
hashbrown = { workspace = true }
|
||||
mlua = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use anyhow::Result;
|
|||
use mlua::IntoLua;
|
||||
use tracing::error;
|
||||
use yazi_actor::lives::Lives;
|
||||
use yazi_binding::runtime_mut;
|
||||
use yazi_binding::runtime_scope;
|
||||
use yazi_dds::{LOCAL, Payload, REMOTE};
|
||||
use yazi_macro::succ;
|
||||
use yazi_plugin::LUA;
|
||||
|
|
@ -31,11 +31,9 @@ impl Actor for AcceptPayload {
|
|||
succ!(Lives::scope(&cx.core, || {
|
||||
let body = payload.body.into_lua(&LUA)?;
|
||||
for (id, cb) in handlers {
|
||||
let blocking = runtime_mut!(LUA)?.critical_push(&id, true);
|
||||
if let Err(e) = cb.call::<()>(body.clone()) {
|
||||
if let Err(e) = runtime_scope!(LUA, &id, cb.call::<()>(body.clone())) {
|
||||
error!("Failed to run `{kind}` event handler in your `{id}` plugin: {e}");
|
||||
}
|
||||
runtime_mut!(LUA)?.critical_pop(blocking)?;
|
||||
}
|
||||
Ok(())
|
||||
})?);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use crossterm::event::MouseEventKind;
|
|||
use mlua::{ObjectLike, Table};
|
||||
use tracing::error;
|
||||
use yazi_actor::lives::Lives;
|
||||
use yazi_binding::runtime_scope;
|
||||
use yazi_config::YAZI;
|
||||
use yazi_macro::succ;
|
||||
use yazi_parser::app::MouseOpt;
|
||||
|
|
@ -20,11 +21,14 @@ impl Actor for Mouse {
|
|||
|
||||
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
|
||||
let event = yazi_binding::MouseEvent::from(opt.event);
|
||||
|
||||
let Some(size) = cx.term.as_ref().and_then(|t| t.size().ok()) else { succ!() };
|
||||
let area = yazi_binding::elements::Rect::from(size);
|
||||
|
||||
let result = Lives::scope(&cx.core, move || {
|
||||
let area = yazi_binding::elements::Rect::from(size);
|
||||
let root = LUA.globals().raw_get::<Table>("Root")?.call_method::<Table>("new", area)?;
|
||||
let root = runtime_scope!(LUA, "root", {
|
||||
LUA.globals().raw_get::<Table>("Root")?.call_method::<Table>("new", area)
|
||||
})?;
|
||||
|
||||
if matches!(event.kind, MouseEventKind::Down(_) if YAZI.mgr.mouse_events.get().draggable()) {
|
||||
root.raw_set("_drag_start", event)?;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
use anyhow::Result;
|
||||
use mlua::ObjectLike;
|
||||
use scopeguard::defer;
|
||||
use tracing::{error, warn};
|
||||
use yazi_binding::runtime_mut;
|
||||
use yazi_binding::runtime_scope;
|
||||
use yazi_dds::Sendable;
|
||||
use yazi_macro::succ;
|
||||
use yazi_parser::app::{PluginMode, PluginOpt};
|
||||
|
|
@ -33,9 +32,6 @@ impl Actor for PluginDo {
|
|||
succ!(cx.core.tasks.scheduler.plugin_entry(opt));
|
||||
}
|
||||
|
||||
let blocking = runtime_mut!(LUA)?.critical_push(&opt.id, true);
|
||||
defer! { _ = runtime_mut!(LUA).map(|mut r| r.critical_pop(blocking)) }
|
||||
|
||||
let plugin = match LOADER.load_with(&LUA, &opt.id, chunk) {
|
||||
Ok(t) => t,
|
||||
Err(e) => succ!(warn!("{e}")),
|
||||
|
|
@ -44,10 +40,10 @@ impl Actor for PluginDo {
|
|||
|
||||
let result = Lives::scope(&cx.core, || {
|
||||
if let Some(cb) = opt.callback {
|
||||
cb(&LUA, plugin)
|
||||
runtime_scope!(LUA, &opt.id, cb(&LUA, plugin))
|
||||
} else {
|
||||
let job = LUA.create_table_from([("args", Sendable::args_to_table(&LUA, opt.args)?)])?;
|
||||
plugin.call_method("entry", job)
|
||||
runtime_scope!(LUA, &opt.id, plugin.call_method("entry", job))
|
||||
}
|
||||
});
|
||||
if let Err(ref e) = result {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use anyhow::Result;
|
||||
use mlua::{ErrorContext, ExternalError, IntoLua, Value};
|
||||
use yazi_binding::runtime_mut;
|
||||
use yazi_binding::runtime_scope;
|
||||
use yazi_dds::{LOCAL, spark::{Spark, SparkKind}};
|
||||
use yazi_plugin::LUA;
|
||||
|
||||
|
|
@ -18,11 +18,7 @@ impl Preflight {
|
|||
Ok(Lives::scope(cx.core, || {
|
||||
let mut body = opt.1.into_lua(&LUA)?;
|
||||
for (id, cb) in handlers {
|
||||
let blocking = runtime_mut!(LUA)?.critical_push(&id, true);
|
||||
let result = cb.call::<Value>(&body);
|
||||
runtime_mut!(LUA)?.critical_pop(blocking)?;
|
||||
|
||||
match result {
|
||||
match runtime_scope!(LUA, &id, cb.call::<Value>(&body)) {
|
||||
Ok(Value::Nil) => {
|
||||
Err(format!("`{kind}` event cancelled by `{id}` plugin on preflight").into_lua_err())?
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,10 @@ pub(super) static FILE_CACHE: RoCell<RefCell<HashMap<PtrCell<yazi_fs::File>, Any
|
|||
pub struct Lives;
|
||||
|
||||
impl Lives {
|
||||
pub fn scope<T>(core: &yazi_core::Core, f: impl FnOnce() -> mlua::Result<T>) -> mlua::Result<T> {
|
||||
pub fn scope<T, F>(core: &yazi_core::Core, f: F) -> mlua::Result<T>
|
||||
where
|
||||
F: FnOnce() -> mlua::Result<T>,
|
||||
{
|
||||
FILE_CACHE.init(Default::default());
|
||||
defer! { FILE_CACHE.drop(); }
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ impl Actor for ToggleAll {
|
|||
const NAME: &str = "toggle_all";
|
||||
|
||||
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
|
||||
use yazi_shared::Either::*;
|
||||
use either::Either::*;
|
||||
let tab = cx.tab_mut();
|
||||
|
||||
let it = tab.current.files.iter().map(|f| &f.url);
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ use std::time::{Duration, Instant};
|
|||
|
||||
use anyhow::Result;
|
||||
use yazi_core::notify::Message;
|
||||
use yazi_dds::spark::SparkKind;
|
||||
use yazi_macro::succ;
|
||||
use yazi_parser::notify::PushOpt;
|
||||
use yazi_proxy::NotifyProxy;
|
||||
use yazi_shared::data::Data;
|
||||
use yazi_shared::{Source, data::Data};
|
||||
|
||||
use crate::{Actor, Ctx};
|
||||
|
||||
|
|
@ -28,4 +29,11 @@ impl Actor for Push {
|
|||
}
|
||||
succ!();
|
||||
}
|
||||
|
||||
fn hook(cx: &Ctx, _: &Self::Options) -> Option<SparkKind> {
|
||||
match cx.source() {
|
||||
Source::Relay => Some(SparkKind::RelayNotifyPush),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use yazi_shared::Either;
|
||||
|
||||
use crate::Adapter;
|
||||
|
||||
pub(super) struct Adapters(Vec<Adapter>);
|
||||
|
|
@ -17,12 +15,7 @@ impl DerefMut for Adapters {
|
|||
}
|
||||
|
||||
impl From<&yazi_emulator::Emulator> for Adapters {
|
||||
fn from(value: &yazi_emulator::Emulator) -> Self {
|
||||
match value.kind {
|
||||
Either::Left(b) => b.into(),
|
||||
Either::Right(u) => u.into(),
|
||||
}
|
||||
}
|
||||
fn from(value: &yazi_emulator::Emulator) -> Self { value.kind.either_into() }
|
||||
}
|
||||
|
||||
impl From<yazi_emulator::Brand> for Adapters {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ pub fn init() -> anyhow::Result<()> {
|
|||
|
||||
// Emulator detection
|
||||
let mut emulator = Emulator::detect().unwrap_or_default();
|
||||
TMUX.set(emulator.kind.is_left_and(|&b| b == Brand::Tmux));
|
||||
TMUX.set(emulator.kind.left() == Some(Brand::Tmux));
|
||||
|
||||
// Tmux support
|
||||
if TMUX.get() {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,19 @@ macro_rules! runtime_mut {
|
|||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! runtime_scope {
|
||||
($lua:ident, $id:expr, $block:expr) => {{
|
||||
let mut f = || {
|
||||
let blocking = $crate::runtime_mut!($lua)?.critical_push($id, true);
|
||||
let result = (|| $block)();
|
||||
$crate::runtime_mut!($lua)?.critical_pop(blocking)?;
|
||||
result
|
||||
};
|
||||
f()
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! deprecate {
|
||||
($lua:ident, $tt:tt) => {{
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ impl Actions {
|
|||
fn file1_output() -> String {
|
||||
use std::io::Write;
|
||||
|
||||
let p = env::temp_dir().join(format!("yazi-debug-{}", timestamp_us()));
|
||||
let p = env::temp_dir().join(format!(".yazi-debug-{}.tmp", timestamp_us()));
|
||||
std::fs::File::create_new(&p).map(|mut f| f.write_all(b"Hello, World!")).ok();
|
||||
|
||||
let cmd = env::var_os("YAZI_FILE_ONE").unwrap_or("file".into());
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ yazi-shim = { path = "../yazi-shim", version = "26.1.22" }
|
|||
anyhow = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
crossterm = { workspace = true }
|
||||
either = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
|
|
@ -48,6 +49,7 @@ clap = { workspace = true }
|
|||
clap_complete = "4.5.65"
|
||||
clap_complete_fig = "4.5.2"
|
||||
clap_complete_nushell = "4.5.10"
|
||||
either = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
vergen-gitcl = { version = "9.1.0", features = [ "build" ] }
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ use std::{borrow::Cow, ffi::OsString};
|
|||
|
||||
use anyhow::{Result, bail};
|
||||
use clap::{Parser, Subcommand};
|
||||
use yazi_shared::{Either, Id};
|
||||
use either::Either;
|
||||
use yazi_shared::Id;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(name = "Ya", about, long_about = None)]
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ pub enum SparkKind {
|
|||
KeyQuit,
|
||||
// which:activate
|
||||
IndWhichActivate,
|
||||
// notify:push
|
||||
RelayNotifyPush,
|
||||
}
|
||||
|
||||
impl AsRef<str> for SparkKind {
|
||||
|
|
@ -27,6 +29,8 @@ impl AsRef<str> for SparkKind {
|
|||
Self::KeyQuit => "key-quit",
|
||||
// which:activate
|
||||
Self::IndWhichActivate => "ind-which-activate",
|
||||
// notify:push
|
||||
Self::RelayNotifyPush => "relay-notify-push",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,6 +166,8 @@ impl<'a> Spark<'a> {
|
|||
KeyQuit => Self::Quit(<_>::from_lua(value, lua)?),
|
||||
// which:activate
|
||||
IndWhichActivate => Self::WhichActivate(<_>::from_lua(value, lua)?),
|
||||
// notify:push
|
||||
RelayNotifyPush => Self::NotifyPush(<_>::from_lua(value, lua)?),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ yazi-tty = { path = "../yazi-tty", version = "26.1.22" }
|
|||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
crossterm = { workspace = true }
|
||||
either = { workspace = true }
|
||||
scopeguard = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ use std::{io::BufWriter, time::Duration};
|
|||
|
||||
use anyhow::Result;
|
||||
use crossterm::{cursor::{RestorePosition, SavePosition}, execute, style::Print, terminal::{disable_raw_mode, enable_raw_mode}};
|
||||
use either::Either;
|
||||
use scopeguard::defer;
|
||||
use tokio::time::sleep;
|
||||
use tracing::{debug, error, warn};
|
||||
use yazi_shared::{Either, RoCell};
|
||||
use yazi_shared::RoCell;
|
||||
use yazi_tty::{Handle, TTY};
|
||||
|
||||
use crate::{Brand, Dimension, Mux, TMUX, Unknown};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ 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::runtime_scope;
|
||||
use yazi_macro::{act, succ};
|
||||
use yazi_plugin::LUA;
|
||||
use yazi_shared::{data::Data, event::NEED_RENDER};
|
||||
use yazi_tty::TTY;
|
||||
use yazi_widgets::COLLISION;
|
||||
|
|
@ -26,7 +28,9 @@ impl App {
|
|||
let collision = COLLISION.swap(false, Ordering::Relaxed);
|
||||
let frame = term
|
||||
.draw(|f| {
|
||||
_ = Lives::scope(&self.core, || Ok(f.render_widget(Root::new(&self.core), f.area())));
|
||||
_ = Lives::scope(&self.core, || {
|
||||
runtime_scope!(LUA, "root", Ok(f.render_widget(Root::new(&self.core), f.area())))
|
||||
});
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
|
|
@ -57,9 +61,11 @@ impl App {
|
|||
let frame = term
|
||||
.draw_partial(|f| {
|
||||
_ = Lives::scope(&self.core, || {
|
||||
f.render_widget(crate::tasks::Progress::new(&self.core), f.area());
|
||||
f.render_widget(crate::notify::Notify::new(&self.core), f.area());
|
||||
Ok(())
|
||||
runtime_scope!(LUA, "root", {
|
||||
f.render_widget(crate::tasks::Progress::new(&self.core), f.area());
|
||||
f.render_widget(crate::notify::Notify::new(&self.core), f.area());
|
||||
Ok(())
|
||||
})
|
||||
});
|
||||
})
|
||||
.unwrap();
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ anyhow = { workspace = true }
|
|||
arc-swap = "1.8.0"
|
||||
bitflags = { workspace = true }
|
||||
dirs = { workspace = true }
|
||||
either = { workspace = true }
|
||||
foldhash = { workspace = true }
|
||||
hashbrown = { workspace = true }
|
||||
parking_lot = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::{collections::VecDeque, future::poll_fn, io, mem, path::{Path, PathBuf}, pin::Pin, task::{Poll, ready}, time::{Duration, Instant}};
|
||||
|
||||
use either::Either;
|
||||
use tokio::task::JoinHandle;
|
||||
use yazi_shared::Either;
|
||||
|
||||
type Task = Either<PathBuf, std::fs::ReadDir>;
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ impl SizeCalculator {
|
|||
};
|
||||
}
|
||||
|
||||
let Some(next) = front.right_mut()?.next() else {
|
||||
let Some(next) = front.as_mut().right()?.next() else {
|
||||
pop_and_continue!();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -182,8 +182,8 @@ fn final_path(path: &Path) -> io::Result<PathBuf> {
|
|||
fn final_path(path: &Path) -> io::Result<PathBuf> {
|
||||
use std::{ffi::OsString, fs::File, os::windows::{ffi::OsStringExt, fs::OpenOptionsExt, io::AsRawHandle}};
|
||||
|
||||
use either::Either;
|
||||
use windows_sys::Win32::{Foundation::HANDLE, Storage::FileSystem::{FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT, GetFinalPathNameByHandleW, VOLUME_NAME_DOS}};
|
||||
use yazi_shared::Either;
|
||||
|
||||
let file = std::fs::OpenOptions::new()
|
||||
.access_mode(0)
|
||||
|
|
@ -214,7 +214,8 @@ fn final_path(path: &Path) -> io::Result<PathBuf> {
|
|||
match inner(&file, &mut [0u16; 512])? {
|
||||
Either::Left(path) => Ok(path),
|
||||
Either::Right(len) => inner(&file, &mut vec![0u16; len as usize])?
|
||||
.left_or_err(|| io::Error::new(io::ErrorKind::InvalidData, "path too long")),
|
||||
.left()
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "path too long")),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::{str::FromStr, time::Duration};
|
|||
use anyhow::anyhow;
|
||||
use mlua::{FromLua, IntoLua, Lua, LuaSerdeExt, Value};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{DurationSeconds, serde_as};
|
||||
use serde_with::{DurationSecondsWithFrac, serde_as};
|
||||
use yazi_config::{Style, THEME};
|
||||
use yazi_shared::event::CmdCow;
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ pub struct PushOpt {
|
|||
pub title: String,
|
||||
pub content: String,
|
||||
pub level: PushLevel,
|
||||
#[serde_as(as = "DurationSeconds<f64>")] // FIXME
|
||||
#[serde_as(as = "DurationSecondsWithFrac<f64>")]
|
||||
pub timeout: Duration,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ impl Deref for Loader {
|
|||
impl Default for Loader {
|
||||
fn default() -> Self {
|
||||
let cache = HashMap::from_iter([
|
||||
// Plugins
|
||||
("archive".to_owned(), preset!("plugins/archive").into()),
|
||||
("code".to_owned(), preset!("plugins/code").into()),
|
||||
("dds".to_owned(), preset!("plugins/dds").into()),
|
||||
|
|
@ -51,6 +52,22 @@ impl Default for Loader {
|
|||
("vfs".to_owned(), preset!("plugins/vfs").into()),
|
||||
("video".to_owned(), preset!("plugins/video").into()),
|
||||
("zoxide".to_owned(), preset!("plugins/zoxide").into()),
|
||||
// Components
|
||||
("current".to_owned(), [][..].into()),
|
||||
("entity".to_owned(), [][..].into()),
|
||||
("header".to_owned(), [][..].into()),
|
||||
("linemode".to_owned(), [][..].into()),
|
||||
("marker".to_owned(), [][..].into()),
|
||||
("modal".to_owned(), [][..].into()),
|
||||
("parent".to_owned(), [][..].into()),
|
||||
("preview".to_owned(), [][..].into()),
|
||||
("progress".to_owned(), [][..].into()),
|
||||
("rail".to_owned(), [][..].into()),
|
||||
("root".to_owned(), [][..].into()),
|
||||
("status".to_owned(), [][..].into()),
|
||||
("tab".to_owned(), [][..].into()),
|
||||
("tabs".to_owned(), [][..].into()),
|
||||
("tasks".to_owned(), [][..].into()),
|
||||
]);
|
||||
Self { cache: RwLock::new(cache) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use anyhow::{Context, Result};
|
||||
use futures::executor::block_on;
|
||||
use mlua::Lua;
|
||||
use yazi_binding::{Runtime, runtime_mut};
|
||||
use yazi_binding::{Runtime, runtime_scope};
|
||||
use yazi_boot::BOOT;
|
||||
use yazi_macro::plugin_preset as preset;
|
||||
use yazi_shared::RoCell;
|
||||
|
|
@ -65,9 +65,7 @@ fn stage_2(lua: &'static Lua) -> mlua::Result<()> {
|
|||
lua.load(preset!("compat")).set_name("compat.lua").exec()?;
|
||||
|
||||
if let Ok(b) = std::fs::read(BOOT.config_dir.join("init.lua")) {
|
||||
let blocking = runtime_mut!(lua)?.critical_push("init", true);
|
||||
block_on(lua.load(b).set_name("init.lua").exec_async())?;
|
||||
runtime_mut!(lua)?.critical_pop(blocking)?;
|
||||
runtime_scope!(lua, "init", block_on(lua.load(b).set_name("init.lua").exec_async()))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
use serde::Serialize;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum Either<L, R> {
|
||||
Left(L),
|
||||
Right(R),
|
||||
}
|
||||
|
||||
impl<L, R> Either<L, R> {
|
||||
pub fn left(&self) -> Option<&L> {
|
||||
match self {
|
||||
Self::Left(l) => Some(l),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn right(&self) -> Option<&R> {
|
||||
match self {
|
||||
Self::Right(r) => Some(r),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn left_mut(&mut self) -> Option<&mut L> {
|
||||
match self {
|
||||
Self::Left(l) => Some(l),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn right_mut(&mut self) -> Option<&mut R> {
|
||||
match self {
|
||||
Self::Right(r) => Some(r),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_left_and<F: FnOnce(&L) -> bool>(&self, f: F) -> bool {
|
||||
self.left().map(f).unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn is_right_and<F: FnOnce(&R) -> bool>(&self, f: F) -> bool {
|
||||
self.right().map(f).unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn into_left(self) -> Option<L> {
|
||||
match self {
|
||||
Self::Left(l) => Some(l),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_right(self) -> Option<R> {
|
||||
match self {
|
||||
Self::Right(r) => Some(r),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn left_or_err<E, F: FnOnce() -> E>(self, f: F) -> Result<L, E> {
|
||||
match self {
|
||||
Self::Left(l) => Ok(l),
|
||||
_ => Err(f()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn right_or_err<E, F: FnOnce() -> E>(self, f: F) -> Result<R, E> {
|
||||
match self {
|
||||
Self::Right(r) => Ok(r),
|
||||
_ => Err(f()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L, R> Serialize for Either<L, R>
|
||||
where
|
||||
L: Serialize,
|
||||
R: Serialize,
|
||||
{
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
match self {
|
||||
Self::Left(l) => l.serialize(serializer),
|
||||
Self::Right(r) => r.serialize(serializer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
yazi_macro::mod_pub!(data errors event loc path pool scheme shell strand translit url wtf8);
|
||||
|
||||
yazi_macro::mod_flat!(alias bytes chars completion_token condition debounce either env id layer localset natsort os predictor ro_cell source sync_cell terminal tests throttle time utf8);
|
||||
yazi_macro::mod_flat!(alias bytes chars completion_token condition debounce env id layer localset natsort os predictor ro_cell source sync_cell terminal tests throttle time utf8);
|
||||
|
||||
pub fn init() {
|
||||
LOCAL_SET.with(tokio::task::LocalSet::new);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ yazi-shared = { path = "../yazi-shared", version = "26.1.22" }
|
|||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
deadpool = { version = "0.12.3", default-features = false, features = [ "managed", "rt_tokio_1" ] }
|
||||
either = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
hashbrown = { workspace = true }
|
||||
parking_lot = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use std::{collections::VecDeque, io, time::{Duration, Instant}};
|
||||
|
||||
use either::Either;
|
||||
use yazi_fs::provider::{DirReader, FileHolder};
|
||||
use yazi_shared::{Either, url::{AsUrl, UrlBuf}};
|
||||
use yazi_shared::url::{AsUrl, UrlBuf};
|
||||
|
||||
use super::ReadDir;
|
||||
|
||||
|
|
@ -66,7 +67,7 @@ impl SizeCalculator {
|
|||
};
|
||||
}
|
||||
|
||||
let Ok(Some(ent)) = front.right_mut()?.next().await else {
|
||||
let Ok(Some(ent)) = front.as_mut().right()?.next().await else {
|
||||
pop_and_continue!();
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue