Skip to content

Commit

Permalink
feat: add a next property to the preloader rules to allow running m…
Browse files Browse the repository at this point in the history
…ultiple preloaders (#1058)
  • Loading branch information
sxyazi committed May 19, 2024
1 parent 0ff4835 commit bd30756
Show file tree
Hide file tree
Showing 27 changed files with 212 additions and 182 deletions.
9 changes: 5 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion yazi-adaptor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ yazi-config = { path = "../yazi-config", version = "0.2.5" }
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }

# External dependencies
anyhow = "1.0.83"
anyhow = "1.0.86"
arc-swap = "1.7.1"
base64 = "0.22.1"
color_quant = "1.1.0"
Expand Down
4 changes: 2 additions & 2 deletions yazi-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ yazi-dds = { path = "../yazi-dds", version = "0.2.5" }
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }

# External dependencies
anyhow = "1.0.83"
anyhow = "1.0.86"
clap = { version = "4.5.4", features = [ "derive" ] }
crossterm = "0.27.0"
md-5 = "0.10.6"
Expand All @@ -22,7 +22,7 @@ tokio = { version = "1.37.0", features = [ "full" ] }
toml_edit = "0.22.13"

[build-dependencies]
anyhow = "1.0.83"
anyhow = "1.0.86"
clap = { version = "4.5.4", features = [ "derive" ] }
clap_complete = "4.5.2"
clap_complete_fig = "4.5.0"
Expand Down
2 changes: 1 addition & 1 deletion yazi-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ repository = "https://github.com/sxyazi/yazi"
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }

