mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
perf: switch to globset to reduce CPU time spent on matching icons (#908)
This commit is contained in:
parent
0cc14f44d7
commit
a70374fced
9 changed files with 53 additions and 77 deletions
15
Cargo.lock
generated
15
Cargo.lock
generated
|
|
@ -852,10 +852,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
name = "globset"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"bstr",
|
||||
"log",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
|
|
@ -2719,7 +2726,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"arc-swap",
|
||||
"crossterm",
|
||||
"glob",
|
||||
"globset",
|
||||
"indexmap",
|
||||
"ratatui",
|
||||
"serde",
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"language":"en","flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG"],"version":"0.2"}
|
||||
{"flagWords":[],"language":"en","version":"0.2","words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset"]}
|
||||
|
|
@ -15,7 +15,7 @@ yazi-shared = { path = "../yazi-shared", version = "0.2.4" }
|
|||
anyhow = "1.0.82"
|
||||
arc-swap = "1.7.1"
|
||||
crossterm = "0.27.0"
|
||||
glob = "0.3.1"
|
||||
globset = "0.4.14"
|
||||
indexmap = "2.2.6"
|
||||
ratatui = "0.26.1"
|
||||
serde = { version = "1.0.197", features = [ "derive" ] }
|
||||
|
|
|
|||
|
|
@ -173,22 +173,14 @@ rules = [
|
|||
{ mime = "image/*", fg = "cyan" },
|
||||
|
||||
# Media
|
||||
{ mime = "video/*", fg = "yellow" },
|
||||
{ mime = "audio/*", fg = "yellow" },
|
||||
{ mime = "{audio,video}/*", fg = "yellow" },
|
||||
|
||||
# Archives
|
||||
{ mime = "application/*zip", fg = "magenta" },
|
||||
{ mime = "application/x-tar", fg = "magenta" },
|
||||
{ mime = "application/x-bzip*", fg = "magenta" },
|
||||
{ mime = "application/x-7z-compressed", fg = "magenta" },
|
||||
{ mime = "application/x-rar", fg = "magenta" },
|
||||
{ mime = "application/x-xz", fg = "magenta" },
|
||||
{ mime = "application/*zip", fg = "magenta" },
|
||||
{ mime = "application/x-{tar,bzip*,7z-compressed,xz,rar}", fg = "magenta" },
|
||||
|
||||
# Documents
|
||||
{ mime = "application/doc", fg = "green" },
|
||||
{ mime = "application/pdf", fg = "green" },
|
||||
{ mime = "application/rtf", fg = "green" },
|
||||
{ mime = "application/vnd.*", fg = "green" },
|
||||
{ mime = "application/{pdf,doc,rtf,vnd.*}", fg = "green" },
|
||||
|
||||
# Fallback
|
||||
# { name = "*", fg = "white" },
|
||||
|
|
|
|||
|
|
@ -55,22 +55,17 @@ play = [
|
|||
rules = [
|
||||
{ name = "*/", use = [ "edit", "open", "reveal" ] },
|
||||
|
||||
{ mime = "text/*", use = [ "edit", "reveal" ] },
|
||||
{ mime = "image/*", use = [ "open", "reveal" ] },
|
||||
{ mime = "video/*", use = [ "play", "reveal" ] },
|
||||
{ mime = "audio/*", use = [ "play", "reveal" ] },
|
||||
{ mime = "inode/x-empty", use = [ "edit", "reveal" ] },
|
||||
{ mime = "text/*", use = [ "edit", "reveal" ] },
|
||||
{ mime = "image/*", use = [ "open", "reveal" ] },
|
||||
{ mime = "{audio,video}/*", use = [ "play", "reveal" ] },
|
||||
{ mime = "inode/x-empty", use = [ "edit", "reveal" ] },
|
||||
|
||||
{ mime = "application/*zip", use = [ "extract", "reveal" ] },
|
||||
{ mime = "application/x-{tar,bzip*,7z-compressed,xz,rar}", use = [ "extract", "reveal" ] },
|
||||
|
||||
{ mime = "application/json", use = [ "edit", "reveal" ] },
|
||||
{ mime = "*/javascript", use = [ "edit", "reveal" ] },
|
||||
|
||||
{ mime = "application/*zip", use = [ "extract", "reveal" ] },
|
||||
{ mime = "application/x-tar", use = [ "extract", "reveal" ] },
|
||||
{ mime = "application/x-bzip*", use = [ "extract", "reveal" ] },
|
||||
{ mime = "application/x-7z-compressed", use = [ "extract", "reveal" ] },
|
||||
{ mime = "application/x-rar", use = [ "extract", "reveal" ] },
|
||||
{ mime = "application/x-xz", use = [ "extract", "reveal" ] },
|
||||
|
||||
{ mime = "*", use = [ "open", "reveal" ] },
|
||||
]
|
||||
|
||||
|
|
@ -96,10 +91,8 @@ preloaders = [
|
|||
previewers = [
|
||||
{ name = "*/", run = "folder", sync = true },
|
||||
# Code
|
||||
{ mime = "text/*", run = "code" },
|
||||
{ mime = "*/xml", run = "code" },
|
||||
{ mime = "*/javascript", run = "code" },
|
||||
{ mime = "*/x-wine-extension-ini", run = "code" },
|
||||
{ mime = "text/*", run = "code" },
|
||||
{ mime = "*/{xml,javascript,x-wine-extension-ini}", run = "code" },
|
||||
# JSON
|
||||
{ mime = "application/json", run = "json" },
|
||||
# Image
|
||||
|
|
@ -110,12 +103,8 @@ previewers = [
|
|||
# PDF
|
||||
{ mime = "application/pdf", run = "pdf" },
|
||||
# Archive
|
||||
{ mime = "application/*zip", run = "archive" },
|
||||
{ mime = "application/x-tar", run = "archive" },
|
||||
{ mime = "application/x-bzip*", run = "archive" },
|
||||
{ mime = "application/x-7z-compressed", run = "archive" },
|
||||
{ mime = "application/x-rar", run = "archive" },
|
||||
{ mime = "application/x-xz", run = "archive" },
|
||||
{ mime = "application/*zip", run = "archive" },
|
||||
{ mime = "application/x-{tar,bzip*,7z-compressed,xz,rar}", run = "archive" },
|
||||
# Fallback
|
||||
{ name = "*", run = "file" },
|
||||
]
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ impl Open {
|
|||
{
|
||||
let is_folder = mime.as_ref() == MIME_DIR;
|
||||
self.rules.iter().find_map(|rule| {
|
||||
if rule.mime.as_ref().is_some_and(|m| m.matches(&mime))
|
||||
|| rule.name.as_ref().is_some_and(|n| n.match_path(&path, is_folder))
|
||||
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))
|
||||
{
|
||||
let openers = rule
|
||||
.use_
|
||||
|
|
|
|||
|
|
@ -1,46 +1,30 @@
|
|||
use std::path::Path;
|
||||
|
||||
use glob::MatchOptions;
|
||||
use globset::GlobBuilder;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(try_from = "String")]
|
||||
pub struct Pattern {
|
||||
inner: glob::Pattern,
|
||||
sensitive: bool,
|
||||
inner: globset::GlobMatcher,
|
||||
is_star: bool,
|
||||
is_folder: bool,
|
||||
full_path: bool,
|
||||
}
|
||||
|
||||
impl Pattern {
|
||||
#[inline]
|
||||
pub fn matches(&self, str: impl AsRef<str>) -> bool {
|
||||
self.inner.matches_with(str.as_ref(), MatchOptions {
|
||||
case_sensitive: self.sensitive,
|
||||
require_literal_separator: self.full_path,
|
||||
require_literal_leading_dot: false,
|
||||
})
|
||||
}
|
||||
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 {
|
||||
if is_folder != self.is_folder {
|
||||
return false;
|
||||
}
|
||||
|
||||
let path = path.as_ref();
|
||||
self.matches(if self.full_path {
|
||||
path.to_string_lossy()
|
||||
} else {
|
||||
path.file_name().map_or_else(|| path.to_string_lossy(), |n| n.to_string_lossy())
|
||||
})
|
||||
is_folder == self.is_folder && (self.is_star || self.inner.is_match(path))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn any_file(&self) -> bool { !self.is_folder && self.inner.as_str() == "*" }
|
||||
pub fn any_file(&self) -> bool { self.is_star && !self.is_folder }
|
||||
|
||||
#[inline]
|
||||
pub fn any_dir(&self) -> bool { self.is_folder && self.inner.as_str() == "*" }
|
||||
pub fn any_dir(&self) -> bool { self.is_star && self.is_folder }
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for Pattern {
|
||||
|
|
@ -49,12 +33,16 @@ impl TryFrom<&str> for Pattern {
|
|||
fn try_from(s: &str) -> Result<Self, Self::Error> {
|
||||
let a = s.trim_start_matches("\\s");
|
||||
let b = a.trim_end_matches('/');
|
||||
Ok(Self {
|
||||
inner: glob::Pattern::new(b)?,
|
||||
sensitive: a.len() < s.len(),
|
||||
is_folder: b.len() < a.len(),
|
||||
full_path: b.contains('/'),
|
||||
})
|
||||
|
||||
let inner = GlobBuilder::new(b)
|
||||
.case_insensitive(a.len() == s.len())
|
||||
.literal_separator(b.contains('/'))
|
||||
.backslash_escape(false)
|
||||
.empty_alternates(false)
|
||||
.build()?
|
||||
.compile_matcher();
|
||||
|
||||
Ok(Self { inner, is_star: b == "*", is_folder: b.len() < a.len() })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,8 +73,8 @@ impl Plugin {
|
|||
.iter()
|
||||
.filter(|&rule| {
|
||||
rule.cond.as_ref().and_then(|c| c.eval(f)) != Some(false)
|
||||
&& (rule.mime.as_ref().zip(mime).map_or(false, |(m, s)| m.matches(s))
|
||||
|| rule.name.as_ref().is_some_and(|n| n.match_path(path, is_folder)))
|
||||
&& (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()
|
||||
}
|
||||
|
|
@ -82,8 +82,8 @@ impl Plugin {
|
|||
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(|m| m.matches(mime))
|
||||
|| rule.name.as_ref().is_some_and(|n| n.match_path(path, is_folder))
|
||||
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))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ impl Filetype {
|
|||
return false;
|
||||
}
|
||||
|
||||
self.name.as_ref().is_some_and(|n| n.match_path(&file.url, file.is_dir()))
|
||||
|| self.mime.as_ref().zip(mime).map_or(false, |(m, s)| m.matches(s))
|
||||
self.mime.as_ref().zip(mime).map_or(false, |(p, m)| p.match_mime(m))
|
||||
|| self.name.as_ref().is_some_and(|n| n.match_path(&file.url, file.is_dir()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue