Skip to content

Commit

Permalink
feat: multiple openers for a single rule
Browse files Browse the repository at this point in the history
  • Loading branch information
Linus789 committed Sep 13, 2023
1 parent 9c6b3c9 commit c490a11
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 28 deletions.
8 changes: 4 additions & 4 deletions config/docs/yazi.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ Set rules for opening specific files, for example:
```toml
[open]
rules = [
{ mime = "text/*", use = "text" },
{ mime = "image/*", use = "image" },
{ mime = "text/*", use = [ "text" ] },
{ mime = "image/*", use = [ "image" ] },

# { mime = "application/json", use = "text" },
{ name = "*.json", use = "text" },
# { mime = "application/json", use = [ "text" ] },
{ name = "*.json", use = [ "text" ] },
]
```

Expand Down
32 changes: 16 additions & 16 deletions config/preset/yazi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,26 +42,26 @@ fallback = [

[open]
rules = [
{ name = "*/", use = "folder" },
{ name = "*/", use = [ "folder" ] },

{ mime = "text/*", use = "text" },
{ mime = "image/*", use = "image" },
{ mime = "video/*", use = "video" },
{ mime = "audio/*", use = "audio" },
{ mime = "inode/x-empty", use = "text" },
{ mime = "text/*", use = [ "text" ] },
{ mime = "image/*", use = [ "image" ] },
{ mime = "video/*", use = [ "video" ] },
{ mime = "audio/*", use = [ "audio" ] },
{ mime = "inode/x-empty", use = [ "text" ] },

{ mime = "application/json", use = "text" },
{ mime = "*/javascript", use = "text" },
{ mime = "application/json", use = [ "text" ] },
{ mime = "*/javascript", use = [ "text" ] },

{ mime = "application/zip", use = "archive" },
{ mime = "application/gzip", use = "archive" },
{ mime = "application/x-tar", use = "archive" },
{ mime = "application/x-bzip", use = "archive" },
{ mime = "application/x-bzip2", use = "archive" },
{ mime = "application/x-7z-compressed", use = "archive" },
{ mime = "application/x-rar", use = "archive" },
{ mime = "application/zip", use = [ "archive" ] },
{ mime = "application/gzip", use = [ "archive" ] },
{ mime = "application/x-tar", use = [ "archive" ] },
{ mime = "application/x-bzip", use = [ "archive" ] },
{ mime = "application/x-bzip2", use = [ "archive" ] },
{ mime = "application/x-7z-compressed", use = [ "archive" ] },
{ mime = "application/x-rar", use = [ "archive" ] },

{ mime = "*", use = "fallback" },
{ mime = "*", use = [ "fallback" ] },
]

[tasks]
Expand Down
23 changes: 17 additions & 6 deletions config/src/open/open.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ struct OpenRule {
name: Option<Pattern>,
mime: Option<Pattern>,
#[serde(rename = "use")]
use_: String,
use_: Vec<String>,
}

impl Default for Open {
fn default() -> Self { toml::from_str(&MERGED_YAZI).unwrap() }
}

impl Open {
pub fn openers<P, M>(&self, path: P, mime: M) -> Option<&IndexSet<Opener>>
pub fn openers<P, M>(&self, path: P, mime: M) -> Option<IndexSet<&Opener>>
where
P: AsRef<Path>,
M: AsRef<str>,
Expand All @@ -36,7 +36,18 @@ impl Open {
if rule.mime.as_ref().map_or(false, |m| m.matches(&mime))
|| rule.name.as_ref().map_or(false, |n| n.match_path(&path, is_folder))
{
self.openers.get(&rule.use_)
let openers = rule
.use_
.iter()
.filter_map(|use_name| self.openers.get(use_name))
.flatten()
.collect::<IndexSet<_>>();

if openers.is_empty() {
return None;
}

Some(openers)
} else {
None
}
Expand All @@ -49,13 +60,13 @@ impl Open {
P: AsRef<Path>,
M: AsRef<str>,
{
self.openers(path, mime).and_then(|o| o.iter().find(|o| o.block))
self.openers(path, mime).and_then(|o| o.iter().find(|o| o.block).copied())
}

pub fn common_openers(&self, targets: &[(impl AsRef<Path>, impl AsRef<str>)]) -> Vec<&Opener> {
let grouped = targets.iter().filter_map(|(p, m)| self.openers(p, m)).collect::<Vec<_>>();
let flat = grouped.iter().flat_map(|&g| g).collect::<IndexSet<_>>();
flat.into_iter().filter(|&o| grouped.iter().all(|g| g.contains(o))).collect()
let flat = grouped.iter().flatten().collect::<IndexSet<_>>();
flat.into_iter().filter(|&o| grouped.iter().all(|g| g.contains(o))).copied().collect()
}
}

Expand Down
8 changes: 6 additions & 2 deletions core/src/tasks/tasks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,12 @@ impl Tasks {

pub fn file_open(&self, targets: &[(impl AsRef<Path>, impl AsRef<str>)]) -> bool {
let mut openers = BTreeMap::new();
for (path, mime) in targets {
if let Some(opener) = OPEN.openers(path, mime).and_then(|o| o.first()) {
let valid_openers = targets
.iter()
.filter_map(|(path, mime)| OPEN.openers(path, mime).map(|o| (path, o)))
.collect::<Vec<_>>();
for (path, opener) in &valid_openers {
if let Some(opener) = opener.first() {
openers.entry(opener).or_insert_with(Vec::new).push(path.as_ref().as_os_str());
}
}
Expand Down

0 comments on commit c490a11

Please sign in to comment.