# External dependencies
anyhow = "1.0.83"
anyhow = "1.0.86"
arc-swap = "1.7.1"
crossterm = "0.27.0"
globset = "0.4.14"
Expand Down
16 changes: 8 additions & 8 deletions yazi-config/preset/yazi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ suppress_preload = false
preloaders = [
{ name = "*", cond = "!mime", run = "mime", multi = true, prio = "high" },
# Image
{ mime = "image/svg+xml", run = "magick" },
{ mime = "image/heic", run = "magick" },
{ mime = "image/jxl", run = "magick" },
{ mime = "image/*", run = "image" },
{ mime = "image/svg+xml", run = "magick" },
{ mime = "image/heic", run = "magick" },
{ mime = "image/jxl", run = "magick" },
{ mime = "image/*", run = "image" },
# Video
{ mime = "video/*", run = "video" },
# PDF
Expand All @@ -102,10 +102,10 @@ previewers = [
# JSON
{ mime = "application/json", run = "json" },
# Image
{ mime = "image/svg+xml", run = "magick" },
{ mime = "image/heic", run = "magick" },
{ mime = "image/jxl", run = "magick" },
{ mime = "image/*", run = "image" },
{ mime = "image/svg+xml", run = "magick" },
{ mime = "image/heic", run = "magick" },
{ mime = "image/jxl", run = "magick" },
{ mime = "image/*", run = "image" },
# Video
{ mime = "video/*", run = "video" },
# PDF
Expand Down
4 changes: 2 additions & 2 deletions yazi-config/src/open/open.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ impl Open {
P: AsRef<Path>,
M: AsRef<str>,
{
let is_folder = mime.as_ref() == MIME_DIR;
let is_dir = mime.as_ref() == MIME_DIR;
self.rules.iter().find_map(|rule| {
if rule.mime.as_ref().is_some_and(|p| p.match_mime(&mime))
|| rule.name.as_ref().is_some_and(|p| p.match_path(&path, is_folder))
|| rule.name.as_ref().is_some_and(|p| p.match_path(&path, is_dir))
{
let openers = rule
.use_
Expand Down
16 changes: 8 additions & 8 deletions yazi-config/src/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,25 @@ use serde::Deserialize;
#[derive(Debug, Deserialize)]
#[serde(try_from = "String")]
pub struct Pattern {
inner: globset::GlobMatcher,
is_star: bool,
is_folder: bool,
inner: globset::GlobMatcher,
is_dir: bool,
is_star: bool,
}

impl Pattern {
#[inline]
pub fn match_mime(&self, str: impl AsRef<str>) -> bool { self.inner.is_match(str.as_ref()) }

#[inline]
pub fn match_path(&self, path: impl AsRef<Path>, is_folder: bool) -> bool {
is_folder == self.is_folder && (self.is_star || self.inner.is_match(path))
pub fn match_path(&self, path: impl AsRef<Path>, is_dir: bool) -> bool {
is_dir == self.is_dir && (self.is_star || self.inner.is_match(path))
}

#[inline]
pub fn any_file(&self) -> bool { self.is_star && !self.is_folder }
pub fn any_file(&self) -> bool { self.is_star && !self.is_dir }

#[inline]
pub fn any_dir(&self) -> bool { self.is_star && self.is_folder }
pub fn any_dir(&self) -> bool { self.is_star && self.is_dir }
}

impl TryFrom<&str> for Pattern {
Expand All @@ -42,7 +42,7 @@ impl TryFrom<&str> for Pattern {
.build()?
.compile_matcher();

Ok(Self { inner, is_star: b == "*", is_folder: b.len() < a.len() })
Ok(Self { inner, is_dir: b.len() < a.len(), is_star: b == "*" })
}
}

Expand Down
11 changes: 4 additions & 7 deletions yazi-config/src/plugin/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
mod plugin;
mod props;
mod rule;
mod run;
mod preloader;
mod previewer;

pub use plugin::*;
pub use props::*;
pub use rule::*;
#[allow(unused_imports)]
pub use run::*;
pub use preloader::*;
pub use previewer::*;

pub const MAX_PRELOADERS: u8 = 32;
63 changes: 35 additions & 28 deletions yazi-config/src/plugin/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ use std::path::Path;
use serde::Deserialize;
use yazi_shared::MIME_DIR;

use super::PluginRule;
use super::{Preloader, Previewer};
use crate::{plugin::MAX_PRELOADERS, Preset, MERGED_YAZI};

#[derive(Deserialize)]
pub struct Plugin {
pub preloaders: Vec<PluginRule>,
pub previewers: Vec<PluginRule>,
pub preloaders: Vec<Preloader>,
pub previewers: Vec<Previewer>,
}

impl Default for Plugin {
Expand All @@ -21,17 +21,17 @@ impl Default for Plugin {

#[derive(Deserialize)]
struct Shadow {
preloaders: Vec<PluginRule>,
preloaders: Vec<Preloader>,
#[serde(default)]
prepend_preloaders: Vec<PluginRule>,
prepend_preloaders: Vec<Preloader>,
#[serde(default)]
append_preloaders: Vec<PluginRule>,
append_preloaders: Vec<Preloader>,

previewers: Vec<PluginRule>,
previewers: Vec<Previewer>,
#[serde(default)]
prepend_previewers: Vec<PluginRule>,
prepend_previewers: Vec<Previewer>,
#[serde(default)]
append_previewers: Vec<PluginRule>,
append_previewers: Vec<Previewer>,
}

let mut shadow = toml::from_str::<Outer>(&MERGED_YAZI).unwrap().plugin;
Expand All @@ -50,9 +50,6 @@ impl Default for Plugin {
}

for (i, preloader) in shadow.preloaders.iter_mut().enumerate() {
if preloader.sync {
panic!("Preloaders cannot be synchronous");
}
preloader.id = i as u8;
}

Expand All @@ -66,24 +63,34 @@ impl Plugin {
path: &Path,
mime: Option<&str>,
f: impl Fn(&str) -> bool + Copy,
) -> Vec<&PluginRule> {
let is_folder = mime == Some(MIME_DIR);
self
.preloaders
.iter()
.filter(|&rule| {
rule.cond.as_ref().and_then(|c| c.eval(f)) != Some(false)
&& (rule.mime.as_ref().zip(mime).map_or(false, |(p, m)| p.match_mime(m))
|| rule.name.as_ref().is_some_and(|p| p.match_path(path, is_folder)))
})
.collect()
) -> Vec<&Preloader> {
let is_dir = mime == Some(MIME_DIR);
let mut preloaders = Vec::with_capacity(1);

for p in &self.preloaders {
if p.cond.as_ref().and_then(|c| c.eval(f)) == Some(false) {
continue;
}

if !p.mime.as_ref().zip(mime).map_or(false, |(p, m)| p.match_mime(m))
&& !p.name.as_ref().is_some_and(|p| p.match_path(path, is_dir))
{
continue;
}

preloaders.push(p);
if !p.next {
break;
}
}
preloaders
}

pub fn previewer(&self, path: &Path, mime: &str) -> Option<&PluginRule> {
let is_folder = mime == MIME_DIR;
self.previewers.iter().find(|&rule| {
rule.mime.as_ref().is_some_and(|p| p.match_mime(mime))
|| rule.name.as_ref().is_some_and(|p| p.match_path(path, is_folder))
pub fn previewer(&self, path: &Path, mime: &str) -> Option<&Previewer> {
let is_dir = mime == MIME_DIR;
self.previewers.iter().find(|&p| {
p.mime.as_ref().is_some_and(|p| p.match_mime(mime))
|| p.name.as_ref().is_some_and(|p| p.match_path(path, is_dir))
})
}
}
39 changes: 39 additions & 0 deletions yazi-config/src/plugin/preloader.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use serde::Deserialize;
use yazi_shared::{event::Cmd, Condition};

use crate::{Pattern, Priority};

#[derive(Debug, Deserialize)]
pub struct Preloader {
#[serde(skip)]
pub id: u8,
pub cond: Option<Condition>,
pub name: Option<Pattern>,
pub mime: Option<Pattern>,
pub run: Cmd,
#[serde(default)]
pub next: bool,
#[serde(default)]
pub multi: bool,
#[serde(default)]
pub prio: Priority,
}

#[derive(Debug, Clone)]
pub struct PreloaderProps {
pub id: u8,
pub name: String,
pub multi: bool,
pub prio: Priority,
}

impl From<&Preloader> for PreloaderProps {
fn from(preloader: &Preloader) -> Self {
Self {
id: preloader.id,
name: preloader.run.name.to_owned(),
multi: preloader.multi,
prio: preloader.prio,
}
}
}
21 changes: 21 additions & 0 deletions yazi-config/src/plugin/previewer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use serde::Deserialize;
use yazi_shared::event::Cmd;

use crate::Pattern;

#[derive(Debug, Deserialize)]
pub struct Previewer {
pub name: Option<Pattern>,
pub mime: Option<Pattern>,
pub run: Cmd,
#[serde(default)]
pub sync: bool,
}

impl Previewer {
#[inline]
pub fn any_file(&self) -> bool { self.name.as_ref().is_some_and(|p| p.any_file()) }

#[inline]
pub fn any_dir(&self) -> bool { self.name.as_ref().is_some_and(|p| p.any_dir()) }
}
16 changes: 0 additions & 16 deletions yazi-config/src/plugin/props.rs

This file was deleted.

29 changes: 0 additions & 29 deletions yazi-config/src/plugin/rule.rs

This file was deleted.

0 comments on commit bd30756

Please sign in to comment.