From 0c063c7eed836334c35cdef60d0f8761d331e306 Mon Sep 17 00:00:00 2001 From: yuuhikaze Date: Mon, 9 Dec 2024 09:51:31 -0500 Subject: [PATCH] ignore: add `inverted_matching` option for `OverrideBuilder` --- crates/ignore/src/overrides.rs | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/crates/ignore/src/overrides.rs b/crates/ignore/src/overrides.rs index 1b02b4d4e..790006afe 100644 --- a/crates/ignore/src/overrides.rs +++ b/crates/ignore/src/overrides.rs @@ -4,7 +4,10 @@ This provides functionality similar to `--include` or `--exclude` in command line tools. */ -use std::path::Path; +use std::{ + path::Path, + sync::atomic::{AtomicBool, Ordering}, +}; use crate::{ gitignore::{self, Gitignore, GitignoreBuilder}, @@ -101,14 +104,23 @@ impl Override { if self.is_empty() { return Match::None; } - let mat = self.0.matched(path, is_dir).invert(); - if mat.is_none() && self.num_whitelists() > 0 && !is_dir { + let mat = if INVERTED_MATCHING.load(Ordering::Relaxed) { + self.0.matched(path, is_dir).invert() + } else { + self.0.matched(path, is_dir) + }; + if mat.is_none() + && (self.num_whitelists() > 0 && INVERTED_MATCHING.load(Ordering::Relaxed)) + && !is_dir + { return Match::Ignore(Glob::unmatched()); } mat.map(move |giglob| Glob(GlobInner::Matched(giglob))) } } +static INVERTED_MATCHING: AtomicBool = AtomicBool::new(true); + /// Builds a matcher for a set of glob overrides. #[derive(Clone, Debug)] pub struct OverrideBuilder { @@ -141,6 +153,16 @@ impl OverrideBuilder { Ok(self) } + /// Enables inverting the gitignore file matching. + /// + /// If enabled it acts as an --include + /// If disabled it acts as an --exclude + /// + /// This is enabled by default. + pub fn inverted_matching(&mut self, yes: bool) { + INVERTED_MATCHING.store(yes, Ordering::Relaxed); + } + /// Toggle whether the globs should be matched case insensitively or not. /// /// When this option is changed, only globs added after the change will be affected.