mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: true custom mime fetcher support - using user rules even during open or in watcher (#1976)
This commit is contained in:
parent
d72f90356b
commit
4194befb88
7 changed files with 44 additions and 14 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -3453,6 +3453,7 @@ dependencies = [
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
"toml",
|
"toml",
|
||||||
|
"tracing",
|
||||||
"validator",
|
"validator",
|
||||||
"yazi-macro",
|
"yazi-macro",
|
||||||
"yazi-shared",
|
"yazi-shared",
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ ratatui = { workspace = true }
|
||||||
regex = { workspace = true }
|
regex = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
toml = { version = "0.8.19", features = [ "preserve_order" ] }
|
toml = { version = "0.8.19", features = [ "preserve_order" ] }
|
||||||
|
tracing = { workspace = true }
|
||||||
validator = { version = "0.19.0", features = [ "derive" ] }
|
validator = { version = "0.19.0", features = [ "derive" ] }
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
|
|
|
||||||
|
|
@ -79,8 +79,8 @@ keymap = [
|
||||||
{ on = ";", run = "shell --interactive", desc = "Run a shell command" },
|
{ on = ";", run = "shell --interactive", desc = "Run a shell command" },
|
||||||
{ on = ":", run = "shell --block --interactive", desc = "Run a shell command (block until finishes)" },
|
{ 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 = ".", 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 --via=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=rg", desc = "Search files by content via ripgrep" },
|
||||||
{ on = "<C-s>", run = "escape --search", desc = "Cancel the ongoing search" },
|
{ on = "<C-s>", run = "escape --search", desc = "Cancel the ongoing search" },
|
||||||
{ on = "z", run = "plugin zoxide", desc = "Jump to a directory via zoxide" },
|
{ 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" },
|
{ on = "Z", run = "plugin fzf", desc = "Jump to a file/directory via fzf" },
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ use std::{collections::HashSet, path::Path, str::FromStr};
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
|
use tracing::warn;
|
||||||
|
use yazi_shared::fs::File;
|
||||||
|
|
||||||
use super::{Fetcher, Preloader, Previewer, Spotter};
|
use super::{Fetcher, Preloader, Previewer, Spotter};
|
||||||
use crate::{Preset, plugin::MAX_PREWORKERS};
|
use crate::{Preset, plugin::MAX_PREWORKERS};
|
||||||
|
|
@ -30,6 +32,27 @@ impl Plugin {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn mime_fetchers(&self, files: Vec<File>) -> impl Iterator<Item = (&Fetcher, Vec<File>)> {
|
||||||
|
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]
|
#[inline]
|
||||||
pub fn fetchers_mask(&self) -> u32 {
|
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 })
|
self.fetchers.iter().fold(0, |n, f| if f.mime.is_some() { n } else { n | 1 << f.idx as u32 })
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,12 @@ use std::{borrow::Cow, ffi::OsString};
|
||||||
|
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
use yazi_boot::ARGS;
|
use yazi_boot::ARGS;
|
||||||
use yazi_config::{OPEN, popup::PickCfg};
|
use yazi_config::{OPEN, PLUGIN, popup::PickCfg};
|
||||||
use yazi_fs::Folder;
|
use yazi_fs::Folder;
|
||||||
use yazi_macro::emit;
|
use yazi_macro::emit;
|
||||||
use yazi_plugin::isolate;
|
use yazi_plugin::isolate;
|
||||||
use yazi_proxy::{ManagerProxy, TasksProxy, options::OpenDoOpt};
|
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};
|
use crate::{manager::Manager, tasks::Tasks};
|
||||||
|
|
||||||
|
|
@ -65,8 +65,10 @@ impl Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
done.extend(files.iter().map(|f| (f.url_owned(), String::new())));
|
done.extend(files.iter().map(|f| (f.url_owned(), String::new())));
|
||||||
if let Err(e) = isolate::fetch(Cmd::new("mime").into(), files).await {
|
for (fetcher, files) in PLUGIN.mime_fetchers(files) {
|
||||||
error!("Fetch `mime` failed in opening: {e}");
|
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 });
|
ManagerProxy::open_do(OpenDoOpt { hovered, targets: done, interactive: opt.interactive });
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,11 @@ use parking_lot::RwLock;
|
||||||
use tokio::{fs, pin, sync::{mpsc::{self, UnboundedReceiver}, watch}};
|
use tokio::{fs, pin, sync::{mpsc::{self, UnboundedReceiver}, watch}};
|
||||||
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
|
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
use yazi_config::PLUGIN;
|
||||||
use yazi_fs::{Files, Folder};
|
use yazi_fs::{Files, Folder};
|
||||||
use yazi_plugin::isolate;
|
use yazi_plugin::isolate;
|
||||||
use yazi_proxy::WATCHER;
|
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;
|
use super::Linked;
|
||||||
|
|
||||||
|
|
@ -151,8 +152,10 @@ impl Watcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
FilesOp::mutate(ops);
|
FilesOp::mutate(ops);
|
||||||
if let Err(e) = isolate::fetch(Cmd::new("mime").into(), reload).await {
|
for (fetcher, files) in PLUGIN.mime_fetchers(reload) {
|
||||||
error!("Fetch `mime` failed in watcher: {e}");
|
if let Err(e) = isolate::fetch(CmdCow::from(&fetcher.run), files).await {
|
||||||
|
error!("Fetch mime failed in watcher: {e}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,13 @@ impl Tasks {
|
||||||
_ => false,
|
_ => 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) {
|
match loaded.get_mut(&f.url) {
|
||||||
Some(n) if *n & (1 << p.idx) != 0 => continue,
|
Some(n) if *n & (1 << g.idx) != 0 => continue,
|
||||||
Some(n) => *n |= 1 << p.idx,
|
Some(n) => *n |= 1 << g.idx,
|
||||||
None => _ = loaded.insert(f.url_owned(), 1 << p.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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue