diff --git a/Cargo.lock b/Cargo.lock index c18485dd2..73f9a7a5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3453,6 +3453,7 @@ dependencies = [ "regex", "serde", "toml", + "tracing", "validator", "yazi-macro", "yazi-shared", diff --git a/yazi-config/Cargo.toml b/yazi-config/Cargo.toml index 59419a873..e6037f099 100644 --- a/yazi-config/Cargo.toml +++ b/yazi-config/Cargo.toml @@ -22,6 +22,7 @@ ratatui = { workspace = true } regex = { workspace = true } serde = { workspace = true } toml = { version = "0.8.19", features = [ "preserve_order" ] } +tracing = { workspace = true } validator = { version = "0.19.0", features = [ "derive" ] } [target.'cfg(target_os = "macos")'.dependencies] diff --git a/yazi-config/preset/keymap.toml b/yazi-config/preset/keymap.toml index 0a38f6540..393ad20ed 100644 --- a/yazi-config/preset/keymap.toml +++ b/yazi-config/preset/keymap.toml @@ -79,8 +79,8 @@ keymap = [ { on = ";", run = "shell --interactive", desc = "Run a shell command" }, { on = ":", run = "shell --block --interactive", desc = "Run a shell command (block until finishes)" }, { on = ".", run = "hidden toggle", desc = "Toggle the visibility of hidden files" }, - { on = "s", run = "search fd", desc = "Search files by name via fd" }, - { on = "S", run = "search rg", desc = "Search files by content via ripgrep" }, + { on = "s", run = "search --via=fd", desc = "Search files by name via fd" }, + { on = "S", run = "search --via=rg", desc = "Search files by content via ripgrep" }, { on = "", run = "escape --search", desc = "Cancel the ongoing search" }, { on = "z", run = "plugin zoxide", desc = "Jump to a directory via zoxide" }, { on = "Z", run = "plugin fzf", desc = "Jump to a file/directory via fzf" }, diff --git a/yazi-config/src/plugin/plugin.rs b/yazi-config/src/plugin/plugin.rs index 5ffd1d9ab..279dd3e4a 100644 --- a/yazi-config/src/plugin/plugin.rs +++ b/yazi-config/src/plugin/plugin.rs @@ -2,6 +2,8 @@ use std::{collections::HashSet, path::Path, str::FromStr}; use anyhow::Context; use serde::{Deserialize, Deserializer}; +use tracing::warn; +use yazi_shared::fs::File; use super::{Fetcher, Preloader, Previewer, Spotter}; use crate::{Preset, plugin::MAX_PREWORKERS}; @@ -30,6 +32,27 @@ impl Plugin { }) } + pub fn mime_fetchers(&self, files: Vec) -> impl Iterator)> { + let mut tasks: [Vec<_>; MAX_PREWORKERS as usize] = Default::default(); + for f in files { + let factors = |s: &str| match s { + "dummy" => f.cha.is_dummy(), + _ => false, + }; + + let found = self.fetchers.iter().find(|&g| g.id == "mime" && g.matches(&f.url, "", factors)); + if let Some(g) = found { + tasks[g.idx as usize].push(f); + } else { + warn!("No mime fetcher for {f:?}"); + } + } + + tasks.into_iter().enumerate().filter_map(|(i, tasks)| { + if tasks.is_empty() { None } else { Some((&self.fetchers[i], tasks)) } + }) + } + #[inline] pub fn fetchers_mask(&self) -> u32 { self.fetchers.iter().fold(0, |n, f| if f.mime.is_some() { n } else { n | 1 << f.idx as u32 }) diff --git a/yazi-core/src/manager/commands/open.rs b/yazi-core/src/manager/commands/open.rs index fc97aea6f..7e8a93803 100644 --- a/yazi-core/src/manager/commands/open.rs +++ b/yazi-core/src/manager/commands/open.rs @@ -2,12 +2,12 @@ use std::{borrow::Cow, ffi::OsString}; use tracing::error; use yazi_boot::ARGS; -use yazi_config::{OPEN, popup::PickCfg}; +use yazi_config::{OPEN, PLUGIN, popup::PickCfg}; use yazi_fs::Folder; use yazi_macro::emit; use yazi_plugin::isolate; use yazi_proxy::{ManagerProxy, TasksProxy, options::OpenDoOpt}; -use yazi_shared::{MIME_DIR, event::{Cmd, CmdCow, EventQuit}, fs::{File, Url}}; +use yazi_shared::{MIME_DIR, event::{CmdCow, EventQuit}, fs::{File, Url}}; use crate::{manager::Manager, tasks::Tasks}; @@ -65,8 +65,10 @@ impl Manager { } done.extend(files.iter().map(|f| (f.url_owned(), String::new()))); - if let Err(e) = isolate::fetch(Cmd::new("mime").into(), files).await { - error!("Fetch `mime` failed in opening: {e}"); + for (fetcher, files) in PLUGIN.mime_fetchers(files) { + if let Err(e) = isolate::fetch(CmdCow::from(&fetcher.run), files).await { + error!("Fetch mime failed on opening: {e}"); + } } ManagerProxy::open_do(OpenDoOpt { hovered, targets: done, interactive: opt.interactive }); diff --git a/yazi-core/src/manager/watcher.rs b/yazi-core/src/manager/watcher.rs index 8cf38b01c..bc6935616 100644 --- a/yazi-core/src/manager/watcher.rs +++ b/yazi-core/src/manager/watcher.rs @@ -6,10 +6,11 @@ use parking_lot::RwLock; use tokio::{fs, pin, sync::{mpsc::{self, UnboundedReceiver}, watch}}; use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream}; use tracing::error; +use yazi_config::PLUGIN; use yazi_fs::{Files, Folder}; use yazi_plugin::isolate; use yazi_proxy::WATCHER; -use yazi_shared::{RoCell, event::Cmd, fs::{Cha, File, FilesOp, Url, realname_unchecked}}; +use yazi_shared::{RoCell, event::CmdCow, fs::{Cha, File, FilesOp, Url, realname_unchecked}}; use super::Linked; @@ -151,8 +152,10 @@ impl Watcher { } FilesOp::mutate(ops); - if let Err(e) = isolate::fetch(Cmd::new("mime").into(), reload).await { - error!("Fetch `mime` failed in watcher: {e}"); + for (fetcher, files) in PLUGIN.mime_fetchers(reload) { + if let Err(e) = isolate::fetch(CmdCow::from(&fetcher.run), files).await { + error!("Fetch mime failed in watcher: {e}"); + } } } } diff --git a/yazi-core/src/tasks/preload.rs b/yazi-core/src/tasks/preload.rs index e9dd506bc..5da217989 100644 --- a/yazi-core/src/tasks/preload.rs +++ b/yazi-core/src/tasks/preload.rs @@ -17,13 +17,13 @@ impl Tasks { _ => false, }; - for p in PLUGIN.fetchers(&f.url, mime, factors) { + for g in PLUGIN.fetchers(&f.url, mime, factors) { match loaded.get_mut(&f.url) { - Some(n) if *n & (1 << p.idx) != 0 => continue, - Some(n) => *n |= 1 << p.idx, - None => _ = loaded.insert(f.url_owned(), 1 << p.idx), + Some(n) if *n & (1 << g.idx) != 0 => continue, + Some(n) => *n |= 1 << g.idx, + None => _ = loaded.insert(f.url_owned(), 1 << g.idx), } - tasks[p.idx as usize].push(f.clone()); + tasks[g.idx as usize].push(f.clone()); } }