|  |  |  | @@ -46,7 +46,6 @@ use crate::{ | 
		
	
		
			
				|  |  |  |  |     messages::{set_ignore_messages, set_messages}, | 
		
	
		
			
				|  |  |  |  |     search::{PatternMatcher, Printer, SearchWorker, SearchWorkerBuilder}, | 
		
	
		
			
				|  |  |  |  |     subject::{Subject, SubjectBuilder}, | 
		
	
		
			
				|  |  |  |  |     Result, | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /// The command that ripgrep should execute based on the command line | 
		
	
	
		
			
				
					
					|  |  |  | @@ -129,7 +128,7 @@ impl Args { | 
		
	
		
			
				|  |  |  |  |     /// ripgrep, then print the version and exit. | 
		
	
		
			
				|  |  |  |  |     /// | 
		
	
		
			
				|  |  |  |  |     /// Also, initialize a global logger. | 
		
	
		
			
				|  |  |  |  |     pub fn parse() -> Result<Args> { | 
		
	
		
			
				|  |  |  |  |     pub fn parse() -> anyhow::Result<Args> { | 
		
	
		
			
				|  |  |  |  |         // We parse the args given on CLI. This does not include args from | 
		
	
		
			
				|  |  |  |  |         // the config. We use the CLI args as an initial configuration while | 
		
	
		
			
				|  |  |  |  |         // trying to parse config files. If a config file exists and has | 
		
	
	
		
			
				
					
					|  |  |  | @@ -140,7 +139,7 @@ impl Args { | 
		
	
		
			
				|  |  |  |  |         set_ignore_messages(!early_matches.is_present("no-ignore-messages")); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         if let Err(err) = Logger::init() { | 
		
	
		
			
				|  |  |  |  |             return Err(format!("failed to initialize logger: {}", err).into()); | 
		
	
		
			
				|  |  |  |  |             anyhow::bail!("failed to initialize logger: {err}"); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         if early_matches.is_present("trace") { | 
		
	
		
			
				|  |  |  |  |             log::set_max_level(log::LevelFilter::Trace); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -194,7 +193,7 @@ impl Args { | 
		
	
		
			
				|  |  |  |  |     /// search results. | 
		
	
		
			
				|  |  |  |  |     /// | 
		
	
		
			
				|  |  |  |  |     /// The returned printer will write results to the given writer. | 
		
	
		
			
				|  |  |  |  |     fn printer<W: WriteColor>(&self, wtr: W) -> Result<Printer<W>> { | 
		
	
		
			
				|  |  |  |  |     fn printer<W: WriteColor>(&self, wtr: W) -> anyhow::Result<Printer<W>> { | 
		
	
		
			
				|  |  |  |  |         match self.matches().output_kind() { | 
		
	
		
			
				|  |  |  |  |             OutputKind::Standard => { | 
		
	
		
			
				|  |  |  |  |                 let separator_search = self.command() == Command::Search; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -218,7 +217,7 @@ impl Args { | 
		
	
		
			
				|  |  |  |  | impl Args { | 
		
	
		
			
				|  |  |  |  |     /// Create a new buffer writer for multi-threaded printing with color | 
		
	
		
			
				|  |  |  |  |     /// support. | 
		
	
		
			
				|  |  |  |  |     pub fn buffer_writer(&self) -> Result<BufferWriter> { | 
		
	
		
			
				|  |  |  |  |     pub fn buffer_writer(&self) -> anyhow::Result<BufferWriter> { | 
		
	
		
			
				|  |  |  |  |         let mut wtr = BufferWriter::stdout(self.matches().color_choice()); | 
		
	
		
			
				|  |  |  |  |         wtr.separator(self.matches().file_separator()?); | 
		
	
		
			
				|  |  |  |  |         Ok(wtr) | 
		
	
	
		
			
				
					
					|  |  |  | @@ -236,7 +235,7 @@ impl Args { | 
		
	
		
			
				|  |  |  |  |     pub fn path_printer<W: WriteColor>( | 
		
	
		
			
				|  |  |  |  |         &self, | 
		
	
		
			
				|  |  |  |  |         wtr: W, | 
		
	
		
			
				|  |  |  |  |     ) -> Result<PathPrinter<W>> { | 
		
	
		
			
				|  |  |  |  |     ) -> anyhow::Result<PathPrinter<W>> { | 
		
	
		
			
				|  |  |  |  |         let mut builder = PathPrinterBuilder::new(); | 
		
	
		
			
				|  |  |  |  |         builder | 
		
	
		
			
				|  |  |  |  |             .color_specs(self.matches().color_specs()?) | 
		
	
	
		
			
				
					
					|  |  |  | @@ -253,7 +252,7 @@ impl Args { | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// Returns true if and only if the search should quit after finding the | 
		
	
		
			
				|  |  |  |  |     /// first match. | 
		
	
		
			
				|  |  |  |  |     pub fn quit_after_match(&self) -> Result<bool> { | 
		
	
		
			
				|  |  |  |  |     pub fn quit_after_match(&self) -> anyhow::Result<bool> { | 
		
	
		
			
				|  |  |  |  |         Ok(self.matches().is_present("quiet") && self.stats()?.is_none()) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -263,7 +262,7 @@ impl Args { | 
		
	
		
			
				|  |  |  |  |     pub fn search_worker<W: WriteColor>( | 
		
	
		
			
				|  |  |  |  |         &self, | 
		
	
		
			
				|  |  |  |  |         wtr: W, | 
		
	
		
			
				|  |  |  |  |     ) -> Result<SearchWorker<W>> { | 
		
	
		
			
				|  |  |  |  |     ) -> anyhow::Result<SearchWorker<W>> { | 
		
	
		
			
				|  |  |  |  |         let matches = self.matches(); | 
		
	
		
			
				|  |  |  |  |         let matcher = self.matcher().clone(); | 
		
	
		
			
				|  |  |  |  |         let printer = self.printer(wtr)?; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -284,7 +283,7 @@ impl Args { | 
		
	
		
			
				|  |  |  |  |     /// | 
		
	
		
			
				|  |  |  |  |     /// When this returns a `Stats` value, then it is guaranteed that the | 
		
	
		
			
				|  |  |  |  |     /// search worker will be configured to track statistics as well. | 
		
	
		
			
				|  |  |  |  |     pub fn stats(&self) -> Result<Option<Stats>> { | 
		
	
		
			
				|  |  |  |  |     pub fn stats(&self) -> anyhow::Result<Option<Stats>> { | 
		
	
		
			
				|  |  |  |  |         Ok(if self.command().is_search() && self.matches().stats() { | 
		
	
		
			
				|  |  |  |  |             Some(Stats::new()) | 
		
	
		
			
				|  |  |  |  |         } else { | 
		
	
	
		
			
				
					
					|  |  |  | @@ -318,12 +317,12 @@ impl Args { | 
		
	
		
			
				|  |  |  |  |     /// | 
		
	
		
			
				|  |  |  |  |     /// If there was a problem reading and parsing the type definitions, then | 
		
	
		
			
				|  |  |  |  |     /// this returns an error. | 
		
	
		
			
				|  |  |  |  |     pub fn type_defs(&self) -> Result<Vec<FileTypeDef>> { | 
		
	
		
			
				|  |  |  |  |     pub fn type_defs(&self) -> anyhow::Result<Vec<FileTypeDef>> { | 
		
	
		
			
				|  |  |  |  |         Ok(self.matches().types()?.definitions().to_vec()) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// Return a walker that never uses additional threads. | 
		
	
		
			
				|  |  |  |  |     pub fn walker(&self) -> Result<Walk> { | 
		
	
		
			
				|  |  |  |  |     pub fn walker(&self) -> anyhow::Result<Walk> { | 
		
	
		
			
				|  |  |  |  |         Ok(self | 
		
	
		
			
				|  |  |  |  |             .matches() | 
		
	
		
			
				|  |  |  |  |             .walker_builder(self.paths(), self.0.threads)? | 
		
	
	
		
			
				
					
					|  |  |  | @@ -371,7 +370,7 @@ impl Args { | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// Return a parallel walker that may use additional threads. | 
		
	
		
			
				|  |  |  |  |     pub fn walker_parallel(&self) -> Result<WalkParallel> { | 
		
	
		
			
				|  |  |  |  |     pub fn walker_parallel(&self) -> anyhow::Result<WalkParallel> { | 
		
	
		
			
				|  |  |  |  |         Ok(self | 
		
	
		
			
				|  |  |  |  |             .matches() | 
		
	
		
			
				|  |  |  |  |             .walker_builder(self.paths(), self.0.threads)? | 
		
	
	
		
			
				
					
					|  |  |  | @@ -434,7 +433,7 @@ impl SortBy { | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// Try to check that the sorting criteria selected is actually supported. | 
		
	
		
			
				|  |  |  |  |     /// If it isn't, then an error is returned. | 
		
	
		
			
				|  |  |  |  |     fn check(&self) -> Result<()> { | 
		
	
		
			
				|  |  |  |  |     fn check(&self) -> anyhow::Result<()> { | 
		
	
		
			
				|  |  |  |  |         match self.kind { | 
		
	
		
			
				|  |  |  |  |             SortByKind::None | SortByKind::Path => {} | 
		
	
		
			
				|  |  |  |  |             SortByKind::LastModified => { | 
		
	
	
		
			
				
					
					|  |  |  | @@ -509,7 +508,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     /// | 
		
	
		
			
				|  |  |  |  |     /// If there are no additional arguments from the environment (e.g., a | 
		
	
		
			
				|  |  |  |  |     /// config file), then the given matches are returned as is. | 
		
	
		
			
				|  |  |  |  |     fn reconfigure(self) -> Result<ArgMatches> { | 
		
	
		
			
				|  |  |  |  |     fn reconfigure(self) -> anyhow::Result<ArgMatches> { | 
		
	
		
			
				|  |  |  |  |         // If the end user says no config, then respect it. | 
		
	
		
			
				|  |  |  |  |         if self.is_present("no-config") { | 
		
	
		
			
				|  |  |  |  |             log::debug!( | 
		
	
	
		
			
				
					
					|  |  |  | @@ -534,7 +533,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// Convert the result of parsing CLI arguments into ripgrep's higher level | 
		
	
		
			
				|  |  |  |  |     /// configuration structure. | 
		
	
		
			
				|  |  |  |  |     fn to_args(self) -> Result<Args> { | 
		
	
		
			
				|  |  |  |  |     fn to_args(self) -> anyhow::Result<Args> { | 
		
	
		
			
				|  |  |  |  |         // We compute these once since they could be large. | 
		
	
		
			
				|  |  |  |  |         let patterns = self.patterns()?; | 
		
	
		
			
				|  |  |  |  |         let matcher = self.matcher(&patterns)?; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -591,7 +590,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     /// | 
		
	
		
			
				|  |  |  |  |     /// If there was a problem building the matcher (e.g., a syntax error), | 
		
	
		
			
				|  |  |  |  |     /// then this returns an error. | 
		
	
		
			
				|  |  |  |  |     fn matcher(&self, patterns: &[String]) -> Result<PatternMatcher> { | 
		
	
		
			
				|  |  |  |  |     fn matcher(&self, patterns: &[String]) -> anyhow::Result<PatternMatcher> { | 
		
	
		
			
				|  |  |  |  |         if self.is_present("pcre2") { | 
		
	
		
			
				|  |  |  |  |             self.matcher_engine("pcre2", patterns) | 
		
	
		
			
				|  |  |  |  |         } else if self.is_present("auto-hybrid-regex") { | 
		
	
	
		
			
				
					
					|  |  |  | @@ -611,13 +610,13 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |         &self, | 
		
	
		
			
				|  |  |  |  |         engine: &str, | 
		
	
		
			
				|  |  |  |  |         patterns: &[String], | 
		
	
		
			
				|  |  |  |  |     ) -> Result<PatternMatcher> { | 
		
	
		
			
				|  |  |  |  |     ) -> anyhow::Result<PatternMatcher> { | 
		
	
		
			
				|  |  |  |  |         match engine { | 
		
	
		
			
				|  |  |  |  |             "default" => { | 
		
	
		
			
				|  |  |  |  |                 let matcher = match self.matcher_rust(patterns) { | 
		
	
		
			
				|  |  |  |  |                     Ok(matcher) => matcher, | 
		
	
		
			
				|  |  |  |  |                     Err(err) => { | 
		
	
		
			
				|  |  |  |  |                         return Err(From::from(suggest(err.to_string()))); | 
		
	
		
			
				|  |  |  |  |                         anyhow::bail!(suggest(err.to_string())); | 
		
	
		
			
				|  |  |  |  |                     } | 
		
	
		
			
				|  |  |  |  |                 }; | 
		
	
		
			
				|  |  |  |  |                 Ok(PatternMatcher::RustRegex(matcher)) | 
		
	
	
		
			
				
					
					|  |  |  | @@ -628,9 +627,9 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |                 Ok(PatternMatcher::PCRE2(matcher)) | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |             #[cfg(not(feature = "pcre2"))] | 
		
	
		
			
				|  |  |  |  |             "pcre2" => Err(From::from( | 
		
	
		
			
				|  |  |  |  |             "pcre2" => anyhow::bail!( | 
		
	
		
			
				|  |  |  |  |                 "PCRE2 is not available in this build of ripgrep", | 
		
	
		
			
				|  |  |  |  |             )), | 
		
	
		
			
				|  |  |  |  |             ), | 
		
	
		
			
				|  |  |  |  |             "auto" => { | 
		
	
		
			
				|  |  |  |  |                 let rust_err = match self.matcher_rust(patterns) { | 
		
	
		
			
				|  |  |  |  |                     Ok(matcher) => { | 
		
	
	
		
			
				
					
					|  |  |  | @@ -647,21 +646,18 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |                     Ok(matcher) => return Ok(matcher), | 
		
	
		
			
				|  |  |  |  |                     Err(err) => err, | 
		
	
		
			
				|  |  |  |  |                 }; | 
		
	
		
			
				|  |  |  |  |                 Err(From::from(format!( | 
		
	
		
			
				|  |  |  |  |                 let divider = "~".repeat(79); | 
		
	
		
			
				|  |  |  |  |                 anyhow::bail!( | 
		
	
		
			
				|  |  |  |  |                     "regex could not be compiled with either the default \ | 
		
	
		
			
				|  |  |  |  |                      regex engine or with PCRE2.\n\n\ | 
		
	
		
			
				|  |  |  |  |                      default regex engine error:\n{}\n{}\n{}\n\n\ | 
		
	
		
			
				|  |  |  |  |                      PCRE2 regex engine error:\n{}", | 
		
	
		
			
				|  |  |  |  |                     "~".repeat(79), | 
		
	
		
			
				|  |  |  |  |                     rust_err, | 
		
	
		
			
				|  |  |  |  |                     "~".repeat(79), | 
		
	
		
			
				|  |  |  |  |                     pcre_err, | 
		
	
		
			
				|  |  |  |  |                 ))) | 
		
	
		
			
				|  |  |  |  |                      default regex engine error:\n\ | 
		
	
		
			
				|  |  |  |  |                      {divider}\n\ | 
		
	
		
			
				|  |  |  |  |                      {rust_err}\n\ | 
		
	
		
			
				|  |  |  |  |                      {divider}\n\n\ | 
		
	
		
			
				|  |  |  |  |                      PCRE2 regex engine error:\n{pcre_err}", | 
		
	
		
			
				|  |  |  |  |                 ); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |             _ => Err(From::from(format!( | 
		
	
		
			
				|  |  |  |  |                 "unrecognized regex engine '{}'", | 
		
	
		
			
				|  |  |  |  |                 engine | 
		
	
		
			
				|  |  |  |  |             ))), | 
		
	
		
			
				|  |  |  |  |             _ => anyhow::bail!("unrecognized regex engine '{engine}'"), | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -669,7 +665,10 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     /// | 
		
	
		
			
				|  |  |  |  |     /// If there was a problem building the matcher (such as a regex syntax | 
		
	
		
			
				|  |  |  |  |     /// error), then an error is returned. | 
		
	
		
			
				|  |  |  |  |     fn matcher_rust(&self, patterns: &[String]) -> Result<RustRegexMatcher> { | 
		
	
		
			
				|  |  |  |  |     fn matcher_rust( | 
		
	
		
			
				|  |  |  |  |         &self, | 
		
	
		
			
				|  |  |  |  |         patterns: &[String], | 
		
	
		
			
				|  |  |  |  |     ) -> anyhow::Result<RustRegexMatcher> { | 
		
	
		
			
				|  |  |  |  |         let mut builder = RustRegexMatcherBuilder::new(); | 
		
	
		
			
				|  |  |  |  |         builder | 
		
	
		
			
				|  |  |  |  |             .case_smart(self.case_smart()) | 
		
	
	
		
			
				
					
					|  |  |  | @@ -707,7 +706,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         match builder.build_many(patterns) { | 
		
	
		
			
				|  |  |  |  |             Ok(m) => Ok(m), | 
		
	
		
			
				|  |  |  |  |             Err(err) => Err(From::from(suggest_multiline(err.to_string()))), | 
		
	
		
			
				|  |  |  |  |             Err(err) => anyhow::bail!(suggest_multiline(err.to_string())), | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -716,7 +715,10 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     /// If there was a problem building the matcher (such as a regex syntax | 
		
	
		
			
				|  |  |  |  |     /// error), then an error is returned. | 
		
	
		
			
				|  |  |  |  |     #[cfg(feature = "pcre2")] | 
		
	
		
			
				|  |  |  |  |     fn matcher_pcre2(&self, patterns: &[String]) -> Result<PCRE2RegexMatcher> { | 
		
	
		
			
				|  |  |  |  |     fn matcher_pcre2( | 
		
	
		
			
				|  |  |  |  |         &self, | 
		
	
		
			
				|  |  |  |  |         patterns: &[String], | 
		
	
		
			
				|  |  |  |  |     ) -> anyhow::Result<PCRE2RegexMatcher> { | 
		
	
		
			
				|  |  |  |  |         let mut builder = PCRE2RegexMatcherBuilder::new(); | 
		
	
		
			
				|  |  |  |  |         builder | 
		
	
		
			
				|  |  |  |  |             .case_smart(self.case_smart()) | 
		
	
	
		
			
				
					
					|  |  |  | @@ -748,7 +750,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// Build a JSON printer that writes results to the given writer. | 
		
	
		
			
				|  |  |  |  |     fn printer_json<W: io::Write>(&self, wtr: W) -> Result<JSON<W>> { | 
		
	
		
			
				|  |  |  |  |     fn printer_json<W: io::Write>(&self, wtr: W) -> anyhow::Result<JSON<W>> { | 
		
	
		
			
				|  |  |  |  |         let mut builder = JSONBuilder::new(); | 
		
	
		
			
				|  |  |  |  |         builder | 
		
	
		
			
				|  |  |  |  |             .pretty(false) | 
		
	
	
		
			
				
					
					|  |  |  | @@ -774,7 +776,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |         paths: &[PathBuf], | 
		
	
		
			
				|  |  |  |  |         wtr: W, | 
		
	
		
			
				|  |  |  |  |         separator_search: bool, | 
		
	
		
			
				|  |  |  |  |     ) -> Result<Standard<W>> { | 
		
	
		
			
				|  |  |  |  |     ) -> anyhow::Result<Standard<W>> { | 
		
	
		
			
				|  |  |  |  |         let mut builder = StandardBuilder::new(); | 
		
	
		
			
				|  |  |  |  |         builder | 
		
	
		
			
				|  |  |  |  |             .color_specs(self.color_specs()?) | 
		
	
	
		
			
				
					
					|  |  |  | @@ -813,7 +815,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |         &self, | 
		
	
		
			
				|  |  |  |  |         paths: &[PathBuf], | 
		
	
		
			
				|  |  |  |  |         wtr: W, | 
		
	
		
			
				|  |  |  |  |     ) -> Result<Summary<W>> { | 
		
	
		
			
				|  |  |  |  |     ) -> anyhow::Result<Summary<W>> { | 
		
	
		
			
				|  |  |  |  |         let mut builder = SummaryBuilder::new(); | 
		
	
		
			
				|  |  |  |  |         builder | 
		
	
		
			
				|  |  |  |  |             .kind(self.summary_kind().expect("summary format")) | 
		
	
	
		
			
				
					
					|  |  |  | @@ -830,7 +832,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// Build a searcher from the command line parameters. | 
		
	
		
			
				|  |  |  |  |     fn searcher(&self, paths: &[PathBuf]) -> Result<Searcher> { | 
		
	
		
			
				|  |  |  |  |     fn searcher(&self, paths: &[PathBuf]) -> anyhow::Result<Searcher> { | 
		
	
		
			
				|  |  |  |  |         let (ctx_before, ctx_after) = self.contexts()?; | 
		
	
		
			
				|  |  |  |  |         let line_term = if self.is_present("crlf") { | 
		
	
		
			
				|  |  |  |  |             LineTerminator::crlf() | 
		
	
	
		
			
				
					
					|  |  |  | @@ -871,7 +873,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |         &self, | 
		
	
		
			
				|  |  |  |  |         paths: &[PathBuf], | 
		
	
		
			
				|  |  |  |  |         threads: usize, | 
		
	
		
			
				|  |  |  |  |     ) -> Result<WalkBuilder> { | 
		
	
		
			
				|  |  |  |  |     ) -> anyhow::Result<WalkBuilder> { | 
		
	
		
			
				|  |  |  |  |         let mut builder = WalkBuilder::new(&paths[0]); | 
		
	
		
			
				|  |  |  |  |         for path in &paths[1..] { | 
		
	
		
			
				|  |  |  |  |             builder.add(path); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -994,7 +996,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     /// | 
		
	
		
			
				|  |  |  |  |     /// If the was a problem parsing any of the provided specs, then an error | 
		
	
		
			
				|  |  |  |  |     /// is returned. | 
		
	
		
			
				|  |  |  |  |     fn color_specs(&self) -> Result<ColorSpecs> { | 
		
	
		
			
				|  |  |  |  |     fn color_specs(&self) -> anyhow::Result<ColorSpecs> { | 
		
	
		
			
				|  |  |  |  |         // Start with a default set of color specs. | 
		
	
		
			
				|  |  |  |  |         let mut specs = default_color_specs(); | 
		
	
		
			
				|  |  |  |  |         for spec_str in self.values_of_lossy_vec("colors") { | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1017,7 +1019,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     /// | 
		
	
		
			
				|  |  |  |  |     /// If there was a problem parsing the values from the user as an integer, | 
		
	
		
			
				|  |  |  |  |     /// then an error is returned. | 
		
	
		
			
				|  |  |  |  |     fn contexts(&self) -> Result<(usize, usize)> { | 
		
	
		
			
				|  |  |  |  |     fn contexts(&self) -> anyhow::Result<(usize, usize)> { | 
		
	
		
			
				|  |  |  |  |         let both = self.usize_of("context")?.unwrap_or(0); | 
		
	
		
			
				|  |  |  |  |         let after = self.usize_of("after-context")?.unwrap_or(both); | 
		
	
		
			
				|  |  |  |  |         let before = self.usize_of("before-context")?.unwrap_or(both); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1061,7 +1063,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// Parse the dfa-size-limit argument option into a byte count. | 
		
	
		
			
				|  |  |  |  |     fn dfa_size_limit(&self) -> Result<Option<usize>> { | 
		
	
		
			
				|  |  |  |  |     fn dfa_size_limit(&self) -> anyhow::Result<Option<usize>> { | 
		
	
		
			
				|  |  |  |  |         let r = self.parse_human_readable_size("dfa-size-limit")?; | 
		
	
		
			
				|  |  |  |  |         u64_to_usize("dfa-size-limit", r) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1072,7 +1074,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     /// if set to automatic, the Searcher will do BOM sniffing for UTF-16 | 
		
	
		
			
				|  |  |  |  |     /// and transcode seamlessly. If disabled, no BOM sniffing nor transcoding | 
		
	
		
			
				|  |  |  |  |     /// will occur. | 
		
	
		
			
				|  |  |  |  |     fn encoding(&self) -> Result<EncodingMode> { | 
		
	
		
			
				|  |  |  |  |     fn encoding(&self) -> anyhow::Result<EncodingMode> { | 
		
	
		
			
				|  |  |  |  |         if self.is_present("no-encoding") { | 
		
	
		
			
				|  |  |  |  |             return Ok(EncodingMode::Auto); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1092,7 +1094,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// Return the file separator to use based on the CLI configuration. | 
		
	
		
			
				|  |  |  |  |     fn file_separator(&self) -> Result<Option<Vec<u8>>> { | 
		
	
		
			
				|  |  |  |  |     fn file_separator(&self) -> anyhow::Result<Option<Vec<u8>>> { | 
		
	
		
			
				|  |  |  |  |         // File separators are only used for the standard grep-line format. | 
		
	
		
			
				|  |  |  |  |         if self.output_kind() != OutputKind::Standard { | 
		
	
		
			
				|  |  |  |  |             return Ok(None); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1130,7 +1132,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     /// for the current system is used if the value is not set. | 
		
	
		
			
				|  |  |  |  |     /// | 
		
	
		
			
				|  |  |  |  |     /// If an invalid pattern is provided, then an error is returned. | 
		
	
		
			
				|  |  |  |  |     fn hyperlink_config(&self) -> Result<HyperlinkConfig> { | 
		
	
		
			
				|  |  |  |  |     fn hyperlink_config(&self) -> anyhow::Result<HyperlinkConfig> { | 
		
	
		
			
				|  |  |  |  |         let mut env = HyperlinkEnvironment::new(); | 
		
	
		
			
				|  |  |  |  |         env.host(hostname(self.value_of_os("hostname-bin"))) | 
		
	
		
			
				|  |  |  |  |             .wsl_prefix(wsl_prefix()); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1140,8 +1142,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |                 Some(format) => match format.parse() { | 
		
	
		
			
				|  |  |  |  |                     Ok(format) => format, | 
		
	
		
			
				|  |  |  |  |                     Err(err) => { | 
		
	
		
			
				|  |  |  |  |                         let msg = format!("invalid hyperlink format: {err}"); | 
		
	
		
			
				|  |  |  |  |                         return Err(msg.into()); | 
		
	
		
			
				|  |  |  |  |                         anyhow::bail!("invalid hyperlink format: {err}"); | 
		
	
		
			
				|  |  |  |  |                     } | 
		
	
		
			
				|  |  |  |  |                 }, | 
		
	
		
			
				|  |  |  |  |             }; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1204,7 +1205,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     /// The maximum number of columns allowed on each line. | 
		
	
		
			
				|  |  |  |  |     /// | 
		
	
		
			
				|  |  |  |  |     /// If `0` is provided, then this returns `None`. | 
		
	
		
			
				|  |  |  |  |     fn max_columns(&self) -> Result<Option<u64>> { | 
		
	
		
			
				|  |  |  |  |     fn max_columns(&self) -> anyhow::Result<Option<u64>> { | 
		
	
		
			
				|  |  |  |  |         Ok(self.usize_of_nonzero("max-columns")?.map(|n| n as u64)) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1215,12 +1216,12 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// The maximum number of matches permitted. | 
		
	
		
			
				|  |  |  |  |     fn max_count(&self) -> Result<Option<u64>> { | 
		
	
		
			
				|  |  |  |  |     fn max_count(&self) -> anyhow::Result<Option<u64>> { | 
		
	
		
			
				|  |  |  |  |         Ok(self.usize_of("max-count")?.map(|n| n as u64)) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// Parses the max-filesize argument option into a byte count. | 
		
	
		
			
				|  |  |  |  |     fn max_file_size(&self) -> Result<Option<u64>> { | 
		
	
		
			
				|  |  |  |  |     fn max_file_size(&self) -> anyhow::Result<Option<u64>> { | 
		
	
		
			
				|  |  |  |  |         self.parse_human_readable_size("max-filesize") | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1311,7 +1312,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// Builds the set of glob overrides from the command line flags. | 
		
	
		
			
				|  |  |  |  |     fn overrides(&self) -> Result<Override> { | 
		
	
		
			
				|  |  |  |  |     fn overrides(&self) -> anyhow::Result<Override> { | 
		
	
		
			
				|  |  |  |  |         let globs = self.values_of_lossy_vec("glob"); | 
		
	
		
			
				|  |  |  |  |         let iglobs = self.values_of_lossy_vec("iglob"); | 
		
	
		
			
				|  |  |  |  |         if globs.is_empty() && iglobs.is_empty() { | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1378,7 +1379,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     /// | 
		
	
		
			
				|  |  |  |  |     /// If the provided path separator is more than a single byte, then an | 
		
	
		
			
				|  |  |  |  |     /// error is returned. | 
		
	
		
			
				|  |  |  |  |     fn path_separator(&self) -> Result<Option<u8>> { | 
		
	
		
			
				|  |  |  |  |     fn path_separator(&self) -> anyhow::Result<Option<u8>> { | 
		
	
		
			
				|  |  |  |  |         let sep = match self.value_of_os("path-separator") { | 
		
	
		
			
				|  |  |  |  |             None => return Ok(None), | 
		
	
		
			
				|  |  |  |  |             Some(sep) => cli::unescape_os(&sep), | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1386,14 +1387,14 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |         if sep.is_empty() { | 
		
	
		
			
				|  |  |  |  |             Ok(None) | 
		
	
		
			
				|  |  |  |  |         } else if sep.len() > 1 { | 
		
	
		
			
				|  |  |  |  |             Err(From::from(format!( | 
		
	
		
			
				|  |  |  |  |             anyhow::bail!( | 
		
	
		
			
				|  |  |  |  |                 "A path separator must be exactly one byte, but \ | 
		
	
		
			
				|  |  |  |  |                  the given separator is {} bytes: {}\n\ | 
		
	
		
			
				|  |  |  |  |                  In some shells on Windows '/' is automatically \ | 
		
	
		
			
				|  |  |  |  |                  expanded. Use '//' instead.", | 
		
	
		
			
				|  |  |  |  |                 sep.len(), | 
		
	
		
			
				|  |  |  |  |                 cli::escape(&sep), | 
		
	
		
			
				|  |  |  |  |             ))) | 
		
	
		
			
				|  |  |  |  |             ) | 
		
	
		
			
				|  |  |  |  |         } else { | 
		
	
		
			
				|  |  |  |  |             Ok(Some(sep[0])) | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1433,7 +1434,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     /// This includes reading the -e/--regexp and -f/--file flags. | 
		
	
		
			
				|  |  |  |  |     /// | 
		
	
		
			
				|  |  |  |  |     /// If any pattern is invalid UTF-8, then an error is returned. | 
		
	
		
			
				|  |  |  |  |     fn patterns(&self) -> Result<Vec<String>> { | 
		
	
		
			
				|  |  |  |  |     fn patterns(&self) -> anyhow::Result<Vec<String>> { | 
		
	
		
			
				|  |  |  |  |         if self.is_present("files") || self.is_present("type-list") { | 
		
	
		
			
				|  |  |  |  |             return Ok(vec![]); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1485,7 +1486,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     /// if -F/--fixed-strings is set. | 
		
	
		
			
				|  |  |  |  |     /// | 
		
	
		
			
				|  |  |  |  |     /// If the pattern is not valid UTF-8, then an error is returned. | 
		
	
		
			
				|  |  |  |  |     fn pattern_from_os_str(&self, pat: &OsStr) -> Result<String> { | 
		
	
		
			
				|  |  |  |  |     fn pattern_from_os_str(&self, pat: &OsStr) -> anyhow::Result<String> { | 
		
	
		
			
				|  |  |  |  |         let s = cli::pattern_from_os(pat)?; | 
		
	
		
			
				|  |  |  |  |         Ok(self.pattern_from_str(s)) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1525,7 +1526,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     /// Builds the set of globs for filtering files to apply to the --pre | 
		
	
		
			
				|  |  |  |  |     /// flag. If no --pre-globs are available, then this always returns an | 
		
	
		
			
				|  |  |  |  |     /// empty set of globs. | 
		
	
		
			
				|  |  |  |  |     fn preprocessor_globs(&self) -> Result<Override> { | 
		
	
		
			
				|  |  |  |  |     fn preprocessor_globs(&self) -> anyhow::Result<Override> { | 
		
	
		
			
				|  |  |  |  |         let globs = self.values_of_lossy_vec("pre-glob"); | 
		
	
		
			
				|  |  |  |  |         if globs.is_empty() { | 
		
	
		
			
				|  |  |  |  |             return Ok(Override::empty()); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1538,7 +1539,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// Parse the regex-size-limit argument option into a byte count. | 
		
	
		
			
				|  |  |  |  |     fn regex_size_limit(&self) -> Result<Option<usize>> { | 
		
	
		
			
				|  |  |  |  |     fn regex_size_limit(&self) -> anyhow::Result<Option<usize>> { | 
		
	
		
			
				|  |  |  |  |         let r = self.parse_human_readable_size("regex-size-limit")?; | 
		
	
		
			
				|  |  |  |  |         u64_to_usize("regex-size-limit", r) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1549,7 +1550,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// Returns the sorting criteria based on command line parameters. | 
		
	
		
			
				|  |  |  |  |     fn sort_by(&self) -> Result<SortBy> { | 
		
	
		
			
				|  |  |  |  |     fn sort_by(&self) -> anyhow::Result<SortBy> { | 
		
	
		
			
				|  |  |  |  |         // For backcompat, continue supporting deprecated --sort-files flag. | 
		
	
		
			
				|  |  |  |  |         if self.is_present("sort-files") { | 
		
	
		
			
				|  |  |  |  |             return Ok(SortBy::asc(SortByKind::Path)); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1596,7 +1597,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// Return the number of threads that should be used for parallelism. | 
		
	
		
			
				|  |  |  |  |     fn threads(&self) -> Result<usize> { | 
		
	
		
			
				|  |  |  |  |     fn threads(&self) -> anyhow::Result<usize> { | 
		
	
		
			
				|  |  |  |  |         if self.sort_by()?.kind != SortByKind::None { | 
		
	
		
			
				|  |  |  |  |             return Ok(1); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1607,7 +1608,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// Builds a file type matcher from the command line flags. | 
		
	
		
			
				|  |  |  |  |     fn types(&self) -> Result<Types> { | 
		
	
		
			
				|  |  |  |  |     fn types(&self) -> anyhow::Result<Types> { | 
		
	
		
			
				|  |  |  |  |         let mut builder = TypesBuilder::new(); | 
		
	
		
			
				|  |  |  |  |         builder.add_defaults(); | 
		
	
		
			
				|  |  |  |  |         for ty in self.values_of_lossy_vec("type-clear") { | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1667,7 +1668,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     /// | 
		
	
		
			
				|  |  |  |  |     /// If the number is zero, then it is considered absent and `None` is | 
		
	
		
			
				|  |  |  |  |     /// returned. | 
		
	
		
			
				|  |  |  |  |     fn usize_of_nonzero(&self, name: &str) -> Result<Option<usize>> { | 
		
	
		
			
				|  |  |  |  |     fn usize_of_nonzero(&self, name: &str) -> anyhow::Result<Option<usize>> { | 
		
	
		
			
				|  |  |  |  |         let n = match self.usize_of(name)? { | 
		
	
		
			
				|  |  |  |  |             None => return Ok(None), | 
		
	
		
			
				|  |  |  |  |             Some(n) => n, | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1677,7 +1678,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /// Safely reads an arg value with the given name, and if it's present, | 
		
	
		
			
				|  |  |  |  |     /// tries to parse it as a usize value. | 
		
	
		
			
				|  |  |  |  |     fn usize_of(&self, name: &str) -> Result<Option<usize>> { | 
		
	
		
			
				|  |  |  |  |     fn usize_of(&self, name: &str) -> anyhow::Result<Option<usize>> { | 
		
	
		
			
				|  |  |  |  |         match self.value_of_lossy(name) { | 
		
	
		
			
				|  |  |  |  |             None => Ok(None), | 
		
	
		
			
				|  |  |  |  |             Some(v) => v.parse().map(Some).map_err(From::from), | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1691,7 +1692,7 @@ impl ArgMatches { | 
		
	
		
			
				|  |  |  |  |     fn parse_human_readable_size( | 
		
	
		
			
				|  |  |  |  |         &self, | 
		
	
		
			
				|  |  |  |  |         arg_name: &str, | 
		
	
		
			
				|  |  |  |  |     ) -> Result<Option<u64>> { | 
		
	
		
			
				|  |  |  |  |     ) -> anyhow::Result<Option<u64>> { | 
		
	
		
			
				|  |  |  |  |         let size = match self.value_of_lossy(arg_name) { | 
		
	
		
			
				|  |  |  |  |             None => return Ok(None), | 
		
	
		
			
				|  |  |  |  |             Some(size) => size, | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1770,11 +1771,10 @@ and look-around.", | 
		
	
		
			
				|  |  |  |  | fn suggest_multiline(msg: String) -> String { | 
		
	
		
			
				|  |  |  |  |     if msg.contains("the literal") && msg.contains("not allowed") { | 
		
	
		
			
				|  |  |  |  |         format!( | 
		
	
		
			
				|  |  |  |  |             "{} | 
		
	
		
			
				|  |  |  |  |             "{msg} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Consider enabling multiline mode with the --multiline flag (or -U for short). | 
		
	
		
			
				|  |  |  |  | When multiline mode is enabled, new line characters can be matched.", | 
		
	
		
			
				|  |  |  |  |             msg | 
		
	
		
			
				|  |  |  |  |         ) | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |         msg | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1783,18 +1783,16 @@ When multiline mode is enabled, new line characters can be matched.", | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /// Convert the result of parsing a human readable file size to a `usize`, | 
		
	
		
			
				|  |  |  |  | /// failing if the type does not fit. | 
		
	
		
			
				|  |  |  |  | fn u64_to_usize(arg_name: &str, value: Option<u64>) -> Result<Option<usize>> { | 
		
	
		
			
				|  |  |  |  | fn u64_to_usize( | 
		
	
		
			
				|  |  |  |  |     arg_name: &str, | 
		
	
		
			
				|  |  |  |  |     value: Option<u64>, | 
		
	
		
			
				|  |  |  |  | ) -> anyhow::Result<Option<usize>> { | 
		
	
		
			
				|  |  |  |  |     use std::usize; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     let value = match value { | 
		
	
		
			
				|  |  |  |  |         None => return Ok(None), | 
		
	
		
			
				|  |  |  |  |         Some(value) => value, | 
		
	
		
			
				|  |  |  |  |     }; | 
		
	
		
			
				|  |  |  |  |     if value <= usize::MAX as u64 { | 
		
	
		
			
				|  |  |  |  |         Ok(Some(value as usize)) | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |         Err(From::from(format!("number too large for {}", arg_name))) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     let Some(value) = value else { return Ok(None) }; | 
		
	
		
			
				|  |  |  |  |     usize::try_from(value) | 
		
	
		
			
				|  |  |  |  |         .map_err(|_| anyhow::anyhow!("number too large for {arg_name}")) | 
		
	
		
			
				|  |  |  |  |         .map(Some) | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /// Sorts by an optional parameter. | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1818,7 +1816,7 @@ fn sort_by_option<T: Ord>( | 
		
	
		
			
				|  |  |  |  | /// corresponds to a `--help` or `--version` request. In which case, the | 
		
	
		
			
				|  |  |  |  | /// corresponding output is printed and the current process is exited | 
		
	
		
			
				|  |  |  |  | /// successfully. | 
		
	
		
			
				|  |  |  |  | fn clap_matches<I, T>(args: I) -> Result<clap::ArgMatches<'static>> | 
		
	
		
			
				|  |  |  |  | fn clap_matches<I, T>(args: I) -> anyhow::Result<clap::ArgMatches<'static>> | 
		
	
		
			
				|  |  |  |  | where | 
		
	
		
			
				|  |  |  |  |     I: IntoIterator<Item = T>, | 
		
	
		
			
				|  |  |  |  |     T: Into<OsString> + Clone, | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1845,7 +1843,7 @@ where | 
		
	
		
			
				|  |  |  |  | /// a directory that no longer exists. We attempt some fallback mechanisms, | 
		
	
		
			
				|  |  |  |  | /// such as querying the PWD environment variable, but otherwise return an | 
		
	
		
			
				|  |  |  |  | /// error. | 
		
	
		
			
				|  |  |  |  | fn current_dir() -> Result<PathBuf> { | 
		
	
		
			
				|  |  |  |  | fn current_dir() -> anyhow::Result<PathBuf> { | 
		
	
		
			
				|  |  |  |  |     let err = match env::current_dir() { | 
		
	
		
			
				|  |  |  |  |         Err(err) => err, | 
		
	
		
			
				|  |  |  |  |         Ok(cwd) => return Ok(cwd), | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1855,12 +1853,10 @@ fn current_dir() -> Result<PathBuf> { | 
		
	
		
			
				|  |  |  |  |             return Ok(PathBuf::from(cwd)); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     Err(format!( | 
		
	
		
			
				|  |  |  |  |         "failed to get current working directory: {} \ | 
		
	
		
			
				|  |  |  |  |     anyhow::bail!( | 
		
	
		
			
				|  |  |  |  |         "failed to get current working directory: {err} \ | 
		
	
		
			
				|  |  |  |  |          --- did your CWD get deleted?", | 
		
	
		
			
				|  |  |  |  |         err, | 
		
	
		
			
				|  |  |  |  |     ) | 
		
	
		
			
				|  |  |  |  |     .into()) | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /// Retrieves the hostname that ripgrep should use wherever a hostname is | 
		
	
	
		
			
				
					
					|  |  |  |   |