diff options
-rw-r--r-- | src/config.rs | 17 | ||||
-rw-r--r-- | src/main.rs | 14 | ||||
-rw-r--r-- | src/project.rs | 29 |
3 files changed, 43 insertions, 17 deletions
diff --git a/src/config.rs b/src/config.rs index f8160af..df31de4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -12,18 +12,19 @@ pub struct Config { #[command(flatten)] pub parsers: Projects, - /// Add arbitrary directories - /// - /// Directories added by this flag are still filtered and sorted based on supplied options. - #[arg(short = 'P', long = "project")] - pub projects: Vec<PathBuf>, - /// Add any current tmux session's paths to output. /// /// Uses the tmux session's `session_path`. #[arg(short = 'T', long = "sessions")] pub tmux_sessions: bool, + /// Include arbitrary directories in output + /// + /// Note: Directories added by this flag are still filtered and sorted based on supplied + /// options. + #[arg(short = 'P', long = "project")] + pub include: Vec<PathBuf>, + #[command(flatten)] pub verbosity: Verbosity, } @@ -51,6 +52,10 @@ pub struct Search { #[derive(Debug, Default, Clone, Args)] pub struct Projects { + /// Exclude matching sessions from output + #[arg(short, long = "exclude")] + pub excludes: Vec<PathBuf>, + /// Match all child directories. /// /// Uses the directory mtime as the timestamp. diff --git a/src/main.rs b/src/main.rs index 78583c2..25a051e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,9 +13,19 @@ fn main() -> Result<()> { let mut projects = Projects::from(config.parsers); - projects.extend(config.projects); + projects.extend(config.include); + + // Workaround due to ignore::WalkBuilder not implementing Default. + if let Some((init, paths)) = config.search.paths.split_first() { + let mut search = Search::new(init); + + for path in paths { + search.add(path); + } + + search.max_depth(config.search.max_depth); + search.hidden(!config.search.hidden); - if let Ok(search) = Search::try_from(config.search) { projects.extend(search); } diff --git a/src/project.rs b/src/project.rs index d05da37..a35c17e 100644 --- a/src/project.rs +++ b/src/project.rs @@ -15,13 +15,15 @@ use crate::{parser::FilterMap, path::PathMatcher, tmux::Tmux}; pub struct Projects { inner: HashMap<PathBuf, Duration>, filters: Vec<Box<dyn FilterMap>>, + excludes: Vec<PathBuf>, mtime: bool, } impl Projects { - pub fn new(fallback: bool) -> Self { + pub fn new(mtime: bool, excludes: Vec<PathBuf>) -> Self { Self { - mtime: fallback, + mtime, + excludes, ..Default::default() } } @@ -34,6 +36,10 @@ impl Projects { let span = tracing::trace_span!("Entry", ?item); let _guard = span.enter(); + if self.excludes.iter().any(|p| &item.path_buf == p) { + return; + } + match self.inner.entry(item.path_buf) { Entry::Occupied(mut occupied) if &item.timestamp > occupied.get() => { trace!(?occupied, new_value=?item.timestamp, "New entry is more recent, replacing"); @@ -105,22 +111,27 @@ impl Extend<Project> for Projects { impl From<crate::config::Projects> for Projects { fn from(value: crate::config::Projects) -> Self { - let mut projects = Projects::new(value.mtime); + let mut filters: Vec<Box<dyn FilterMap>> = Vec::new(); if let Some(pattern) = &value.pattern { - projects.add_filter(PathMatcher(pattern.to_owned())); + filters.push(Box::new(PathMatcher(pattern.to_owned()))); } if value.tmux { - projects.add_filter(Tmux); + filters.push(Box::new(Tmux)); } #[cfg(feature = "git")] if value.git { - projects.add_filter(crate::git::Git); + filters.push(Box::new(crate::git::Git)); } - projects + Self { + filters, + excludes: value.excludes, + mtime: value.mtime, + ..Default::default() + } } } @@ -146,9 +157,9 @@ impl From<(PathBuf, Duration)> for Project { } impl From<(&PathBuf, &Duration)> for Project { - fn from((path_buf, timestamp): (&PathBuf, &Duration)) -> Self { + fn from((path_buf, ×tamp): (&PathBuf, &Duration)) -> Self { Self { - timestamp: *timestamp, + timestamp, path_buf: path_buf.to_owned(), } } |