grox 0.10.0

Command-line tool that searches for regex matches in a file tree.
Documentation
Grox is a command-line tool that searches a file tree for regex matches.

# Usage

For example,

```text
$ grox the
(0) ./lib.rs:21: ... g to only retrieve the first match per f ...
(1) ./lib.rs:29: /// Path to the file.
(2) ./lib.rs:31: ... e number (1-up) of the match.
(3) ./lib.rs:97: /// Sets the file pattern.
(4) ./lib.rs:106: ... e a directory from the search.
(5) ./lib.rs:110: ... wise extension of the starting direct ...
(6) ./lib.rs:110: ... y.  For example, if the starting direct ...
(7) ./lib.rs:110: ... tory is `../foo`, then an excluded dire ...
(8) ./lib.rs:115: /// Sets the maximum search d ...
(9) ./lib.rs:119: ... le, searches only the starting direct ...
(10) ./lib.rs:133: ... Attempts to build the searcher.
(11) ./lib.rs:137: ... ful and an error if the starting direct ...
(12) ./lib.rs:236: .and_then(OsStr::to_str ...
(13) ./lib.rs:237: .and_then(|name| name.ch ...
(14) ./lib.rs:493: ... oing to fold my clothes").unwrap();
(15) ./history.rs:11: /// Path to the starting direct ...
(16) ./history.rs:23: ... ies excluded from the search.
(17) ./history.rs:44: ... d an `io:Error` if the starting direct ...
(18) ./history.rs:75: ... / * `file` - Path to the file.
(19) ./history.rs:79: ... sful and an error otherwise.
(20) ./history.rs:85: ... / Add a location to the history object.
(21) ./history.rs:89: ... / * `file` - Path to the file.
(22) ./history.rs:94: ... an `io::Error` if the path couldn't be  ...
(23) ./history.rs:101: /// Save the history object t ...
(24) ./history.rs:105: ... / * `file` - Path to the file.
(25) ./history.rs:109: ... sful and an error otherwise.
(26) ./history.rs:121: /// Path to the file.
(27) ./open.rs:3: /// Facilitates the opening of a file  ...
(28) ./open.rs:5: /// Does the opener handle a g ...
(29) ./open.rs:9: ... ` - Name of/path to the editor.
(30) ./open.rs:16: /// Forms the `execv` argumen ...
(31) ./open.rs:20: ... / * `file` - Path to the file to be opened ...
(32) ./open.rs:25: ... s to `execv` minus the path to the edito ...
(33) ./open.rs:25: ... ` minus the path to the editor that shou ...
(34) ./open.rs:25: ... r that should go at the beginning.
(35) ./open.rs:257: ... t (if supported by the opener).
(36) ./main.rs:24: ... ory excluded from the search.  Can be sp ...
(37) ./main.rs:32: ... hort, help = "Open the file for the spec ...
(38) ./main.rs:32: ... "Open the file for the specified resul ...
```

By default the search starts with the current working directory.  You can change this by `-d DIRECTORY`.

You can limit the directory search depth by `-p DEPTH`.  A depth of 0 searches only the starting directory.

If you only want to get the names of the matching files, add `-n`:

```text
$ grox the -n
(0) ./lib.rs
(1) ./history.rs
(2) ./open.rs
(3) ./main.rs
```

If you only want to search files whose names match a certain pattern, you can use `-f`:

```text
$ grox some_pattern -f '\.rs$'
```

You can exclude directories from the search by `-x`:

```text
$ grox some_pattern -x ./foo -x ./bar/baz
```

The excluded directories can either be absolute or relative to the starting directory.  For example, `-d ../foo -x bar -x /baz` would ignore the directories `../foo/bar` and `/baz`.

By default, grox will display up to 15 non-whitespace characters on either side of the matching text.  You can change this value by setting the `GROX_PADDING` environment variable:

