olson-sean-k / wax

Opinionated and portable globs that can be matched against paths and directory trees.
https://glob.guide
MIT License
112 stars 10 forks source link

Support more options? #27

Closed WindSoilder closed 2 years ago

WindSoilder commented 2 years ago

It would be nice to support some glob options, like matching hidden directory or not.

In the nu-glob crate(which is a fork of glob crate with some addition, it supports something like this: https://github.com/nushell/nushell/blob/main/crates/nu-glob/src/lib.rs#L870-L892

/// Configuration options to modify the behaviour of `Pattern::matches_with(..)`.
#[allow(missing_copy_implementations)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct MatchOptions {
    /// Whether or not patterns should be matched in a case-sensitive manner.
    /// This currently only considers upper/lower case relationships between
    /// ASCII characters, but in future this might be extended to work with
    /// Unicode.
    pub case_sensitive: bool,

    /// Whether or not path-component separator characters (e.g. `/` on
    /// Posix) must be matched by a literal `/`, rather than by `*` or `?` or
    /// `[...]`.
    pub require_literal_separator: bool,

    /// Whether or not paths that contain components that start with a `.`
    /// will require that `.` appears literally in the pattern; `*`, `?`, `**`,
    /// or `[...]` will not match. This is useful because such files are
    /// conventionally considered hidden on Unix systems and it might be
    /// desirable to skip them when listing files.
    pub require_literal_leading_dot: bool,

    /// if given pattern contains `**`, this flag check if `**` matches hidden directory.
    /// For example: if true, `**` will match `.abcdef/ghi`.
    pub recursive_match_hidden_dir: bool,
}
olson-sean-k commented 2 years ago

I believe Wax is capable of all the behaviors described in the example code. However, the design intentionally avoids exposing some of these behaviors as simple toggles controlled via the API, so some additional code may be required for your use case.

When matching a directory tree via Glob::walk, the Walk iterator allows calling code to control the traversal of the file system via filter_tree. Unlike toggles, this filtering is arbitrary and can be used to discard hidden files and/or directories. See this example for filter_tree in the API docs, which illustrates just that. I expect this to be a fairly common pattern, so I may introduce functions on Walk to make this kind of filtering easier to achieve. Note that this only applies to semantic matching (i.e., Glob::walk and friends) and not logical matching (i.e., Pattern::is_match).

Toggling case sensitivity via an API would prevent glob expressions from matching sub-text using different casing requirements. Instead, Wax uses flags for this. Every expression chooses how and where casing is handled. In the simplest instance, expressions simply begin with a flag, such as in (?i)**/insensitive.

Regarding literal separators, glob expressions are designed with consistent behavior in mind, especially for individual patterns. For this reason, the matching behavior of patterns is deliberately not configurable. Instead, glob expressions can match across component boundaries via tree wildcards ** and/or repetitions <...>.

Please let me know if there's a remaining feature that you think Wax should support or that you're unsure how to achieve using the current API.

WindSoilder commented 2 years ago

Thanks for your detailed instruction, it seems I can work around this :-)

Close the issue for now:)