Skip to content

Commit c2affae

Browse files
committed
feat: add a next property to the preloader rules to allow running multiple preloaders (#1058)
1 parent 0ff4835 commit c2affae

File tree

28 files changed

+219
-189
lines changed

28 files changed

+219
-189
lines changed

Diff for: Cargo.lock

+5-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: flake.lock

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: yazi-adaptor/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ yazi-config = { path = "../yazi-config", version = "0.2.5" }
1313
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
1414

1515
# External dependencies
16-
anyhow = "1.0.83"
16+
anyhow = "1.0.86"
1717
arc-swap = "1.7.1"
1818
base64 = "0.22.1"
1919
color_quant = "1.1.0"

Diff for: yazi-cli/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ yazi-dds = { path = "../yazi-dds", version = "0.2.5" }
1313
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
1414

1515
# External dependencies
16-
anyhow = "1.0.83"
16+
anyhow = "1.0.86"
1717
clap = { version = "4.5.4", features = [ "derive" ] }
1818
crossterm = "0.27.0"
1919
md-5 = "0.10.6"
@@ -22,7 +22,7 @@ tokio = { version = "1.37.0", features = [ "full" ] }
2222
toml_edit = "0.22.13"
2323

2424
[build-dependencies]
25-
anyhow = "1.0.83"
25+
anyhow = "1.0.86"
2626
clap = { version = "4.5.4", features = [ "derive" ] }
2727
clap_complete = "4.5.2"
2828
clap_complete_fig = "4.5.0"

Diff for: yazi-config/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ repository = "https://github.com/sxyazi/yazi"
1212
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
1313

1414
# External dependencies
15-
anyhow = "1.0.83"
15+
anyhow = "1.0.86"
1616
arc-swap = "1.7.1"
1717
crossterm = "0.27.0"
1818
globset = "0.4.14"

Diff for: yazi-config/preset/yazi.toml

+9-9
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,12 @@ suppress_preload = false
8080
[plugin]
8181

8282
preloaders = [
83-
{ name = "*", cond = "!mime", run = "mime", multi = true, prio = "high" },
83+
{ name = "*", cond = "!mime", run = "mime", next = true, multi = true, prio = "high" },
8484
# Image
85-
{ mime = "image/svg+xml", run = "magick" },
86-
{ mime = "image/heic", run = "magick" },
87-
{ mime = "image/jxl", run = "magick" },
88-
{ mime = "image/*", run = "image" },
85+
{ mime = "image/svg+xml", run = "magick" },
86+
{ mime = "image/heic", run = "magick" },
87+
{ mime = "image/jxl", run = "magick" },
88+
{ mime = "image/*", run = "image" },
8989
# Video
9090
{ mime = "video/*", run = "video" },
9191
# PDF
@@ -102,10 +102,10 @@ previewers = [
102102
# JSON
103103
{ mime = "application/json", run = "json" },
104104
# Image
105-
{ mime = "image/svg+xml", run = "magick" },
106-
{ mime = "image/heic", run = "magick" },
107-
{ mime = "image/jxl", run = "magick" },
108-
{ mime = "image/*", run = "image" },
105+
{ mime = "image/svg+xml", run = "magick" },
106+
{ mime = "image/heic", run = "magick" },
107+
{ mime = "image/jxl", run = "magick" },
108+
{ mime = "image/*", run = "image" },
109109
# Video
110110
{ mime = "video/*", run = "video" },
111111
# PDF

Diff for: yazi-config/src/open/open.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ impl Open {
2323
P: AsRef<Path>,
2424
M: AsRef<str>,
2525
{
26-
let is_folder = mime.as_ref() == MIME_DIR;
26+
let is_dir = mime.as_ref() == MIME_DIR;
2727
self.rules.iter().find_map(|rule| {
2828
if rule.mime.as_ref().is_some_and(|p| p.match_mime(&mime))
29-
|| rule.name.as_ref().is_some_and(|p| p.match_path(&path, is_folder))
29+
|| rule.name.as_ref().is_some_and(|p| p.match_path(&path, is_dir))
3030
{
3131
let openers = rule
3232
.use_

Diff for: yazi-config/src/pattern.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,25 @@ use serde::Deserialize;
66
#[derive(Debug, Deserialize)]
77
#[serde(try_from = "String")]
88
pub struct Pattern {
9-
inner: globset::GlobMatcher,
10-
is_star: bool,
11-
is_folder: bool,
9+
inner: globset::GlobMatcher,
10+
is_dir: bool,
11+
is_star: bool,
1212
}
1313

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

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

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

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

3030
impl TryFrom<&str> for Pattern {
@@ -42,7 +42,7 @@ impl TryFrom<&str> for Pattern {
4242
.build()?
4343
.compile_matcher();
4444

45-
Ok(Self { inner, is_star: b == "*", is_folder: b.len() < a.len() })
45+
Ok(Self { inner, is_dir: b.len() < a.len(), is_star: b == "*" })
4646
}
4747
}
4848

Diff for: yazi-config/src/plugin/mod.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
mod plugin;
2-
mod props;
3-
mod rule;
4-
mod run;
2+
mod preloader;
3+
mod previewer;
54

65
pub use plugin::*;
7-
pub use props::*;
8-
pub use rule::*;
9-
#[allow(unused_imports)]
10-
pub use run::*;
6+
pub use preloader::*;
7+
pub use previewer::*;
118

129
pub const MAX_PRELOADERS: u8 = 32;

Diff for: yazi-config/src/plugin/plugin.rs

+35-28
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ use std::path::Path;
33
use serde::Deserialize;
44
use yazi_shared::MIME_DIR;
55

6-
use super::PluginRule;
6+
use super::{Preloader, Previewer};
77
use crate::{plugin::MAX_PRELOADERS, Preset, MERGED_YAZI};
88

99
#[derive(Deserialize)]
1010
pub struct Plugin {
11-
pub preloaders: Vec<PluginRule>,
12-
pub previewers: Vec<PluginRule>,
11+
pub preloaders: Vec<Preloader>,
12+
pub previewers: Vec<Previewer>,
1313
}
1414

1515
impl Default for Plugin {
@@ -21,17 +21,17 @@ impl Default for Plugin {
2121

2222
#[derive(Deserialize)]
2323
struct Shadow {
24-
preloaders: Vec<PluginRule>,
24+
preloaders: Vec<Preloader>,
2525
#[serde(default)]
26-
prepend_preloaders: Vec<PluginRule>,
26+
prepend_preloaders: Vec<Preloader>,
2727
#[serde(default)]
28-
append_preloaders: Vec<PluginRule>,
28+
append_preloaders: Vec<Preloader>,
2929

30-
previewers: Vec<PluginRule>,
30+
previewers: Vec<Previewer>,
3131
#[serde(default)]
32-
prepend_previewers: Vec<PluginRule>,
32+
prepend_previewers: Vec<Previewer>,
3333
#[serde(default)]
34-
append_previewers: Vec<PluginRule>,
34+
append_previewers: Vec<Previewer>,
3535
}
3636

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

5252
for (i, preloader) in shadow.preloaders.iter_mut().enumerate() {
53-
if preloader.sync {
54-
panic!("Preloaders cannot be synchronous");
55-
}
5653
preloader.id = i as u8;
5754
}
5855

@@ -66,24 +63,34 @@ impl Plugin {
6663
path: &Path,
6764
mime: Option<&str>,
6865
f: impl Fn(&str) -> bool + Copy,
69-
) -> Vec<&PluginRule> {
70-
let is_folder = mime == Some(MIME_DIR);
71-
self
72-
.preloaders
73-
.iter()
74-
.filter(|&rule| {
75-
rule.cond.as_ref().and_then(|c| c.eval(f)) != Some(false)
76-
&& (rule.mime.as_ref().zip(mime).map_or(false, |(p, m)| p.match_mime(m))
77-
|| rule.name.as_ref().is_some_and(|p| p.match_path(path, is_folder)))
78-
})
79-
.collect()
66+
) -> Vec<&Preloader> {
67+
let is_dir = mime == Some(MIME_DIR);
68+
let mut preloaders = Vec::with_capacity(1);
69+
70+
for p in &self.preloaders {
71+
if p.cond.as_ref().and_then(|c| c.eval(f)) == Some(false) {
72+
continue;
73+
}
74+
75+
if !p.mime.as_ref().zip(mime).map_or(false, |(p, m)| p.match_mime(m))
76+
&& !p.name.as_ref().is_some_and(|p| p.match_path(path, is_dir))
77+
{
78+
continue;
79+
}
80+
81+
preloaders.push(p);
82+
if !p.next {
83+
break;
84+
}
85+
}
86+
preloaders
8087
}
8188

82-
pub fn previewer(&self, path: &Path, mime: &str) -> Option<&PluginRule> {
83-
let is_folder = mime == MIME_DIR;
84-
self.previewers.iter().find(|&rule| {
85-
rule.mime.as_ref().is_some_and(|p| p.match_mime(mime))
86-
|| rule.name.as_ref().is_some_and(|p| p.match_path(path, is_folder))
89+
pub fn previewer(&self, path: &Path, mime: &str) -> Option<&Previewer> {
90+
let is_dir = mime == MIME_DIR;
91+
self.previewers.iter().find(|&p| {
92+
p.mime.as_ref().is_some_and(|p| p.match_mime(mime))
93+
|| p.name.as_ref().is_some_and(|p| p.match_path(path, is_dir))
8794
})
8895
}
8996
}

Diff for: yazi-config/src/plugin/preloader.rs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use serde::Deserialize;
2+
use yazi_shared::{event::Cmd, Condition};
3+
4+
use crate::{Pattern, Priority};
5+
6+
#[derive(Debug, Deserialize)]
7+
pub struct Preloader {
8+
#[serde(skip)]
9+
pub id: u8,
10+
pub cond: Option<Condition>,
11+
pub name: Option<Pattern>,
12+
pub mime: Option<Pattern>,
13+
pub run: Cmd,
14+
#[serde(default)]
15+
pub next: bool,
16+
#[serde(default)]
17+
pub multi: bool,
18+
#[serde(default)]
19+
pub prio: Priority,
20+
}
21+
22+
#[derive(Debug, Clone)]
23+
pub struct PreloaderProps {
24+
pub id: u8,
25+
pub name: String,
26+
pub multi: bool,
27+
pub prio: Priority,
28+
}
29+
30+
impl From<&Preloader> for PreloaderProps {
31+
fn from(preloader: &Preloader) -> Self {
32+
Self {
33+
id: preloader.id,
34+
name: preloader.run.name.to_owned(),
35+
multi: preloader.multi,
36+
prio: preloader.prio,
37+
}
38+
}
39+
}

Diff for: yazi-config/src/plugin/previewer.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use serde::Deserialize;
2+
use yazi_shared::event::Cmd;
3+
4+
use crate::Pattern;
5+
6+
#[derive(Debug, Deserialize)]
7+
pub struct Previewer {
8+
pub name: Option<Pattern>,
9+
pub mime: Option<Pattern>,
10+
pub run: Cmd,
11+
#[serde(default)]
12+
pub sync: bool,
13+
}
14+
15+
impl Previewer {
16+
#[inline]
17+
pub fn any_file(&self) -> bool { self.name.as_ref().is_some_and(|p| p.any_file()) }
18+
19+
#[inline]
20+
pub fn any_dir(&self) -> bool { self.name.as_ref().is_some_and(|p| p.any_dir()) }
21+
}

Diff for: yazi-config/src/plugin/props.rs

-16
This file was deleted.

0 commit comments

Comments
 (0)