```text
$ GROX_PADDING=30 grox the
(0) ./lib.rs:21: ... // Flag specifying to only retrieve the first match per file.
(1) ./lib.rs:29: /// Path to the file.
(2) ./lib.rs:31: /// Line number (1-up) of the match.
(3) ./lib.rs:97: /// Sets the file pattern.
(4) ./lib.rs:106: /// Exclude a directory from the search.
(5) ./lib.rs:110: ... .  Must be a string-wise extension of the starting directory.  For example,  ...
(6) ./lib.rs:110: ... tarting directory.  For example, if the starting directory is `../foo`, t ...
(7) ./lib.rs:110: ... he starting directory is `../foo`, then an excluded directory could be `.. ...
(8) ./lib.rs:115: /// Sets the maximum search depth.
(9) ./lib.rs:119: ... pth of 0, for example, searches only the starting directory.
(10) ./lib.rs:133: /// Attempts to build the searcher.
(11) ./lib.rs:137: ... archer if successful and an error if the starting directory couldn't be ac ...
(12) ./lib.rs:236: .and_then(OsStr::to_str)
(13) ./lib.rs:237: .and_then(|name| name.chars().next())
(14) ./lib.rs:493: ... m not a fool\nI'm going to fold my clothes").unwrap();
(15) ./history.rs:11: /// Path to the starting directory.
(16) ./history.rs:23: /// Directories excluded from the search.
(17) ./history.rs:44: ... t if successful and an `io:Error` if the starting directory couldn't be re ...
(18) ./history.rs:75: /// * `file` - Path to the file.
(19) ./history.rs:79: ... y object if successful and an error otherwise.
(20) ./history.rs:85: /// Add a location to the history object.
(21) ./history.rs:89: /// * `file` - Path to the file.
(22) ./history.rs:94: ... if successful and an `io::Error` if the path couldn't be resolved.
(23) ./history.rs:101: /// Save the history object to a file.
(24) ./history.rs:105: /// * `file` - Path to the file.
(25) ./history.rs:109: ... /// `()` if successful and an error otherwise.
(26) ./history.rs:121: /// Path to the file.
(27) ./open.rs:3: /// Facilitates the opening of a file with a provided ed ...
(28) ./open.rs:5: /// Does the opener handle a given editor?
(29) ./open.rs:9: /// * `editor` - Name of/path to the editor.
(30) ./open.rs:16: /// Forms the `execv` arguments for opening a fi ...
(31) ./open.rs:20: /// * `file` - Path to the file to be opened.
(32) ./open.rs:25: ... / Arguments to pass to `execv` minus the path to the editor that should go at  ...
(33) ./open.rs:25: ... s to pass to `execv` minus the path to the editor that should go at the beginn ...
(34) ./open.rs:25: ... e path to the editor that should go at the beginning.
(35) ./open.rs:257: ... ne` - Line to open at (if supported by the opener).
(36) ./main.rs:24: ... nd, help = "Directory excluded from the search.  Can be specified multiple  ...
(37) ./main.rs:32: #[arg(short, help = "Open the file for the specified result.")]
(38) ./main.rs:32: ... arg(short, help = "Open the file for the specified result.")]
```

A value of 0 will show the entire containing line.

## Opening files

You can open the n-th match in an editor with the `-l` option.  For example, say you found these matches:

```text
$ grox some_pattern
(0) file1.txt:55: ...
(1) file2:txt:2: ...
```

If you wanted to open up file1.txt, you could run the search again with `-l`:

```text
$ grox some_pattern -l 0
```

If the `EDITOR` environment variable is set, then Grox will use the specified executable.  Otherwise, it will try to use `less`.  You can manually specify the editor by

```text
$ grox some_pattern -l 0 -e vim
```

If the chosen editor is one of the following, then Grox will open up the file to the line containing the match:

* less
* more
* vi
* vim
* nvim
* emacs
* code
* xed
* subl

## History

When you run a search without `-l` and stdout is a terminal, a history file is created at `~/.grox_history.json`.  If you then re-run the exact same search with `-l`, Grox will grab the result from the history file instead of re-running the search.

Every search that doesn't use `-l` will overwrite the history file if it exists.  That is, only the most recent search is saved.

If you pass `-c`, then the the history file, if it exists, will be deleted before Grox does anything else.