From a1fcd86cbcbf70fc27650a561b29b570f413db9e Mon Sep 17 00:00:00 2001 From: sxyazi Date: Fri, 29 Dec 2023 21:48:26 +0800 Subject: [PATCH] .. --- cspell.json | 2 +- yazi-config/preset/yazi.toml | 2 +- yazi-config/src/lib.rs | 2 + yazi-config/src/plugin/mod.rs | 2 + yazi-config/src/plugin/plugin.rs | 4 +- yazi-config/src/plugin/props.rs | 16 +++++ yazi-config/src/priority.rs | 32 ++++++++++ yazi-core/src/tab/preview.rs | 6 +- yazi-scheduler/src/file/mod.rs | 2 + yazi-scheduler/src/lib.rs | 6 +- yazi-scheduler/src/plugin/mod.rs | 2 + yazi-scheduler/src/plugin/plugin.rs | 5 +- yazi-scheduler/src/preload/mod.rs | 2 + yazi-scheduler/src/preload/op.rs | 9 ++- yazi-scheduler/src/preload/preload.rs | 84 ++++++++++++++------------- yazi-scheduler/src/process/mod.rs | 2 + yazi-scheduler/src/scheduler.rs | 7 +-- 17 files changed, 126 insertions(+), 59 deletions(-) create mode 100644 yazi-config/src/plugin/props.rs create mode 100644 yazi-config/src/priority.rs diff --git a/cspell.json b/cspell.json index 07e982c0..933340ab 100644 --- a/cspell.json +++ b/cspell.json @@ -1 +1 @@ -{"language":"en","flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting"],"version":"0.2"} +{"language":"en","words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio"],"version":"0.2","flagWords":[]} diff --git a/yazi-config/preset/yazi.toml b/yazi-config/preset/yazi.toml index bd5b4439..8425278d 100644 --- a/yazi-config/preset/yazi.toml +++ b/yazi-config/preset/yazi.toml @@ -77,7 +77,7 @@ suppress_preload = false [plugin] preloaders = [ - { name = "*", cond = "!mime", exec = "mime.lua", multi = true }, + { name = "*", cond = "!mime", exec = "mime.lua", multi = true, prio = "high" }, # Image { mime = "image/vnd.djvu", exec = "noop.lua" }, { mime = "image/*", exec = "image.lua" }, diff --git a/yazi-config/src/lib.rs b/yazi-config/src/lib.rs index e71004f8..3347986c 100644 --- a/yazi-config/src/lib.rs +++ b/yazi-config/src/lib.rs @@ -13,6 +13,7 @@ pub mod plugin; pub mod popup; mod preset; pub mod preview; +mod priority; mod tasks; pub mod theme; mod validation; @@ -21,6 +22,7 @@ mod xdg; pub use layout::*; pub(crate) use pattern::*; pub(crate) use preset::*; +pub use priority::*; pub(crate) use xdg::*; pub static ARGS: RoCell = RoCell::new(); diff --git a/yazi-config/src/plugin/mod.rs b/yazi-config/src/plugin/mod.rs index af03fb09..ec375606 100644 --- a/yazi-config/src/plugin/mod.rs +++ b/yazi-config/src/plugin/mod.rs @@ -1,7 +1,9 @@ mod exec; mod plugin; +mod props; pub use exec::*; pub use plugin::*; +pub use props::*; pub const MAX_PRELOADERS: u8 = 32; diff --git a/yazi-config/src/plugin/plugin.rs b/yazi-config/src/plugin/plugin.rs index 83eb47ef..34cf4645 100644 --- a/yazi-config/src/plugin/plugin.rs +++ b/yazi-config/src/plugin/plugin.rs @@ -3,7 +3,7 @@ use std::path::Path; use serde::Deserialize; use yazi_shared::{event::Exec, Condition, MIME_DIR}; -use crate::{pattern::Pattern, plugin::MAX_PRELOADERS, MERGED_YAZI}; +use crate::{pattern::Pattern, plugin::MAX_PRELOADERS, Priority, MERGED_YAZI}; #[derive(Deserialize)] pub struct Plugin { @@ -24,6 +24,8 @@ pub struct PluginRule { pub sync: bool, #[serde(default)] pub multi: bool, + #[serde(default)] + pub prio: Priority, } impl Default for Plugin { diff --git a/yazi-config/src/plugin/props.rs b/yazi-config/src/plugin/props.rs new file mode 100644 index 00000000..80a8196c --- /dev/null +++ b/yazi-config/src/plugin/props.rs @@ -0,0 +1,16 @@ +use super::PluginRule; +use crate::Priority; + +#[derive(Debug, Clone)] +pub struct PluginProps { + pub id: u8, + pub cmd: String, + pub multi: bool, + pub prio: Priority, +} + +impl From<&PluginRule> for PluginProps { + fn from(rule: &PluginRule) -> Self { + Self { id: rule.id, cmd: rule.exec.cmd.to_owned(), multi: rule.multi, prio: rule.prio } + } +} diff --git a/yazi-config/src/priority.rs b/yazi-config/src/priority.rs new file mode 100644 index 00000000..50535297 --- /dev/null +++ b/yazi-config/src/priority.rs @@ -0,0 +1,32 @@ +use std::str::FromStr; + +use anyhow::anyhow; +use serde::Deserialize; + +#[derive(Default, Clone, Copy, Debug, Deserialize)] +#[serde(try_from = "String")] +pub enum Priority { + Low = 0, + #[default] + Normal = 1, + High = 2, +} + +impl FromStr for Priority { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + match s { + "low" => Ok(Self::Low), + "normal" => Ok(Self::Normal), + "high" => Ok(Self::High), + _ => Err(anyhow!("Invalid priority: {s}")), + } + } +} + +impl TryFrom for Priority { + type Error = anyhow::Error; + + fn try_from(s: String) -> Result { Self::from_str(&s) } +} diff --git a/yazi-core/src/tab/preview.rs b/yazi-core/src/tab/preview.rs index 54456592..0ab91c79 100644 --- a/yazi-core/src/tab/preview.rs +++ b/yazi-core/src/tab/preview.rs @@ -5,7 +5,7 @@ use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt}; use tokio_util::sync::CancellationToken; use yazi_adaptor::ADAPTOR; use yazi_config::PLUGIN; -use yazi_plugin::{external::Highlighter, utils::PreviewLock}; +use yazi_plugin::{external::Highlighter, isolate, utils::PreviewLock}; use yazi_shared::{fs::{Cha, File, FilesOp, Url}, MIME_DIR}; use crate::folder::Files; @@ -32,9 +32,9 @@ impl Preview { self.abort(); if previewer.sync { - yazi_plugin::isolate::peek_sync(&previewer.exec, file, self.skip); + isolate::peek_sync(&previewer.exec, file, self.skip); } else { - self.previewer_ct = Some(yazi_plugin::isolate::peek(&previewer.exec, file, self.skip)); + self.previewer_ct = Some(isolate::peek(&previewer.exec, file, self.skip)); } } diff --git a/yazi-scheduler/src/file/mod.rs b/yazi-scheduler/src/file/mod.rs index 600b5425..ecb518b7 100644 --- a/yazi-scheduler/src/file/mod.rs +++ b/yazi-scheduler/src/file/mod.rs @@ -1,3 +1,5 @@ +#![allow(clippy::module_inception)] + mod file; mod op; diff --git a/yazi-scheduler/src/lib.rs b/yazi-scheduler/src/lib.rs index a7f92806..9c807796 100644 --- a/yazi-scheduler/src/lib.rs +++ b/yazi-scheduler/src/lib.rs @@ -16,8 +16,8 @@ pub use running::*; pub use scheduler::*; pub use task::*; -const LOW: u8 = 0; -const NORMAL: u8 = 1; -const HIGH: u8 = 2; +const LOW: u8 = yazi_config::Priority::Low as u8; +const NORMAL: u8 = yazi_config::Priority::Normal as u8; +const HIGH: u8 = yazi_config::Priority::High as u8; pub fn init() { init_blocker(); } diff --git a/yazi-scheduler/src/plugin/mod.rs b/yazi-scheduler/src/plugin/mod.rs index dacceffe..4ef84332 100644 --- a/yazi-scheduler/src/plugin/mod.rs +++ b/yazi-scheduler/src/plugin/mod.rs @@ -1,3 +1,5 @@ +#![allow(clippy::module_inception)] + mod op; mod plugin; diff --git a/yazi-scheduler/src/plugin/plugin.rs b/yazi-scheduler/src/plugin/plugin.rs index 9cff8a32..28ebae3d 100644 --- a/yazi-scheduler/src/plugin/plugin.rs +++ b/yazi-scheduler/src/plugin/plugin.rs @@ -1,5 +1,6 @@ use anyhow::Result; use tokio::sync::mpsc; +use yazi_plugin::isolate; use super::{PluginOp, PluginOpEntry}; use crate::{TaskOp, TaskProg, HIGH}; @@ -20,7 +21,7 @@ impl Plugin { pub async fn work(&self, op: PluginOp) -> Result<()> { match op { PluginOp::Entry(task) => { - yazi_plugin::isolate::entry(&task.name).await?; + isolate::entry(&task.name).await?; } } Ok(()) @@ -29,7 +30,7 @@ impl Plugin { pub async fn micro(&self, task: PluginOpEntry) -> Result<()> { self.prog.send(TaskProg::New(task.id, 0))?; - if let Err(e) = yazi_plugin::isolate::entry(&task.name).await { + if let Err(e) = isolate::entry(&task.name).await { self.fail(task.id, format!("Micro plugin failed:\n{e}"))?; return Err(e.into()); } diff --git a/yazi-scheduler/src/preload/mod.rs b/yazi-scheduler/src/preload/mod.rs index d4399138..829ef0e5 100644 --- a/yazi-scheduler/src/preload/mod.rs +++ b/yazi-scheduler/src/preload/mod.rs @@ -1,3 +1,5 @@ +#![allow(clippy::module_inception)] + mod op; mod preload; diff --git a/yazi-scheduler/src/preload/op.rs b/yazi-scheduler/src/preload/op.rs index c0f0b89a..6e4b4d01 100644 --- a/yazi-scheduler/src/preload/op.rs +++ b/yazi-scheduler/src/preload/op.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use yazi_config::plugin::PluginProps; use yazi_shared::{fs::Url, Throttle}; #[derive(Debug)] @@ -19,11 +20,9 @@ impl PreloadOp { #[derive(Clone, Debug)] pub struct PreloadOpRule { - pub id: usize, - pub rule_id: u8, - pub rule_multi: bool, - pub plugin: String, - pub targets: Vec, + pub id: usize, + pub plugin: PluginProps, + pub targets: Vec, } #[derive(Debug)] diff --git a/yazi-scheduler/src/preload/preload.rs b/yazi-scheduler/src/preload/preload.rs index 3ccb9661..14fb7aae 100644 --- a/yazi-scheduler/src/preload/preload.rs +++ b/yazi-scheduler/src/preload/preload.rs @@ -4,10 +4,12 @@ use anyhow::Result; use parking_lot::RwLock; use tokio::sync::mpsc; use tracing::error; +use yazi_config::Priority; +use yazi_plugin::isolate; use yazi_shared::fs::{calculate_size, FilesOp, Url}; use super::{PreloadOp, PreloadOpRule, PreloadOpSize}; -use crate::{TaskOp, TaskProg}; +use crate::{TaskOp, TaskProg, HIGH, NORMAL}; pub struct Preload { macro_: async_priority_channel::Sender, @@ -28,58 +30,62 @@ impl Preload { pub async fn work(&self, op: PreloadOp) -> Result<()> { match op { PreloadOp::Rule(task) => { - todo!() + let urls: Vec<_> = task.targets.iter().map(|f| f.url()).collect(); + let result = isolate::preload(task.plugin.cmd, task.targets, task.plugin.multi).await; + if let Err(e) = result { + self.fail(task.id, format!("Preload task failed:\n{e}"))?; + return Err(e.into()); + }; + + let code = result.unwrap(); + if code & 1 == 0 { + error!("Preload task returned {code}"); + } + if code >> 1 & 1 != 0 { + let mut loaded = self.rule_loaded.write(); + for url in urls { + loaded.get_mut(&url).map(|x| *x ^= 1 << task.plugin.id); + } + } + self.prog.send(TaskProg::Adv(task.id, 1, 0))?; } PreloadOp::Size(task) => { - todo!() + let length = calculate_size(&task.target).await; + task.throttle.done((task.target, length), |buf| { + { + let mut loading = self.size_loading.write(); + for (path, _) in &buf { + loading.remove(path); + } + } + + let parent = buf[0].0.parent_url().unwrap(); + FilesOp::Size(parent, BTreeMap::from_iter(buf)).emit(); + }); + self.prog.send(TaskProg::Adv(task.id, 1, 0))?; } } Ok(()) } pub async fn rule(&self, task: PreloadOpRule) -> Result<()> { - self.prog.send(TaskProg::New(task.id, 0))?; + let id = task.id; + self.prog.send(TaskProg::New(id, 0))?; - let urls: Vec<_> = task.targets.iter().map(|f| f.url()).collect(); - let result = yazi_plugin::isolate::preload(task.plugin, task.targets, task.rule_multi).await; - if let Err(e) = result { - self.fail(task.id, format!("Preload task failed:\n{e}"))?; - return Err(e.into()); - }; - - let code = result.unwrap(); - if code & 1 == 0 { - error!("Preload task returned {code}"); + match task.plugin.prio { + Priority::Low => self.macro_.send(PreloadOp::Rule(task).into(), NORMAL).await?, + Priority::Normal => self.macro_.send(PreloadOp::Rule(task).into(), HIGH).await?, + Priority::High => self.work(PreloadOp::Rule(task)).await?, } - if code >> 1 & 1 != 0 { - let mut loaded = self.rule_loaded.write(); - for url in urls { - loaded.get_mut(&url).map(|x| *x ^= 1 << task.rule_id); - } - } - - self.prog.send(TaskProg::Adv(task.id, 1, 0))?; - self.succ(task.id) + self.succ(id) } pub async fn size(&self, task: PreloadOpSize) -> Result<()> { - self.prog.send(TaskProg::New(task.id, 0))?; + let id = task.id; - let length = calculate_size(&task.target).await; - task.throttle.done((task.target, length), |buf| { - { - let mut loading = self.size_loading.write(); - for (path, _) in &buf { - loading.remove(path); - } - } - - let parent = buf[0].0.parent_url().unwrap(); - FilesOp::Size(parent, BTreeMap::from_iter(buf)).emit(); - }); - - self.prog.send(TaskProg::Adv(task.id, 1, 0))?; - self.succ(task.id) + self.prog.send(TaskProg::New(id, 0))?; + self.work(PreloadOp::Size(task)).await?; + self.succ(id) } } diff --git a/yazi-scheduler/src/process/mod.rs b/yazi-scheduler/src/process/mod.rs index e563de5d..1d72a7b1 100644 --- a/yazi-scheduler/src/process/mod.rs +++ b/yazi-scheduler/src/process/mod.rs @@ -1,3 +1,5 @@ +#![allow(clippy::module_inception)] + mod op; mod process; diff --git a/yazi-scheduler/src/scheduler.rs b/yazi-scheduler/src/scheduler.rs index 1637bbfb..ad0111f9 100644 --- a/yazi-scheduler/src/scheduler.rs +++ b/yazi-scheduler/src/scheduler.rs @@ -312,14 +312,12 @@ impl Scheduler { format!("Run preloader `{}` with {} target(s)", rule.exec.cmd, targets.len()), ); - let (rule_id, rule_multi) = (rule.id, rule.multi); - let cmd = rule.exec.cmd.clone(); + let plugin = rule.into(); let targets = targets.into_iter().cloned().collect(); - let preload = self.preload.clone(); _ = self.micro.try_send( async move { - preload.rule(PreloadOpRule { id, rule_id, rule_multi, plugin: cmd, targets }).await.ok(); + preload.rule(PreloadOpRule { id, plugin, targets }).await.ok(); } .boxed(), HIGH, @@ -329,6 +327,7 @@ impl Scheduler { pub fn preload_size(&self, targets: Vec<&Url>) { let throttle = Arc::new(Throttle::new(targets.len(), Duration::from_millis(300))); let mut running = self.running.write(); + for target in targets { let id = running.add(TaskKind::Preload, format!("Calculate the size of {:?}", target)); let target = target.clone();