From 33782f12240147a84ba8158670ea074e6c644788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20=C2=B7=20Misaki=20Masa?= <sxyazi@gmail.com> Date: Thu, 7 Mar 2024 17:26:18 +0800 Subject: [PATCH] feat: `cx.yanked` plugin API (#788) --- yazi-config/src/open/open.rs | 6 ++-- yazi-core/src/completion/completion.rs | 4 +-- yazi-core/src/folder/files.rs | 20 +++++------ yazi-core/src/folder/sorter.rs | 4 +-- yazi-core/src/manager/commands/hover.rs | 4 +-- yazi-core/src/manager/commands/rename.rs | 4 +-- yazi-core/src/manager/linked.rs | 6 ++-- yazi-core/src/manager/watcher.rs | 14 ++++---- yazi-core/src/tab/commands/visual_mode.rs | 6 ++-- yazi-core/src/tab/finder.rs | 6 ++-- yazi-core/src/tab/mode.rs | 10 +++--- yazi-core/src/tab/selected.rs | 6 ++-- yazi-core/src/tab/tab.rs | 4 +-- yazi-core/src/tasks/tasks.rs | 4 +-- yazi-fm/src/lives/iter.rs | 25 +++++++++++++ yazi-fm/src/lives/lives.rs | 2 +- yazi-fm/src/lives/mod.rs | 2 ++ yazi-fm/src/lives/selected.rs | 43 +++++++++-------------- yazi-fm/src/lives/tasks.rs | 2 +- yazi-fm/src/lives/yanked.rs | 41 +++++++++++++++++++-- yazi-plugin/src/loader.rs | 6 ++-- yazi-plugin/src/utils/call.rs | 6 ++-- yazi-scheduler/src/preload/preload.rs | 6 ++-- yazi-scheduler/src/running.rs | 7 ++-- yazi-shared/src/event/cmd.rs | 4 +-- yazi-shared/src/fs/op.rs | 8 ++--- 26 files changed, 150 insertions(+), 100 deletions(-) create mode 100644 yazi-fm/src/lives/iter.rs diff --git a/yazi-config/src/open/open.rs b/yazi-config/src/open/open.rs index a18ebfed..0ccd8983 100644 --- a/yazi-config/src/open/open.rs +++ b/yazi-config/src/open/open.rs @@ -1,4 +1,4 @@ -use std::{collections::BTreeMap, path::Path}; +use std::{collections::HashMap, path::Path}; use indexmap::IndexSet; use serde::{Deserialize, Deserializer}; @@ -10,7 +10,7 @@ use crate::{open::OpenRule, Preset, MERGED_YAZI}; #[derive(Debug)] pub struct Open { rules: Vec<OpenRule>, - openers: BTreeMap<String, IndexSet<Opener>>, + openers: HashMap<String, IndexSet<Opener>>, } impl Default for Open { @@ -65,7 +65,7 @@ impl<'de> Deserialize<'de> for Open { { #[derive(Deserialize)] struct Outer { - opener: BTreeMap<String, Vec<Opener>>, + opener: HashMap<String, Vec<Opener>>, open: OuterOpen, } #[derive(Deserialize)] diff --git a/yazi-core/src/completion/completion.rs b/yazi-core/src/completion/completion.rs index af5279e4..5cad5a00 100644 --- a/yazi-core/src/completion/completion.rs +++ b/yazi-core/src/completion/completion.rs @@ -1,8 +1,8 @@ -use std::collections::BTreeMap; +use std::collections::HashMap; #[derive(Default)] pub struct Completion { - pub(super) caches: BTreeMap<String, Vec<String>>, + pub(super) caches: HashMap<String, Vec<String>>, pub(super) cands: Vec<String>, pub(super) offset: usize, pub cursor: usize, diff --git a/yazi-core/src/folder/files.rs b/yazi-core/src/folder/files.rs index b4a61acc..6ca0d49c 100644 --- a/yazi-core/src/folder/files.rs +++ b/yazi-core/src/folder/files.rs @@ -1,4 +1,4 @@ -use std::{collections::{BTreeMap, BTreeSet}, mem, ops::Deref, sync::atomic::Ordering}; +use std::{collections::{HashMap, HashSet}, mem, ops::Deref, sync::atomic::Ordering}; use anyhow::Result; use tokio::{fs::{self, DirEntry}, select, sync::mpsc::{self, UnboundedReceiver}}; @@ -14,7 +14,7 @@ pub struct Files { version: u64, pub(crate) revision: u64, - pub sizes: BTreeMap<Url, u64>, + pub sizes: HashMap<Url, u64>, sorter: FilesSorter, filter: Option<Filter>, @@ -128,7 +128,7 @@ impl Files { } } - pub fn update_size(&mut self, sizes: BTreeMap<Url, u64>) { + pub fn update_size(&mut self, sizes: HashMap<Url, u64>) { if sizes.is_empty() { return; } @@ -146,7 +146,7 @@ impl Files { macro_rules! go { ($dist:expr, $src:expr, $inc:literal) => { - let mut todo: BTreeMap<_, _> = $src.into_iter().map(|f| (f.url(), f)).collect(); + let mut todo: HashMap<_, _> = $src.into_iter().map(|f| (f.url(), f)).collect(); for f in &$dist { if todo.remove(&f.url).is_some() && todo.is_empty() { break; @@ -176,7 +176,7 @@ impl Files { macro_rules! go { ($dist:expr, $src:expr, $inc:literal) => { - let mut todo: BTreeSet<_> = $src.into_iter().collect(); + let mut todo: HashSet<_> = $src.into_iter().collect(); let len = $dist.len(); $dist.retain(|f| !todo.remove(&f.url)); @@ -217,7 +217,7 @@ impl Files { }; } - let mut urls: BTreeSet<_> = urls.into_iter().collect(); + let mut urls: HashSet<_> = urls.into_iter().collect(); if !urls.is_empty() { go!(self.items, urls, 1); } @@ -228,8 +228,8 @@ impl Files { pub fn update_updating( &mut self, - files: BTreeMap<Url, File>, - ) -> (BTreeMap<Url, File>, BTreeMap<Url, File>) { + files: HashMap<Url, File>, + ) -> (HashMap<Url, File>, HashMap<Url, File>) { if files.is_empty() { return Default::default(); } @@ -257,7 +257,7 @@ impl Files { || !f.url.file_name().is_some_and(|s| filter.matches(s)) }) } else if self.show_hidden { - (BTreeMap::new(), files) + (HashMap::new(), files) } else { files.into_iter().partition(|(_, f)| f.is_hidden()) }; @@ -271,7 +271,7 @@ impl Files { (hidden, items) } - pub fn update_upserting(&mut self, files: BTreeMap<Url, File>) { + pub fn update_upserting(&mut self, files: HashMap<Url, File>) { if files.is_empty() { return; } diff --git a/yazi-core/src/folder/sorter.rs b/yazi-core/src/folder/sorter.rs index 779b22e2..5130ac68 100644 --- a/yazi-core/src/folder/sorter.rs +++ b/yazi-core/src/folder/sorter.rs @@ -1,4 +1,4 @@ -use std::{cmp::Ordering, collections::BTreeMap, mem}; +use std::{cmp::Ordering, collections::HashMap, mem}; use yazi_config::manager::SortBy; use yazi_shared::{fs::{File, Url}, natsort}; @@ -12,7 +12,7 @@ pub struct FilesSorter { } impl FilesSorter { - pub(super) fn sort(&self, items: &mut Vec<File>, sizes: &BTreeMap<Url, u64>) { + pub(super) fn sort(&self, items: &mut Vec<File>, sizes: &HashMap<Url, u64>) { if items.is_empty() { return; } diff --git a/yazi-core/src/manager/commands/hover.rs b/yazi-core/src/manager/commands/hover.rs index 4d46e1b8..94df57d0 100644 --- a/yazi-core/src/manager/commands/hover.rs +++ b/yazi-core/src/manager/commands/hover.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeSet; +use std::collections::HashSet; use yazi_shared::{event::Cmd, fs::Url, render}; @@ -31,7 +31,7 @@ impl Manager { self.peek(false); // Refresh watcher - let mut to_watch = BTreeSet::new(); + let mut to_watch = HashSet::with_capacity(3 * self.tabs.len()); for tab in self.tabs.iter() { to_watch.insert(&tab.current.cwd); if let Some(ref p) = tab.parent { diff --git a/yazi-core/src/manager/commands/rename.rs b/yazi-core/src/manager/commands/rename.rs index a980e716..3cb990e4 100644 --- a/yazi-core/src/manager/commands/rename.rs +++ b/yazi-core/src/manager/commands/rename.rs @@ -1,4 +1,4 @@ -use std::{collections::BTreeMap, ffi::{OsStr, OsString}, io::{stdout, BufWriter, Write}, path::PathBuf}; +use std::{collections::HashMap, ffi::{OsStr, OsString}, io::{stdout, BufWriter, Write}, path::PathBuf}; use anyhow::{anyhow, bail, Result}; use tokio::{fs::{self, OpenOptions}, io::{stdin, AsyncReadExt, AsyncWriteExt}}; @@ -49,7 +49,7 @@ impl Manager { let file = File::from(new.clone()).await?; FilesOp::Deleting(file.parent().unwrap(), vec![new.clone()]).emit(); - FilesOp::Upserting(file.parent().unwrap(), BTreeMap::from_iter([(old, file)])).emit(); + FilesOp::Upserting(file.parent().unwrap(), HashMap::from_iter([(old, file)])).emit(); Ok(ManagerProxy::hover(Some(new))) } diff --git a/yazi-core/src/manager/linked.rs b/yazi-core/src/manager/linked.rs index 9d688feb..c29fc201 100644 --- a/yazi-core/src/manager/linked.rs +++ b/yazi-core/src/manager/linked.rs @@ -1,12 +1,12 @@ -use std::{collections::BTreeMap, ops::{Deref, DerefMut}}; +use std::{collections::HashMap, ops::{Deref, DerefMut}}; use yazi_shared::fs::Url; #[derive(Default)] -pub struct Linked(BTreeMap<Url, Url> /* from ==> to */); +pub struct Linked(HashMap<Url, Url> /* from ==> to */); impl Deref for Linked { - type Target = BTreeMap<Url, Url>; + type Target = HashMap<Url, Url>; fn deref(&self) -> &Self::Target { &self.0 } } diff --git a/yazi-core/src/manager/watcher.rs b/yazi-core/src/manager/watcher.rs index 5aece338..e8b0ecbf 100644 --- a/yazi-core/src/manager/watcher.rs +++ b/yazi-core/src/manager/watcher.rs @@ -1,4 +1,4 @@ -use std::{collections::{BTreeMap, BTreeSet}, sync::Arc, time::{Duration, SystemTime}}; +use std::{collections::{HashMap, HashSet}, sync::Arc, time::{Duration, SystemTime}}; use anyhow::Result; use notify::{event::{MetadataKind, ModifyKind}, EventKind, RecommendedWatcher, RecursiveMode, Watcher as _Watcher}; @@ -14,7 +14,7 @@ use crate::folder::{Files, Folder}; pub struct Watcher { watcher: RecommendedWatcher, - watched: Arc<RwLock<BTreeSet<Url>>>, + watched: Arc<RwLock<HashSet<Url>>>, pub linked: Arc<RwLock<Linked>>, } @@ -60,11 +60,11 @@ impl Watcher { instance } - pub(super) fn watch(&mut self, mut new: BTreeSet<&Url>) { + pub(super) fn watch(&mut self, mut new: HashSet<&Url>) { new.retain(|&u| u.is_regular()); - let (to_unwatch, to_watch): (BTreeSet<_>, BTreeSet<_>) = { + let (to_unwatch, to_watch): (HashSet<_>, HashSet<_>) = { let guard = self.watched.read(); - let old: BTreeSet<_> = guard.iter().collect(); + let old: HashSet<_> = guard.iter().collect(); ( old.difference(&new).map(|&x| x.clone()).collect(), new.difference(&old).map(|&x| x.clone()).collect(), @@ -147,7 +147,7 @@ impl Watcher { pin!(rx); while let Some(urls) = rx.next().await { - let urls: BTreeSet<_> = urls.into_iter().collect(); + let urls: HashSet<_> = urls.into_iter().collect(); let mut reload = Vec::with_capacity(urls.len()); for u in urls { @@ -163,7 +163,7 @@ impl Watcher { if !file.is_dir() { reload.push(file.clone()); } - FilesOp::Upserting(parent, BTreeMap::from_iter([(u, file)])).emit(); + FilesOp::Upserting(parent, HashMap::from_iter([(u, file)])).emit(); } if reload.is_empty() { diff --git a/yazi-core/src/tab/commands/visual_mode.rs b/yazi-core/src/tab/commands/visual_mode.rs index 8e19ace5..6d618525 100644 --- a/yazi-core/src/tab/commands/visual_mode.rs +++ b/yazi-core/src/tab/commands/visual_mode.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeSet; +use std::collections::HashSet; use yazi_shared::{event::Cmd, render}; @@ -18,9 +18,9 @@ impl Tab { let idx = self.current.cursor; if opt.unset { - self.mode = Mode::Unset(idx, BTreeSet::from([idx])); + self.mode = Mode::Unset(idx, HashSet::from([idx])); } else { - self.mode = Mode::Select(idx, BTreeSet::from([idx])); + self.mode = Mode::Select(idx, HashSet::from([idx])); }; render!(); } diff --git a/yazi-core/src/tab/finder.rs b/yazi-core/src/tab/finder.rs index 72239ce9..2da8571a 100644 --- a/yazi-core/src/tab/finder.rs +++ b/yazi-core/src/tab/finder.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeMap; +use std::collections::HashMap; use anyhow::Result; use yazi_shared::fs::Url; @@ -7,7 +7,7 @@ use crate::folder::{Files, Filter, FilterCase}; pub struct Finder { pub filter: Filter, - matched: BTreeMap<Url, u8>, + matched: HashMap<Url, u8>, revision: u64, } @@ -63,7 +63,7 @@ impl Finder { impl Finder { #[inline] - pub fn matched(&self) -> &BTreeMap<Url, u8> { &self.matched } + pub fn matched(&self) -> &HashMap<Url, u8> { &self.matched } #[inline] pub fn matched_idx(&self, url: &Url) -> Option<u8> { self.matched.get(url).copied() } diff --git a/yazi-core/src/tab/mode.rs b/yazi-core/src/tab/mode.rs index 05c8d8e5..98f27139 100644 --- a/yazi-core/src/tab/mode.rs +++ b/yazi-core/src/tab/mode.rs @@ -1,15 +1,15 @@ -use std::{collections::BTreeSet, fmt::Display, mem}; +use std::{collections::HashSet, fmt::Display, mem}; #[derive(Clone, Debug, Default, Eq, PartialEq)] pub enum Mode { #[default] Normal, - Select(usize, BTreeSet<usize>), - Unset(usize, BTreeSet<usize>), + Select(usize, HashSet<usize>), + Unset(usize, HashSet<usize>), } impl Mode { - pub fn visual_mut(&mut self) -> Option<(usize, &mut BTreeSet<usize>)> { + pub fn visual_mut(&mut self) -> Option<(usize, &mut HashSet<usize>)> { match self { Mode::Normal => None, Mode::Select(start, indices) => Some((*start, indices)), @@ -17,7 +17,7 @@ impl Mode { } } - pub fn take_visual(&mut self) -> Option<(usize, BTreeSet<usize>)> { + pub fn take_visual(&mut self) -> Option<(usize, HashSet<usize>)> { match mem::take(self) { Mode::Normal => None, Mode::Select(start, indices) => Some((start, indices)), diff --git a/yazi-core/src/tab/selected.rs b/yazi-core/src/tab/selected.rs index 86bcd0d6..18e56f66 100644 --- a/yazi-core/src/tab/selected.rs +++ b/yazi-core/src/tab/selected.rs @@ -1,15 +1,15 @@ -use std::{collections::{BTreeSet, HashMap}, ops::Deref}; +use std::{collections::{HashMap, HashSet}, ops::Deref}; use yazi_shared::fs::Url; #[derive(Default)] pub struct Selected { - inner: BTreeSet<Url>, + inner: HashSet<Url>, parents: HashMap<Url, usize>, } impl Deref for Selected { - type Target = BTreeSet<Url>; + type Target = HashSet<Url>; fn deref(&self) -> &Self::Target { &self.inner } } diff --git a/yazi-core/src/tab/tab.rs b/yazi-core/src/tab/tab.rs index 42445a09..0a36c1f4 100644 --- a/yazi-core/src/tab/tab.rs +++ b/yazi-core/src/tab/tab.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeMap; +use std::collections::HashMap; use anyhow::Result; use tokio::task::JoinHandle; @@ -14,7 +14,7 @@ pub struct Tab { pub parent: Option<Folder>, pub backstack: Backstack<Url>, - pub history: BTreeMap<Url, Folder>, + pub history: HashMap<Url, Folder>, pub selected: Selected, pub preview: Preview, diff --git a/yazi-core/src/tasks/tasks.rs b/yazi-core/src/tasks/tasks.rs index 22f6a6b8..5d8d20ae 100644 --- a/yazi-core/src/tasks/tasks.rs +++ b/yazi-core/src/tasks/tasks.rs @@ -1,4 +1,4 @@ -use std::{collections::{BTreeMap, HashMap, HashSet}, ffi::OsStr, mem, sync::Arc, time::Duration}; +use std::{collections::{HashMap, HashSet}, ffi::OsStr, mem, sync::Arc, time::Duration}; use tokio::time::sleep; use tracing::debug; @@ -57,7 +57,7 @@ impl Tasks { } pub fn file_open(&self, hovered: &Url, targets: &[(Url, String)]) { - let mut openers = BTreeMap::new(); + let mut openers = HashMap::new(); for (url, mime) in targets { if let Some(opener) = OPEN.openers(url, mime).and_then(|o| o.first().copied()) { openers.entry(opener).or_insert_with(|| vec![hovered]).push(url); diff --git a/yazi-fm/src/lives/iter.rs b/yazi-fm/src/lives/iter.rs new file mode 100644 index 00000000..4b0e0989 --- /dev/null +++ b/yazi-fm/src/lives/iter.rs @@ -0,0 +1,25 @@ +use mlua::AnyUserData; + +use super::SCOPE; + +pub(super) struct Iter<I: Iterator<Item = T>, T> { + inner: I, + count: usize, +} + +impl<I: Iterator<Item = T> + 'static, T: 'static> Iter<I, T> { + #[inline] + pub(super) fn make(inner: I) -> mlua::Result<AnyUserData<'static>> { + SCOPE.create_any_userdata(Self { inner, count: 0 }) + } +} + +impl<I: Iterator<Item = T>, T> Iterator for Iter<I, T> { + type Item = (usize, T); + + fn next(&mut self) -> Option<Self::Item> { + let next = self.inner.next()?; + self.count += 1; + Some((self.count, next)) + } +} diff --git a/yazi-fm/src/lives/lives.rs b/yazi-fm/src/lives/lives.rs index 3cbc9b5d..03e12cad 100644 --- a/yazi-fm/src/lives/lives.rs +++ b/yazi-fm/src/lives/lives.rs @@ -45,7 +45,7 @@ impl Lives { ("active", super::Tab::make(cx.manager.active())?), ("tabs", super::Tabs::make(&cx.manager.tabs)?), ("tasks", super::Tasks::make(&cx.tasks)?), - ("yanked", scope.create_any_userdata_ref(&cx.manager.yanked)?), + ("yanked", super::Yanked::make(&cx.manager.yanked)?), ])?, )?; diff --git a/yazi-fm/src/lives/mod.rs b/yazi-fm/src/lives/mod.rs index 52e6ff63..d910d4c7 100644 --- a/yazi-fm/src/lives/mod.rs +++ b/yazi-fm/src/lives/mod.rs @@ -4,6 +4,7 @@ mod config; mod file; mod files; mod folder; +mod iter; mod lives; mod mode; mod preview; @@ -17,6 +18,7 @@ use config::*; use file::*; use files::*; use folder::*; +use iter::*; pub(super) use lives::*; use mode::*; use preview::*; diff --git a/yazi-fm/src/lives/selected.rs b/yazi-fm/src/lives/selected.rs index 29fbfb34..57f7e16e 100644 --- a/yazi-fm/src/lives/selected.rs +++ b/yazi-fm/src/lives/selected.rs @@ -1,24 +1,24 @@ -use std::{collections::{btree_set, BTreeSet}, ops::Deref}; +use std::{collections::{hash_set, HashSet}, ops::Deref}; use mlua::{AnyUserData, IntoLuaMulti, Lua, MetaMethod, UserDataMethods, UserDataRefMut}; use yazi_plugin::{bindings::Cast, url::Url}; -use super::SCOPE; +use super::{Iter, SCOPE}; #[derive(Clone, Copy)] pub(super) struct Selected { - inner: *const BTreeSet<yazi_shared::fs::Url>, + inner: *const HashSet<yazi_shared::fs::Url>, } impl Deref for Selected { - type Target = BTreeSet<yazi_shared::fs::Url>; + type Target = HashSet<yazi_shared::fs::Url>; fn deref(&self) -> &Self::Target { self.inner() } } impl Selected { #[inline] - pub(crate) fn make(inner: &BTreeSet<yazi_shared::fs::Url>) -> mlua::Result<AnyUserData<'static>> { + pub(super) fn make(inner: &HashSet<yazi_shared::fs::Url>) -> mlua::Result<AnyUserData<'static>> { SCOPE.create_any_userdata(Self { inner }) } @@ -27,16 +27,17 @@ impl Selected { reg.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.len())); reg.add_meta_method(MetaMethod::Pairs, |lua, me, ()| { - let iter = lua.create_function(|lua, mut iter: UserDataRefMut<SelectedIter>| { - if let Some(url) = iter.inner.next() { - iter.next += 1; - (iter.next, Url::cast(lua, url.clone())?).into_lua_multi(lua) - } else { - ().into_lua_multi(lua) - } - })?; + let iter = lua.create_function( + |lua, mut iter: UserDataRefMut<Iter<hash_set::Iter<yazi_shared::fs::Url>, _>>| { + if let Some(next) = iter.next() { + (next.0, Url::cast(lua, next.1.clone())?).into_lua_multi(lua) + } else { + ().into_lua_multi(lua) + } + }, + )?; - Ok((iter, SelectedIter::make(me.inner()))) + Ok((iter, Iter::make(me.inner().iter()))) }); })?; @@ -44,17 +45,5 @@ impl Selected { } #[inline] - fn inner(&self) -> &'static BTreeSet<yazi_shared::fs::Url> { unsafe { &*self.inner } } -} - -struct SelectedIter { - next: usize, - inner: btree_set::Iter<'static, yazi_shared::fs::Url>, -} - -impl SelectedIter { - #[inline] - fn make(selected: &'static BTreeSet<yazi_shared::fs::Url>) -> mlua::Result<AnyUserData<'static>> { - SCOPE.create_any_userdata(Self { next: 0, inner: selected.iter() }) - } + fn inner(&self) -> &'static HashSet<yazi_shared::fs::Url> { unsafe { &*self.inner } } } diff --git a/yazi-fm/src/lives/tasks.rs b/yazi-fm/src/lives/tasks.rs index cc83fe6b..481e7004 100644 --- a/yazi-fm/src/lives/tasks.rs +++ b/yazi-fm/src/lives/tasks.rs @@ -16,7 +16,7 @@ impl Deref for Tasks { impl Tasks { #[inline] - pub(crate) fn make(inner: &yazi_core::tasks::Tasks) -> mlua::Result<AnyUserData<'static>> { + pub(super) fn make(inner: &yazi_core::tasks::Tasks) -> mlua::Result<AnyUserData<'static>> { SCOPE.create_any_userdata(Self { inner }) } diff --git a/yazi-fm/src/lives/yanked.rs b/yazi-fm/src/lives/yanked.rs index 3051ecae..9c35b79b 100644 --- a/yazi-fm/src/lives/yanked.rs +++ b/yazi-fm/src/lives/yanked.rs @@ -1,13 +1,48 @@ -use mlua::{Lua, MetaMethod, UserDataFields, UserDataMethods}; +use std::{collections::hash_set, ops::Deref}; -pub(super) struct Yanked; +use mlua::{AnyUserData, IntoLuaMulti, Lua, MetaMethod, UserDataFields, UserDataMethods, UserDataRefMut}; +use yazi_plugin::{bindings::Cast, url::Url}; + +use super::{Iter, SCOPE}; + +pub(super) struct Yanked { + inner: *const yazi_core::manager::Yanked, +} + +impl Deref for Yanked { + type Target = yazi_core::manager::Yanked; + + fn deref(&self) -> &Self::Target { self.inner() } +} impl Yanked { + #[inline] + pub(super) fn make(inner: &yazi_core::manager::Yanked) -> mlua::Result<AnyUserData<'static>> { + SCOPE.create_any_userdata(Self { inner }) + } + pub(super) fn register(lua: &Lua) -> mlua::Result<()> { - lua.register_userdata_type::<yazi_core::manager::Yanked>(|reg| { + lua.register_userdata_type::<Self>(|reg| { reg.add_field_method_get("is_cut", |_, me| Ok(me.cut)); reg.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.len())); + + reg.add_meta_method(MetaMethod::Pairs, |lua, me, ()| { + let iter = lua.create_function( + |lua, mut iter: UserDataRefMut<Iter<hash_set::Iter<yazi_shared::fs::Url>, _>>| { + if let Some(next) = iter.next() { + (next.0, Url::cast(lua, next.1.clone())?).into_lua_multi(lua) + } else { + ().into_lua_multi(lua) + } + }, + )?; + + Ok((iter, Iter::make(me.inner().iter()))) + }); }) } + + #[inline] + fn inner(&self) -> &'static yazi_core::manager::Yanked { unsafe { &*self.inner } } } diff --git a/yazi-plugin/src/loader.rs b/yazi-plugin/src/loader.rs index 3408b418..b8b20443 100644 --- a/yazi-plugin/src/loader.rs +++ b/yazi-plugin/src/loader.rs @@ -1,4 +1,4 @@ -use std::{borrow::Cow, collections::BTreeMap, ops::Deref}; +use std::{borrow::Cow, collections::HashMap, ops::Deref}; use anyhow::{bail, Result}; use mlua::{ExternalError, Table}; @@ -13,7 +13,7 @@ pub static LOADED: RoCell<Loader> = RoCell::new(); #[derive(Default)] pub struct Loader { - loaded: RwLock<BTreeMap<String, Vec<u8>>>, + loaded: RwLock<HashMap<String, Vec<u8>>>, } impl Loader { @@ -67,7 +67,7 @@ impl Loader { } impl Deref for Loader { - type Target = RwLock<BTreeMap<String, Vec<u8>>>; + type Target = RwLock<HashMap<String, Vec<u8>>>; #[inline] fn deref(&self) -> &Self::Target { &self.loaded } diff --git a/yazi-plugin/src/utils/call.rs b/yazi-plugin/src/utils/call.rs index aa966478..183adf6d 100644 --- a/yazi-plugin/src/utils/call.rs +++ b/yazi-plugin/src/utils/call.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeMap; +use std::collections::HashMap; use mlua::{ExternalError, Lua, Table, Value}; use yazi_shared::{emit, event::Cmd, render, Layer}; @@ -7,9 +7,9 @@ use super::Utils; use crate::ValueSendable; impl Utils { - fn parse_args(t: Table) -> mlua::Result<(Vec<String>, BTreeMap<String, String>)> { + fn parse_args(t: Table) -> mlua::Result<(Vec<String>, HashMap<String, String>)> { let mut args = vec![]; - let mut named = BTreeMap::new(); + let mut named = HashMap::new(); for result in t.pairs::<Value, Value>() { let (k, v) = result?; match k { diff --git a/yazi-scheduler/src/preload/preload.rs b/yazi-scheduler/src/preload/preload.rs index 19f49257..5c73a8fc 100644 --- a/yazi-scheduler/src/preload/preload.rs +++ b/yazi-scheduler/src/preload/preload.rs @@ -1,4 +1,4 @@ -use std::collections::{BTreeMap, BTreeSet, HashMap}; +use std::collections::{HashMap, HashSet}; use anyhow::Result; use parking_lot::RwLock; @@ -16,7 +16,7 @@ pub struct Preload { prog: mpsc::UnboundedSender<TaskProg>, pub rule_loaded: RwLock<HashMap<Url, u32>>, - pub size_loading: RwLock<BTreeSet<Url>>, + pub size_loading: RwLock<HashSet<Url>>, } impl Preload { @@ -60,7 +60,7 @@ impl Preload { } let parent = buf[0].0.parent_url().unwrap(); - FilesOp::Size(parent, BTreeMap::from_iter(buf)).emit(); + FilesOp::Size(parent, HashMap::from_iter(buf)).emit(); }); self.prog.send(TaskProg::Adv(task.id, 1, 0))?; } diff --git a/yazi-scheduler/src/running.rs b/yazi-scheduler/src/running.rs index 8f771f0a..86298d3c 100644 --- a/yazi-scheduler/src/running.rs +++ b/yazi-scheduler/src/running.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeMap; +use std::collections::HashMap; use futures::future::BoxFuture; use yazi_config::TASKS; @@ -10,9 +10,8 @@ use crate::TaskKind; pub struct Running { incr: usize, - pub(super) hooks: - BTreeMap<usize, Box<dyn (FnOnce(bool) -> BoxFuture<'static, ()>) + Send + Sync>>, - pub(super) all: BTreeMap<usize, Task>, + pub(super) hooks: HashMap<usize, Box<dyn (FnOnce(bool) -> BoxFuture<'static, ()>) + Send + Sync>>, + pub(super) all: HashMap<usize, Task>, } impl Running { diff --git a/yazi-shared/src/event/cmd.rs b/yazi-shared/src/event/cmd.rs index c519dd6b..f37c1941 100644 --- a/yazi-shared/src/event/cmd.rs +++ b/yazi-shared/src/event/cmd.rs @@ -1,10 +1,10 @@ -use std::{any::Any, collections::BTreeMap, fmt::{self, Display}, mem}; +use std::{any::Any, collections::HashMap, fmt::{self, Display}, mem}; #[derive(Debug, Default)] pub struct Cmd { pub name: String, pub args: Vec<String>, - pub named: BTreeMap<String, String>, + pub named: HashMap<String, String>, pub data: Option<Box<dyn Any + Send>>, } diff --git a/yazi-shared/src/fs/op.rs b/yazi-shared/src/fs/op.rs index 61993dce..20d3c3be 100644 --- a/yazi-shared/src/fs/op.rs +++ b/yazi-shared/src/fs/op.rs @@ -1,4 +1,4 @@ -use std::{collections::BTreeMap, sync::atomic::{AtomicU64, Ordering}, time::SystemTime}; +use std::{collections::HashMap, sync::atomic::{AtomicU64, Ordering}, time::SystemTime}; use super::File; use crate::{emit, event::Cmd, fs::Url, Layer}; @@ -10,12 +10,12 @@ pub enum FilesOp { Full(Url, Vec<File>, Option<SystemTime>), Part(Url, Vec<File>, u64), Done(Url, Option<SystemTime>, u64), - Size(Url, BTreeMap<Url, u64>), + Size(Url, HashMap<Url, u64>), Creating(Url, Vec<File>), Deleting(Url, Vec<Url>), - Updating(Url, BTreeMap<Url, File>), - Upserting(Url, BTreeMap<Url, File>), + Updating(Url, HashMap<Url, File>), + Upserting(Url, HashMap<Url, File>), } impl FilesOp {