diff --git a/yazi-config/src/mgr/mgr.rs b/yazi-config/src/mgr/mgr.rs index d1932d4d..84411041 100644 --- a/yazi-config/src/mgr/mgr.rs +++ b/yazi-config/src/mgr/mgr.rs @@ -26,6 +26,7 @@ pub struct Mgr { pub scrolloff: u8, pub mouse_events: MouseEvents, pub title_format: String, + pub ignore_rule: String, } impl FromStr for Mgr { diff --git a/yazi-core/src/tab/folder.rs b/yazi-core/src/tab/folder.rs index 459e5b8c..45b56458 100644 --- a/yazi-core/src/tab/folder.rs +++ b/yazi-core/src/tab/folder.rs @@ -2,7 +2,7 @@ use std::mem; use yazi_config::{LAYOUT, MGR}; use yazi_dds::Pubsub; -use yazi_fs::{File, Files, FilesOp, FolderStage, Step, cha::Cha}; +use yazi_fs::{File, Files, FilesOp, FolderStage, Step, cha::Cha, Filter}; use yazi_proxy::MgrProxy; use yazi_shared::{Id, url::{Url, Urn, UrnBuf}}; @@ -24,7 +24,7 @@ impl Default for Folder { Self { url: Default::default(), cha: Default::default(), - files: Files::new(MGR.show_hidden), + files: Files::new(MGR.show_hidden, Filter::new(MGR.ignore_rule.as_str(), yazi_fs::FilterCase::Smart).ok()), stage: Default::default(), offset: Default::default(), cursor: Default::default(), diff --git a/yazi-fs/src/files.rs b/yazi-fs/src/files.rs index 6d195c61..a005872f 100644 --- a/yazi-fs/src/files.rs +++ b/yazi-fs/src/files.rs @@ -18,6 +18,7 @@ pub struct Files { sorter: FilesSorter, filter: Option, + ignore_filter: Option, show_hidden: bool, } @@ -28,7 +29,7 @@ impl Deref for Files { } impl Files { - pub fn new(show_hidden: bool) -> Self { Self { show_hidden, ..Default::default() } } + pub fn new(show_hidden: bool, ignore_filter: Option) -> Self { Self { show_hidden, ignore_filter, ..Default::default() } } pub async fn from_dir(dir: &Url) -> std::io::Result> { let mut it = fs::read_dir(dir).await?; @@ -320,6 +321,13 @@ impl Files { } fn split_files(&self, files: impl IntoIterator) -> (Vec, Vec) { + let mut files: Vec = files.into_iter().collect(); + if let Some(ignore_filter) = &self.ignore_filter { + files = files + .into_iter() + .filter(|f| !ignore_filter.matches(f.name())) + .collect(); + } if let Some(filter) = &self.filter { files .into_iter() @@ -380,6 +388,26 @@ impl Files { true } + // --- Ignore Filter + #[inline] + pub fn ignore_filter(&self) -> Option<&Filter> { self.ignore_filter.as_ref() } + + pub fn set_ignore_filter(&mut self, filter: Option) -> bool { + if self.ignore_filter == filter { + return false; + } + + self.ignore_filter = filter; + if self.ignore_filter.is_none() { + return true; + } + + let it = mem::take(&mut self.items).into_iter().chain(mem::take(&mut self.hidden)); + (self.hidden, self.items) = self.split_files(it); + self.sorter.sort(&mut self.items, &self.sizes); + true + } + // --- Show hidden pub fn set_show_hidden(&mut self, state: bool) { if self.show_hidden == state {