README.md

ExMinimatch
===========

Globbing paths without walking the tree! Elixir and Erlang provide `wildcard`
functions in the stdlib. But these will walk the directory tree. If you simply
want to test whether a file path matches a glob, ExMinimatch is for you.

Quick examples:

    iex> import ExMinimatch
    nil

    iex> match("**/*{1..2}{a,b}.{png,jpg}", "asdf/pic2a.jpg")
    true

    iex> match("*.+(bar|foo)", "bar.foo")
    true

    iex> ["me.jpg", "images/me.png", "images/you.svg"] |> filter("**/*.{png,jpg}")
    ["me.jpg", "images/me.png"]

Compiled forms below allows us to cache the %ExMinimatcher{} struct when used
against large number of files repeated.

    iex> compile("**/*{1..2}{a,b}.{png,jpg}") |> match("asdf/pic2a.jpg")
    true

    iex> ["me.jpg", "images/me.png", "images/you.svg"] |> filter(compile("**/*.{png,jpg}"))
    ["me.jpg", "images/me.png"]

ExMinimatch is a port of the [minimatch](https://github.com/isaacs/minimatch)
javascript project. It is a close port but not exactly the same. See
"Comparison to minimatch.js" section below.

## Glob Patterns

Supports these glob features:

- [Brace Expansion](https://github.com/gniquil/ex_brace_expansion)
- Extended glob matching
- "Globstar" ** matching

See:

- man sh
- man bash
- man 3 fnmatch
- man 5 gitignore

## Options

`compile`, `match`, and `filter` all have forms that take an options argument (as a map %{}).
The following are the explanations. By default, all fo these are false.

### log

Possible values are `:info`, and `:debug`. If set, will dump information into
repl. `:debug` dumps more.

### nobrace

Do not expand `{a,b}` and `{1..3}` brace sets.

### noglobstar

Disable `**` matching against multiple folder names.

### dot

Allow patterns to match filenames starting with a period, even if the pattern
does not explicitly have a period in that spot.

Note that by default, `a/**/b` will not match `a/.d/b`, unless dot is set, e.g.
`match("a/**/b", "a/.d/b", %{dot: true})`

### noext

Disable "extglob" style patterns like `+(a|b)`.

### nocase

Perform a case-insensitive match.

### match_base

If set, then patterns without slashes will be matched against the basename of
the path if it contains slashes. For example, `a?b` would match the path
`/xyz/123/acb`, but not `/xyz/acb/123`.

### nocomment

Suppress the behavior of treating `#` at the start of a pattern as a comment.

### nonegate

Suppress the behavior of treating leading `!` character as negation.

## Comparison to minimatch.js

`minimatch.js` converts a glob into a list of regular expressions. However, when
it comes to matching, one can choose to use `minimatch.match` or use the complete
regular expression generated by `minimatch.makeRe` to test it against a file
pattern. Unfortunately, the 2 approaches are __inconsistent__. Notably the full regular
expression based approach has a few important pieces missing. Therefore, here
we implement the first approach. For detail, take a look at `ExMinimatcher.Matcher`.