mirror of
https://github.com/sharkdp/fd.git
synced 2024-11-18 01:40:34 +01:00
Use RegexSet instead of hand-written parser
This commit is contained in:
parent
86fe9977e8
commit
370d9f081f
4 changed files with 17 additions and 54 deletions
|
@ -16,6 +16,7 @@ use exec::CommandTemplate;
|
|||
use lscolors::LsColors;
|
||||
use walk::FileType;
|
||||
use regex_syntax::{Expr, ExprBuilder};
|
||||
use regex::RegexSet;
|
||||
|
||||
/// Configuration options for *fd*.
|
||||
pub struct FdOptions {
|
||||
|
@ -65,7 +66,7 @@ pub struct FdOptions {
|
|||
/// The extension to search for. Only entries matching the extension will be included.
|
||||
///
|
||||
/// The value (if present) will be a lowercase string without leading dots.
|
||||
pub extensions: Option<HashSet<String>>,
|
||||
pub extensions: Option<RegexSet>,
|
||||
|
||||
/// If a value is supplied, each item found will be used to generate and execute commands.
|
||||
pub command: Option<CommandTemplate>,
|
||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -25,7 +25,6 @@ mod app;
|
|||
mod exec;
|
||||
mod internal;
|
||||
mod output;
|
||||
mod utils;
|
||||
mod walk;
|
||||
|
||||
#[cfg(windows)]
|
||||
|
@ -38,7 +37,7 @@ use std::sync::Arc;
|
|||
use std::time;
|
||||
|
||||
use atty::Stream;
|
||||
use regex::RegexBuilder;
|
||||
use regex::{RegexBuilder, RegexSetBuilder};
|
||||
|
||||
use exec::CommandTemplate;
|
||||
use internal::{error, pattern_has_uppercase_char, transform_args_with_exec, FdOptions};
|
||||
|
@ -153,8 +152,15 @@ fn main() {
|
|||
.collect(),
|
||||
},
|
||||
extensions: matches.values_of("extension").map(|exts| {
|
||||
exts.map(|e| String::from(".") + &e.trim_left_matches('.'))
|
||||
.collect()
|
||||
let patterns = exts.map(|e| e.trim_left_matches('.'))
|
||||
.map(|e| format!(r".\.{}$", regex::escape(e)));
|
||||
match RegexSetBuilder::new(patterns)
|
||||
.case_insensitive(true)
|
||||
.build()
|
||||
{
|
||||
Ok(re) => re,
|
||||
Err(err) => error(err.description()),
|
||||
}
|
||||
}),
|
||||
command,
|
||||
exclude_patterns: matches
|
||||
|
|
45
src/utils.rs
45
src/utils.rs
|
@ -1,45 +0,0 @@
|
|||
// Copyright (c) 2017 fd developers
|
||||
// Licensed under the Apache License, Version 2.0
|
||||
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>
|
||||
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||
// at your option. All files in the project carrying such
|
||||
// notice may not be copied, modified, or distributed except
|
||||
// according to those terms.
|
||||
|
||||
use std::path::Path;
|
||||
use std::iter::Iterator;
|
||||
|
||||
/// Determine if an os string ends with any of the given extensions (case insensitive).
|
||||
pub fn path_has_any_extension<'a, I>(path: &Path, exts: I) -> bool
|
||||
where
|
||||
I: 'a + Iterator<Item = &'a String> + Clone,
|
||||
{
|
||||
// TODO: remove these two lines when we drop support for Rust version < 1.23.
|
||||
#[allow(unused_imports)]
|
||||
use std::ascii::AsciiExt;
|
||||
|
||||
if let Some(ref name) = path.file_name() {
|
||||
if let Some(ref name_str) = name.to_str() {
|
||||
exts.clone().any(|x| {
|
||||
let mut it = name_str.chars().rev();
|
||||
|
||||
if x.chars()
|
||||
.rev()
|
||||
.zip(&mut it)
|
||||
.all(|(a, b)| a.eq_ignore_ascii_case(&b))
|
||||
{
|
||||
match it.next() {
|
||||
Some('/') | None => false,
|
||||
_ => true,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
|
@ -11,7 +11,6 @@ extern crate ctrlc;
|
|||
use exec;
|
||||
use fshelper;
|
||||
use internal::{error, FdOptions, EXITCODE_SIGINT, MAX_BUFFER_LENGTH};
|
||||
use utils::path_has_any_extension;
|
||||
use output;
|
||||
|
||||
use std::process;
|
||||
|
@ -214,9 +213,11 @@ pub fn scan(path_vec: &[PathBuf], pattern: Arc<Regex>, config: Arc<FdOptions>) {
|
|||
}
|
||||
|
||||
// Filter out unwanted extensions.
|
||||
if let Some(ref filter_exts) = config.extensions {
|
||||
if !path_has_any_extension(entry_path, filter_exts.iter()) {
|
||||
return ignore::WalkState::Continue;
|
||||
if let Some(ref exts_regex) = config.extensions {
|
||||
if let Some(path_str) = entry_path.file_name().map_or(None, |s| s.to_str()) {
|
||||
if !exts_regex.is_match(path_str) {
|
||||
return ignore::WalkState::Continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue