mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-07-31 20:21:59 -07:00
Compare commits
30 Commits
globset-0.
...
ignore-0.1
Author | SHA1 | Date | |
---|---|---|---|
|
487713aa34 | ||
|
e300541701 | ||
|
e9df420d2f | ||
|
201b4fc757 | ||
|
90a11dec5e | ||
|
9456d95e8f | ||
|
0c298f60a6 | ||
|
79271fcb33 | ||
|
fc975af8e9 | ||
|
1425d6735e | ||
|
aed3ccb9c7 | ||
|
33c95d2919 | ||
|
01deac9427 | ||
|
b4bc3b6349 | ||
|
685cc6c562 | ||
|
08c017330f | ||
|
2f3a8c7f69 | ||
|
3ac1b68e54 | ||
|
0ebd5465b7 | ||
|
5cb4bb9ea0 | ||
|
c8a179b4da | ||
|
46f94826fd | ||
|
75f1855a91 | ||
|
fd9870d668 | ||
|
a3a2708067 | ||
|
78847b65c8 | ||
|
e962eea1cc | ||
|
95bc678403 | ||
|
68af3bbdc4 | ||
|
70b6bdb104 |
85
CHANGELOG.md
85
CHANGELOG.md
@@ -1,3 +1,88 @@
|
|||||||
|
0.5.1 (2017-04-09)
|
||||||
|
==================
|
||||||
|
Feature enhancements:
|
||||||
|
|
||||||
|
* Added or improved file type filtering for vim.
|
||||||
|
* [FEATURE #34](https://github.com/BurntSushi/ripgrep/issues/34):
|
||||||
|
Add a `-o/--only-matching` flag.
|
||||||
|
* [FEATURE #377](https://github.com/BurntSushi/ripgrep/issues/377):
|
||||||
|
Column numbers can now be customized with a color. (The default is
|
||||||
|
no color.)
|
||||||
|
* [FEATURE #419](https://github.com/BurntSushi/ripgrep/issues/419):
|
||||||
|
Added `-0` short flag option for `--null`.
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* [BUG #381](https://github.com/BurntSushi/ripgrep/issues/381):
|
||||||
|
Include license text in all subcrates.
|
||||||
|
* [BUG #418](https://github.com/BurntSushi/ripgrep/issues/418),
|
||||||
|
[BUG #426](https://github.com/BurntSushi/ripgrep/issues/426),
|
||||||
|
[BUG #439](https://github.com/BurntSushi/ripgrep/issues/439):
|
||||||
|
Fix a few bugs with `-h/--help` output.
|
||||||
|
|
||||||
|
|
||||||
|
0.5.0 (2017-03-12)
|
||||||
|
==================
|
||||||
|
This is a new minor version release of ripgrep that includes one minor breaking
|
||||||
|
change, bug fixes and several new features including support for text encodings
|
||||||
|
other than UTF-8.
|
||||||
|
|
||||||
|
A notable accomplishment with respect to Rust is that ripgrep proper now only
|
||||||
|
contains a single `unsafe` use (for accessing the contents of a memory map).
|
||||||
|
|
||||||
|
The **breaking change** is:
|
||||||
|
|
||||||
|
* [FEATURE #380](https://github.com/BurntSushi/ripgrep/issues/380):
|
||||||
|
Line numbers are now hidden by default when ripgrep is printing to a tty
|
||||||
|
**and** the only thing searched is stdin.
|
||||||
|
|
||||||
|
Feature enhancements:
|
||||||
|
|
||||||
|
* Added or improved file type filtering for Ceylon, CSS, Elixir, HTML, log,
|
||||||
|
SASS, SVG, Twig
|
||||||
|
* [FEATURE #1](https://github.com/BurntSushi/ripgrep/issues/1):
|
||||||
|
Add support for additional text encodings, including automatic detection for
|
||||||
|
UTF-16 via BOM sniffing. Explicit text encoding support with the
|
||||||
|
`-E/--encoding` flag was also added for latin-1, GBK, EUC-JP
|
||||||
|
and Shift_JIS, among others. The full list can be found here:
|
||||||
|
https://encoding.spec.whatwg.org/#concept-encoding-get
|
||||||
|
* [FEATURE #129](https://github.com/BurntSushi/ripgrep/issues/129):
|
||||||
|
Add a new `-M/--max-columns` flag that omits lines longer than the given
|
||||||
|
number of bytes. (Disabled by default!)
|
||||||
|
* [FEATURE #369](https://github.com/BurntSushi/ripgrep/issues/369):
|
||||||
|
A new flag, `--max-filesize`, was added for limiting searches to files with
|
||||||
|
a maximum file size.
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* [BUG #52](https://github.com/BurntSushi/ripgrep/issues/52),
|
||||||
|
[BUG #311](https://github.com/BurntSushi/ripgrep/issues/311):
|
||||||
|
Tweak how binary files are detected and handled. (We are slightly less
|
||||||
|
conservative and will no longer use memory without bound.)
|
||||||
|
* [BUG #326](https://github.com/BurntSushi/ripgrep/issues/326):
|
||||||
|
When --files flag is given, we should never attempt to parse positional
|
||||||
|
arguments as regexes.
|
||||||
|
* [BUG #327](https://github.com/BurntSushi/ripgrep/issues/327):
|
||||||
|
Permit the --heading flag to override the --no-heading flag.
|
||||||
|
* [BUG #340](https://github.com/BurntSushi/ripgrep/pull/340):
|
||||||
|
Clarify that the `-u/--unrestricted` flags are aliases.
|
||||||
|
* [BUG #343](https://github.com/BurntSushi/ripgrep/pull/343):
|
||||||
|
Global git ignore config should use `$HOME/.config/git/ignore` and not
|
||||||
|
`$HOME/git/ignore`.
|
||||||
|
* [BUG #345](https://github.com/BurntSushi/ripgrep/pull/345):
|
||||||
|
Clarify docs for `-g/--glob` flag.
|
||||||
|
* [BUG #381](https://github.com/BurntSushi/ripgrep/issues/381):
|
||||||
|
Add license files to each sub-crate.
|
||||||
|
* [BUG #383](https://github.com/BurntSushi/ripgrep/issues/383):
|
||||||
|
Use latest version of clap (for argv parsing).
|
||||||
|
* [BUG #392](https://github.com/BurntSushi/ripgrep/issues/391):
|
||||||
|
Fix translation of set globs (e.g., `{foo,bar,quux}`) to regexes.
|
||||||
|
* [BUG #401](https://github.com/BurntSushi/ripgrep/pull/401):
|
||||||
|
Add PowerShell completion file to Windows release.
|
||||||
|
* [BUG #405](https://github.com/BurntSushi/ripgrep/issues/405):
|
||||||
|
Fix bug when excluding absolute paths with the `-g/--glob` flag.
|
||||||
|
|
||||||
|
|
||||||
0.4.0
|
0.4.0
|
||||||
=====
|
=====
|
||||||
This is a new minor version release of ripgrep that includes a couple very
|
This is a new minor version release of ripgrep that includes a couple very
|
||||||
|
38
Cargo.lock
generated
38
Cargo.lock
generated
@@ -1,15 +1,15 @@
|
|||||||
[root]
|
[root]
|
||||||
name = "ripgrep"
|
name = "ripgrep"
|
||||||
version = "0.4.0"
|
version = "0.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bytecount 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytecount 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clap 2.21.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clap 2.23.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"encoding_rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"encoding_rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"grep 0.1.6",
|
"grep 0.1.6",
|
||||||
"ignore 0.1.8",
|
"ignore 0.1.9",
|
||||||
"lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -17,12 +17,12 @@ dependencies = [
|
|||||||
"num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"termcolor 0.3.1",
|
"termcolor 0.3.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.6.2"
|
version = "0.6.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -45,7 +45,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "0.8.0"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -63,12 +63,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "2.21.1"
|
version = "2.23.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bitflags 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -116,7 +116,7 @@ dependencies = [
|
|||||||
name = "globset"
|
name = "globset"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -135,11 +135,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ignore"
|
name = "ignore"
|
||||||
version = "0.1.8"
|
version = "0.1.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"globset 0.1.4",
|
"globset 0.1.4",
|
||||||
"lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -158,7 +158,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "0.2.4"
|
version = "0.2.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -203,7 +203,7 @@ name = "regex"
|
|||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"simd 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"simd 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -247,7 +247,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wincolor 0.1.3",
|
"wincolor 0.1.3",
|
||||||
]
|
]
|
||||||
@@ -332,20 +332,20 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
"checksum aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0638fd549427caa90c499814196d1b9e3725eb4d15d7339d6de073a680ed0ca2"
|
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
|
||||||
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
|
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
|
||||||
"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
|
"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
|
||||||
"checksum bitflags 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e1ab483fc81a8143faa7203c4a3c02888ebd1a782e37e41fa34753ba9a162"
|
"checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
|
||||||
"checksum bytecount 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1e8f09fbc8c6726a4b616dcfbd4f54491068d6bb1b93ac03c78ac18ff9a5924a"
|
"checksum bytecount 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1e8f09fbc8c6726a4b616dcfbd4f54491068d6bb1b93ac03c78ac18ff9a5924a"
|
||||||
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
||||||
"checksum clap 2.21.1 (registry+https://github.com/rust-lang/crates.io-index)" = "74a80f603221c9cd9aa27a28f52af452850051598537bb6b359c38a7d61e5cda"
|
"checksum clap 2.23.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d480c39a2e5f9b3a3798c661613e1b0e7a7ae71e005102d4aa910fc3289df484"
|
||||||
"checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97"
|
"checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97"
|
||||||
"checksum encoding_rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a1cca0a26f904955d80d70b9bff1019e4f4cbc06f2fcbccf8bd3d889cc1c9b7"
|
"checksum encoding_rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a1cca0a26f904955d80d70b9bff1019e4f4cbc06f2fcbccf8bd3d889cc1c9b7"
|
||||||
"checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83"
|
"checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83"
|
||||||
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
|
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
|
||||||
"checksum fs2 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34edaee07555859dc13ca387e6ae05686bb4d0364c95d649b6dab959511f4baf"
|
"checksum fs2 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34edaee07555859dc13ca387e6ae05686bb4d0364c95d649b6dab959511f4baf"
|
||||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||||
"checksum lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7291b1dd97d331f752620b02dfdbc231df7fc01bf282a00769e1cdb963c460dc"
|
"checksum lazy_static 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4732c563b9a21a406565c4747daa7b46742f082911ae4753f390dc9ec7ee1a97"
|
||||||
"checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135"
|
"checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135"
|
||||||
"checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad"
|
"checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad"
|
||||||
"checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
|
"checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ripgrep"
|
name = "ripgrep"
|
||||||
version = "0.4.0" #:version
|
version = "0.5.0" #:version
|
||||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||||
description = """
|
description = """
|
||||||
Line oriented search tool using Rust's regex library. Combines the raw
|
Line oriented search tool using Rust's regex library. Combines the raw
|
||||||
@@ -28,11 +28,11 @@ path = "tests/tests.rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
atty = "0.2.2"
|
atty = "0.2.2"
|
||||||
bytecount = "0.1.4"
|
bytecount = "0.1.4"
|
||||||
clap = "2.20.5"
|
clap = "2.23.1"
|
||||||
encoding_rs = "0.5.0"
|
encoding_rs = "0.5.0"
|
||||||
env_logger = { version = "0.4", default-features = false }
|
env_logger = { version = "0.4", default-features = false }
|
||||||
grep = { version = "0.1.5", path = "grep" }
|
grep = { version = "0.1.5", path = "grep" }
|
||||||
ignore = { version = "0.1.7", path = "ignore" }
|
ignore = { version = "0.1.9", path = "ignore" }
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
@@ -44,7 +44,7 @@ same-file = "0.1.1"
|
|||||||
termcolor = { version = "0.3.0", path = "termcolor" }
|
termcolor = { version = "0.3.0", path = "termcolor" }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
clap = "2.18"
|
clap = "2.23.1"
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
58
README.md
58
README.md
@@ -13,6 +13,10 @@ downloads available for
|
|||||||
|
|
||||||
Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org).
|
Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org).
|
||||||
|
|
||||||
|
### CHANGELOG
|
||||||
|
|
||||||
|
Please see the [CHANGELOG](CHANGELOG.md) for a release history.
|
||||||
|
|
||||||
### Screenshot of search results
|
### Screenshot of search results
|
||||||
|
|
||||||
[](http://burntsushi.net/stuff/ripgrep1.png)
|
[](http://burntsushi.net/stuff/ripgrep1.png)
|
||||||
@@ -226,11 +230,10 @@ colorize your output and show line numbers, just like The Silver Searcher.
|
|||||||
Coloring works on Windows too! Colors can be controlled more granularly with
|
Coloring works on Windows too! Colors can be controlled more granularly with
|
||||||
the `--color` flag.
|
the `--color` flag.
|
||||||
|
|
||||||
One last thing before we get started: `ripgrep` assumes UTF-8 *everywhere*. It
|
One last thing before we get started: generally speaking, `ripgrep` assumes the
|
||||||
can still search files that are invalid UTF-8 (like, say, latin-1), but it will
|
input is reading is UTF-8. However, if ripgrep notices a file is encoded as
|
||||||
simply not work on UTF-16 encoded files or other more exotic encodings.
|
UTF-16, then it will know how to search it. For other encodings, you'll need to
|
||||||
[Support for other encodings may
|
explicitly specify them with the `-E/--encoding` flag.
|
||||||
happen.](https://github.com/BurntSushi/ripgrep/issues/1)
|
|
||||||
|
|
||||||
To recursively search the current directory, while respecting all `.gitignore`
|
To recursively search the current directory, while respecting all `.gitignore`
|
||||||
files, ignore hidden files and directories and skip binary files:
|
files, ignore hidden files and directories and skip binary files:
|
||||||
@@ -375,6 +378,51 @@ $ cargo test
|
|||||||
|
|
||||||
from the repository root.
|
from the repository root.
|
||||||
|
|
||||||
|
### Tips
|
||||||
|
|
||||||
|
#### Windows Powershell
|
||||||
|
|
||||||
|
##### Powershell Profile
|
||||||
|
|
||||||
|
To customize powershell on start-up there is a special powershell script that has to be created.
|
||||||
|
In order to find its location run command `Get-Command $profile | Select-Object -ExpandProperty Definition`
|
||||||
|
See [more](https://technet.microsoft.com/en-us/library/bb613488(v=vs.85).aspx) for profile details.
|
||||||
|
|
||||||
|
Any powershell code in this file gets evaluated at the start of console.
|
||||||
|
This way you can have own aliases to be created at start.
|
||||||
|
|
||||||
|
##### Setup function alias
|
||||||
|
|
||||||
|
Often you can find a need to make alias for the favourite utility.
|
||||||
|
|
||||||
|
But powershell function aliases do not behave like your typical linux shell alias.
|
||||||
|
|
||||||
|
You always need to propagate arguments and **Stdin** input.
|
||||||
|
But it cannot be done simply as `function grep() { $input | rg.exe --hidden $args }`
|
||||||
|
|
||||||
|
Use below example as reference to how setup alias in powershell.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
function grep {
|
||||||
|
$count = @($input).Count
|
||||||
|
$input.Reset()
|
||||||
|
|
||||||
|
if ($count) {
|
||||||
|
$input | rg.exe --hidden $args
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rg.exe --hidden $args
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Powershell special variables:
|
||||||
|
* input - is powershell **Stdin** object that allows you to access its content.
|
||||||
|
* args - is array of arguments passed to this function.
|
||||||
|
|
||||||
|
This alias checks whether there is **Stdin** input and propagates only if there is some lines.
|
||||||
|
Otherwise empty `$input` will make powershell to trigger `rg` to search empty **Stdin**
|
||||||
|
|
||||||
### Known issues
|
### Known issues
|
||||||
|
|
||||||
#### I just hit Ctrl+C in the middle of ripgrep's output and now my terminal's foreground color is wrong!
|
#### I just hit Ctrl+C in the middle of ripgrep's output and now my terminal's foreground color is wrong!
|
||||||
|
@@ -40,7 +40,7 @@ before_deploy:
|
|||||||
- cargo build --release
|
- cargo build --release
|
||||||
- mkdir staging
|
- mkdir staging
|
||||||
- copy target\release\rg.exe staging
|
- copy target\release\rg.exe staging
|
||||||
- copy target\release\build\ripgrep-*\out\_rg.ps1 staging
|
- ps: copy target\release\build\ripgrep-*\out\_rg.ps1 staging
|
||||||
- cd staging
|
- cd staging
|
||||||
# release zipfile will look like 'rust-everywhere-v1.2.3-x86_64-pc-windows-msvc'
|
# release zipfile will look like 'rust-everywhere-v1.2.3-x86_64-pc-windows-msvc'
|
||||||
- 7z a ../%PROJECT_NAME%-%APPVEYOR_REPO_TAG_NAME%-%TARGET%.zip *
|
- 7z a ../%PROJECT_NAME%-%APPVEYOR_REPO_TAG_NAME%-%TARGET%.zip *
|
||||||
|
2
build.rs
2
build.rs
@@ -19,7 +19,7 @@ fn main() {
|
|||||||
};
|
};
|
||||||
fs::create_dir_all(&outdir).unwrap();
|
fs::create_dir_all(&outdir).unwrap();
|
||||||
|
|
||||||
let mut app = app::app_short();
|
let mut app = app::app();
|
||||||
app.gen_completions("rg", Shell::Bash, &outdir);
|
app.gen_completions("rg", Shell::Bash, &outdir);
|
||||||
app.gen_completions("rg", Shell::Fish, &outdir);
|
app.gen_completions("rg", Shell::Fish, &outdir);
|
||||||
app.gen_completions("rg", Shell::Zsh, &outdir);
|
app.gen_completions("rg", Shell::Zsh, &outdir);
|
||||||
|
@@ -17,9 +17,6 @@ install_c_toolchain() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
install_rustup() {
|
install_rustup() {
|
||||||
# uninstall the rust toolchain installed by travis, we are going to use rustup
|
|
||||||
sh ~/rust/lib/rustlib/uninstall.sh
|
|
||||||
|
|
||||||
curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain=$TRAVIS_RUST_VERSION
|
curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain=$TRAVIS_RUST_VERSION
|
||||||
|
|
||||||
rustc -V
|
rustc -V
|
||||||
|
17
doc/rg.1
17
doc/rg.1
@@ -181,7 +181,7 @@ Styles are limited to nobold, bold, nointense or intense.
|
|||||||
.RS
|
.RS
|
||||||
.PP
|
.PP
|
||||||
The format of the flag is {type}:{attribute}:{value}.
|
The format of the flag is {type}:{attribute}:{value}.
|
||||||
{type} should be one of path, line or match.
|
{type} should be one of path, line, column or match.
|
||||||
{attribute} can be fg, bg or style.
|
{attribute} can be fg, bg or style.
|
||||||
Value is either a color (for fg and bg) or a text style.
|
Value is either a color (for fg and bg) or a text style.
|
||||||
A special format, {type}:none, will clear all color settings for {type}.
|
A special format, {type}:none, will clear all color settings for {type}.
|
||||||
@@ -299,6 +299,13 @@ Follow symlinks.
|
|||||||
.RS
|
.RS
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.TP
|
||||||
|
.B \-M, \-\-max\-columns \f[I]NUM\f[]
|
||||||
|
Don\[aq]t print lines longer than this limit in bytes.
|
||||||
|
Longer lines are omitted, and only the number of matches in that line is
|
||||||
|
printed.
|
||||||
|
.RS
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
.B \-m, \-\-max\-count \f[I]NUM\f[]
|
.B \-m, \-\-max\-count \f[I]NUM\f[]
|
||||||
Limit the number of matching lines per file searched to NUM.
|
Limit the number of matching lines per file searched to NUM.
|
||||||
.RS
|
.RS
|
||||||
@@ -355,7 +362,7 @@ Note that .ignore files will continue to be respected.
|
|||||||
.RS
|
.RS
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.TP
|
||||||
.B \-\-null
|
.B \-0, \-\-null
|
||||||
Whenever a file name is printed, follow it with a NUL byte.
|
Whenever a file name is printed, follow it with a NUL byte.
|
||||||
This includes printing filenames before matches, and when printing a
|
This includes printing filenames before matches, and when printing a
|
||||||
list of matching files such as with \-\-count, \-\-files\-with\-matches
|
list of matching files such as with \-\-count, \-\-files\-with\-matches
|
||||||
@@ -363,6 +370,12 @@ and \-\-files.
|
|||||||
.RS
|
.RS
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.TP
|
||||||
|
.B \-o, \-\-only\-matching
|
||||||
|
Print only the matched (non\-empty) parts of a matching line, with each
|
||||||
|
such part on a separate output line.
|
||||||
|
.RS
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
.B \-\-path\-separator \f[I]SEPARATOR\f[]
|
.B \-\-path\-separator \f[I]SEPARATOR\f[]
|
||||||
The path separator to use when printing file paths.
|
The path separator to use when printing file paths.
|
||||||
This defaults to your platform\[aq]s path separator, which is / on Unix
|
This defaults to your platform\[aq]s path separator, which is / on Unix
|
||||||
|
12
doc/rg.1.md
12
doc/rg.1.md
@@ -123,9 +123,9 @@ Project home page: https://github.com/BurntSushi/ripgrep
|
|||||||
black. Styles are limited to nobold, bold, nointense or intense.
|
black. Styles are limited to nobold, bold, nointense or intense.
|
||||||
|
|
||||||
The format of the flag is {type}:{attribute}:{value}. {type} should be one
|
The format of the flag is {type}:{attribute}:{value}. {type} should be one
|
||||||
of path, line or match. {attribute} can be fg, bg or style. Value is either
|
of path, line, column or match. {attribute} can be fg, bg or style. Value
|
||||||
a color (for fg and bg) or a text style. A special format, {type}:none,
|
is either a color (for fg and bg) or a text style. A special format,
|
||||||
will clear all color settings for {type}.
|
{type}:none, will clear all color settings for {type}.
|
||||||
|
|
||||||
For example, the following command will change the match color to magenta
|
For example, the following command will change the match color to magenta
|
||||||
and the background color for line numbers to yellow:
|
and the background color for line numbers to yellow:
|
||||||
@@ -243,12 +243,16 @@ Project home page: https://github.com/BurntSushi/ripgrep
|
|||||||
: Don't respect version control ignore files (e.g., .gitignore).
|
: Don't respect version control ignore files (e.g., .gitignore).
|
||||||
Note that .ignore files will continue to be respected.
|
Note that .ignore files will continue to be respected.
|
||||||
|
|
||||||
--null
|
-0, --null
|
||||||
: Whenever a file name is printed, follow it with a NUL byte.
|
: Whenever a file name is printed, follow it with a NUL byte.
|
||||||
This includes printing filenames before matches, and when printing
|
This includes printing filenames before matches, and when printing
|
||||||
a list of matching files such as with --count, --files-with-matches
|
a list of matching files such as with --count, --files-with-matches
|
||||||
and --files.
|
and --files.
|
||||||
|
|
||||||
|
-o, --only-matching
|
||||||
|
: Print only the matched (non-empty) parts of a matching line, with each such
|
||||||
|
part on a separate output line.
|
||||||
|
|
||||||
--path-separator *SEPARATOR*
|
--path-separator *SEPARATOR*
|
||||||
: The path separator to use when printing file paths. This defaults to your
|
: The path separator to use when printing file paths. This defaults to your
|
||||||
platform's path separator, which is / on Unix and \\ on Windows. This flag is
|
platform's path separator, which is / on Unix and \\ on Windows. This flag is
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ignore"
|
name = "ignore"
|
||||||
version = "0.1.8" #:version
|
version = "0.1.9" #:version
|
||||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||||
description = """
|
description = """
|
||||||
A fast library for efficiently matching ignore files such as `.gitignore`
|
A fast library for efficiently matching ignore files such as `.gitignore`
|
||||||
|
@@ -191,6 +191,7 @@ const DEFAULT_TYPES: &'static [(&'static str, &'static [&'static str])] = &[
|
|||||||
("twig", &["*.twig"]),
|
("twig", &["*.twig"]),
|
||||||
("vala", &["*.vala"]),
|
("vala", &["*.vala"]),
|
||||||
("vb", &["*.vb"]),
|
("vb", &["*.vb"]),
|
||||||
|
("vim", &["*.vim"]),
|
||||||
("vimscript", &["*.vim"]),
|
("vimscript", &["*.vim"]),
|
||||||
("wiki", &["*.mediawiki", "*.wiki"]),
|
("wiki", &["*.mediawiki", "*.wiki"]),
|
||||||
("xml", &["*.xml"]),
|
("xml", &["*.xml"]),
|
||||||
|
@@ -1,16 +1,16 @@
|
|||||||
class RipgrepBin < Formula
|
class RipgrepBin < Formula
|
||||||
version '0.4.0'
|
version '0.5.0'
|
||||||
desc "Search tool like grep and The Silver Searcher."
|
desc "Search tool like grep and The Silver Searcher."
|
||||||
homepage "https://github.com/BurntSushi/ripgrep"
|
homepage "https://github.com/BurntSushi/ripgrep"
|
||||||
url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-apple-darwin.tar.gz"
|
url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-apple-darwin.tar.gz"
|
||||||
sha256 "6ac71251909227f8ef7eda27d3080c954843f3665b81e455362c90b2a9c4734a"
|
sha256 "5bfa8872c4f2a5d010ddec1c213d518056e62d4dd3b3f23a0ef099b85343dbdd"
|
||||||
|
|
||||||
conflicts_with "ripgrep"
|
conflicts_with "ripgrep"
|
||||||
|
|
||||||
def install
|
def install
|
||||||
bin.install "rg"
|
bin.install "rg"
|
||||||
man1.install "rg.1"
|
man1.install "rg.1"
|
||||||
|
|
||||||
bash_completion.install "complete/rg.bash-completion"
|
bash_completion.install "complete/rg.bash-completion"
|
||||||
fish_completion.install "complete/rg.fish"
|
fish_completion.install "complete/rg.fish"
|
||||||
zsh_completion.install "complete/_rg"
|
zsh_completion.install "complete/_rg"
|
||||||
|
55
src/app.rs
55
src/app.rs
@@ -32,16 +32,6 @@ ARGS:
|
|||||||
OPTIONS:
|
OPTIONS:
|
||||||
{unified}";
|
{unified}";
|
||||||
|
|
||||||
/// Build a clap application with short help strings.
|
|
||||||
pub fn app_short() -> App<'static, 'static> {
|
|
||||||
app(false, |k| USAGES[k].short)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Build a clap application with long help strings.
|
|
||||||
pub fn app_long() -> App<'static, 'static> {
|
|
||||||
app(true, |k| USAGES[k].long)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Build a clap application parameterized by usage strings.
|
/// Build a clap application parameterized by usage strings.
|
||||||
///
|
///
|
||||||
/// The function given should take a clap argument name and return a help
|
/// The function given should take a clap argument name and return a help
|
||||||
@@ -49,10 +39,9 @@ pub fn app_long() -> App<'static, 'static> {
|
|||||||
///
|
///
|
||||||
/// This is an intentionally stand-alone module so that it can be used easily
|
/// This is an intentionally stand-alone module so that it can be used easily
|
||||||
/// in a `build.rs` script to build shell completion files.
|
/// in a `build.rs` script to build shell completion files.
|
||||||
fn app<F>(next_line_help: bool, doc: F) -> App<'static, 'static>
|
pub fn app() -> App<'static, 'static> {
|
||||||
where F: Fn(&'static str) -> &'static str {
|
|
||||||
let arg = |name| {
|
let arg = |name| {
|
||||||
Arg::with_name(name).help(doc(name)).next_line_help(next_line_help)
|
Arg::with_name(name).help(USAGES[name].short).long_help(USAGES[name].long)
|
||||||
};
|
};
|
||||||
let flag = |name| arg(name).long(name);
|
let flag = |name| arg(name).long(name);
|
||||||
|
|
||||||
@@ -64,16 +53,12 @@ fn app<F>(next_line_help: bool, doc: F) -> App<'static, 'static>
|
|||||||
.setting(AppSettings::UnifiedHelpMessage)
|
.setting(AppSettings::UnifiedHelpMessage)
|
||||||
.usage(USAGE)
|
.usage(USAGE)
|
||||||
.template(TEMPLATE)
|
.template(TEMPLATE)
|
||||||
// Handle help/version manually to make their output formatting
|
.help_message("Prints help information. Use --help for more details.")
|
||||||
// consistent with short/long views.
|
|
||||||
.arg(arg("help-short").short("h"))
|
|
||||||
.arg(flag("help"))
|
|
||||||
.arg(flag("version").short("V"))
|
|
||||||
// First, set up primary positional/flag arguments.
|
// First, set up primary positional/flag arguments.
|
||||||
.arg(arg("pattern")
|
.arg(arg("pattern")
|
||||||
.required_unless_one(&[
|
.required_unless_one(&[
|
||||||
"file", "files", "help-short", "help", "regexp", "type-list",
|
"file", "files", "help-short", "help", "regexp", "type-list",
|
||||||
"version",
|
"ripgrep-version",
|
||||||
]))
|
]))
|
||||||
.arg(arg("path").multiple(true))
|
.arg(arg("path").multiple(true))
|
||||||
.arg(flag("regexp").short("e")
|
.arg(flag("regexp").short("e")
|
||||||
@@ -158,7 +143,8 @@ fn app<F>(next_line_help: bool, doc: F) -> App<'static, 'static>
|
|||||||
.arg(flag("no-ignore"))
|
.arg(flag("no-ignore"))
|
||||||
.arg(flag("no-ignore-parent"))
|
.arg(flag("no-ignore-parent"))
|
||||||
.arg(flag("no-ignore-vcs"))
|
.arg(flag("no-ignore-vcs"))
|
||||||
.arg(flag("null"))
|
.arg(flag("null").short("0"))
|
||||||
|
.arg(flag("only-matching").short("o").conflicts_with("replace"))
|
||||||
.arg(flag("path-separator").value_name("SEPARATOR").takes_value(true))
|
.arg(flag("path-separator").value_name("SEPARATOR").takes_value(true))
|
||||||
.arg(flag("pretty").short("p"))
|
.arg(flag("pretty").short("p"))
|
||||||
.arg(flag("replace").short("r").value_name("ARG").takes_value(true))
|
.arg(flag("replace").short("r").value_name("ARG").takes_value(true))
|
||||||
@@ -206,7 +192,7 @@ lazy_static! {
|
|||||||
doc!(h, "help",
|
doc!(h, "help",
|
||||||
"Show verbose help output.",
|
"Show verbose help output.",
|
||||||
"When given, more details about flags are provided.");
|
"When given, more details about flags are provided.");
|
||||||
doc!(h, "version",
|
doc!(h, "ripgrep-version",
|
||||||
"Prints version information.");
|
"Prints version information.");
|
||||||
|
|
||||||
doc!(h, "pattern",
|
doc!(h, "pattern",
|
||||||
@@ -249,12 +235,12 @@ lazy_static! {
|
|||||||
red, blue, green, cyan, magenta, yellow, white and black. \
|
red, blue, green, cyan, magenta, yellow, white and black. \
|
||||||
Styles are limited to nobold, bold, nointense or intense.\n\n\
|
Styles are limited to nobold, bold, nointense or intense.\n\n\
|
||||||
The format of the flag is {type}:{attribute}:{value}. {type} \
|
The format of the flag is {type}:{attribute}:{value}. {type} \
|
||||||
should be one of path, line or match. {attribute} can be fg, bg \
|
should be one of path, line, column or match. {attribute} can \
|
||||||
or style. {value} is either a color (for fg and bg) or a text \
|
be fg, bg or style. {value} is either a color (for fg and bg) \
|
||||||
style. A special format, {type}:none, will clear all color \
|
or a text style. A special format, {type}:none, will clear all \
|
||||||
settings for {type}.\n\nFor example, the following command will \
|
color settings for {type}.\n\nFor example, the following \
|
||||||
change the match color to magenta and the background color for \
|
command will change the match color to magenta and the \
|
||||||
line numbers to yellow:\n\n\
|
background color for line numbers to yellow:\n\n\
|
||||||
rg --colors 'match:fg:magenta' --colors 'line:bg:yellow' foo.");
|
rg --colors 'match:fg:magenta' --colors 'line:bg:yellow' foo.");
|
||||||
doc!(h, "encoding",
|
doc!(h, "encoding",
|
||||||
"Specify the text encoding of files to search.",
|
"Specify the text encoding of files to search.",
|
||||||
@@ -388,10 +374,11 @@ lazy_static! {
|
|||||||
"Limit the number of matching lines per file searched to NUM.");
|
"Limit the number of matching lines per file searched to NUM.");
|
||||||
doc!(h, "max-filesize",
|
doc!(h, "max-filesize",
|
||||||
"Ignore files larger than NUM in size.",
|
"Ignore files larger than NUM in size.",
|
||||||
"Ignore files larger than NUM in size. Does not ignore directories. \
|
"Ignore files larger than NUM in size. Does not ignore \
|
||||||
|
directories. \
|
||||||
\n\nThe input format accepts suffixes of K, M or G which \
|
\n\nThe input format accepts suffixes of K, M or G which \
|
||||||
correspond to kilobytes, megabytes and gigabytes. If no suffix is \
|
correspond to kilobytes, megabytes and gigabytes. If no suffix \
|
||||||
provided the input is treated as bytes. \
|
is provided the input is treated as bytes. \
|
||||||
\n\nExample: --max-filesize 50K or --max-filesize 80M");
|
\n\nExample: --max-filesize 50K or --max-filesize 80M");
|
||||||
doc!(h, "maxdepth",
|
doc!(h, "maxdepth",
|
||||||
"Descend at most NUM directories.",
|
"Descend at most NUM directories.",
|
||||||
@@ -435,6 +422,10 @@ lazy_static! {
|
|||||||
printing a list of matching files such as with --count, \
|
printing a list of matching files such as with --count, \
|
||||||
--files-with-matches and --files. This option is useful for use \
|
--files-with-matches and --files. This option is useful for use \
|
||||||
with xargs.");
|
with xargs.");
|
||||||
|
doc!(h, "only-matching",
|
||||||
|
"Print only matched parts of a line.",
|
||||||
|
"Print only the matched (non-empty) parts of a matching line, \
|
||||||
|
with each such part on a separate output line.");
|
||||||
doc!(h, "path-separator",
|
doc!(h, "path-separator",
|
||||||
"Path separator to use when printing file paths.",
|
"Path separator to use when printing file paths.",
|
||||||
"The path separator to use when printing file paths. This \
|
"The path separator to use when printing file paths. This \
|
||||||
@@ -496,8 +487,8 @@ lazy_static! {
|
|||||||
permits specifying one or more other type names (separated by a \
|
permits specifying one or more other type names (separated by a \
|
||||||
comma) that have been defined and its rules will automatically \
|
comma) that have been defined and its rules will automatically \
|
||||||
be imported into the type specified. For example, to create a \
|
be imported into the type specified. For example, to create a \
|
||||||
type called src that matches C++, Python and Markdown files, one \
|
type called src that matches C++, Python and Markdown files, \
|
||||||
can use:\n\n\
|
one can use:\n\n\
|
||||||
--type-add 'src:include:cpp,py,md'\n\n\
|
--type-add 'src:include:cpp,py,md'\n\n\
|
||||||
Additional glob rules can still be added to the src type by \
|
Additional glob rules can still be added to the src type by \
|
||||||
using the --type-add flag again:\n\n\
|
using the --type-add flag again:\n\n\
|
||||||
|
22
src/args.rs
22
src/args.rs
@@ -5,7 +5,6 @@ use std::fs;
|
|||||||
use std::io::{self, BufRead};
|
use std::io::{self, BufRead};
|
||||||
use std::ops;
|
use std::ops;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
@@ -66,6 +65,7 @@ pub struct Args {
|
|||||||
no_ignore_vcs: bool,
|
no_ignore_vcs: bool,
|
||||||
no_messages: bool,
|
no_messages: bool,
|
||||||
null: bool,
|
null: bool,
|
||||||
|
only_matching: bool,
|
||||||
path_separator: Option<u8>,
|
path_separator: Option<u8>,
|
||||||
quiet: bool,
|
quiet: bool,
|
||||||
quiet_matched: QuietMatched,
|
quiet_matched: QuietMatched,
|
||||||
@@ -88,21 +88,7 @@ impl Args {
|
|||||||
///
|
///
|
||||||
/// Also, initialize a global logger.
|
/// Also, initialize a global logger.
|
||||||
pub fn parse() -> Result<Args> {
|
pub fn parse() -> Result<Args> {
|
||||||
let matches = app::app_short().get_matches();
|
let matches = app::app().get_matches();
|
||||||
if matches.is_present("help-short") {
|
|
||||||
let _ = ::app::app_short().print_help();
|
|
||||||
println!("");
|
|
||||||
process::exit(0);
|
|
||||||
}
|
|
||||||
if matches.is_present("help") {
|
|
||||||
let _ = ::app::app_long().print_help();
|
|
||||||
println!("");
|
|
||||||
process::exit(0);
|
|
||||||
}
|
|
||||||
if matches.is_present("version") {
|
|
||||||
println!("ripgrep {}", crate_version!());
|
|
||||||
process::exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut logb = env_logger::LogBuilder::new();
|
let mut logb = env_logger::LogBuilder::new();
|
||||||
if matches.is_present("debug") {
|
if matches.is_present("debug") {
|
||||||
@@ -156,6 +142,7 @@ impl Args {
|
|||||||
.heading(self.heading)
|
.heading(self.heading)
|
||||||
.line_per_match(self.line_per_match)
|
.line_per_match(self.line_per_match)
|
||||||
.null(self.null)
|
.null(self.null)
|
||||||
|
.only_matching(self.only_matching)
|
||||||
.path_separator(self.path_separator)
|
.path_separator(self.path_separator)
|
||||||
.with_filename(self.with_filename)
|
.with_filename(self.with_filename)
|
||||||
.max_columns(self.max_columns);
|
.max_columns(self.max_columns);
|
||||||
@@ -360,6 +347,7 @@ impl<'a> ArgMatches<'a> {
|
|||||||
no_ignore_vcs: self.no_ignore_vcs(),
|
no_ignore_vcs: self.no_ignore_vcs(),
|
||||||
no_messages: self.is_present("no-messages"),
|
no_messages: self.is_present("no-messages"),
|
||||||
null: self.is_present("null"),
|
null: self.is_present("null"),
|
||||||
|
only_matching: self.is_present("only-matching"),
|
||||||
path_separator: try!(self.path_separator()),
|
path_separator: try!(self.path_separator()),
|
||||||
quiet: quiet,
|
quiet: quiet,
|
||||||
quiet_matched: QuietMatched::new(quiet),
|
quiet_matched: QuietMatched::new(quiet),
|
||||||
@@ -832,7 +820,7 @@ impl<'a> ArgMatches<'a> {
|
|||||||
let caps = try!(re.captures(&max_filesize)
|
let caps = try!(re.captures(&max_filesize)
|
||||||
.ok_or("invalid format for max-filesize argument"));
|
.ok_or("invalid format for max-filesize argument"));
|
||||||
|
|
||||||
let value = try!(caps[1].parse::<u64>().map_err(|err| err.to_string()));
|
let value = try!(caps[1].parse::<u64>().map_err(|err|err.to_string()));
|
||||||
let suffix = caps.get(2).map(|x| x.as_str());
|
let suffix = caps.get(2).map(|x| x.as_str());
|
||||||
|
|
||||||
match suffix {
|
match suffix {
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::io::{self, Read};
|
use std::io::{self, Read};
|
||||||
|
|
||||||
@@ -290,10 +288,6 @@ mod tests {
|
|||||||
|
|
||||||
use super::{Bom, BomPeeker, DecodeReader};
|
use super::{Bom, BomPeeker, DecodeReader};
|
||||||
|
|
||||||
fn utf8(bytes: &[u8]) -> &str {
|
|
||||||
::std::str::from_utf8(bytes).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_to_string<R: Read>(mut rdr: R) -> String {
|
fn read_to_string<R: Read>(mut rdr: R) -> String {
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
rdr.read_to_string(&mut s).unwrap();
|
rdr.read_to_string(&mut s).unwrap();
|
||||||
@@ -453,7 +447,8 @@ mod tests {
|
|||||||
test_trans_simple!(trans_simple_utf16be, "utf-16be", b"\x04\x16", "Ж");
|
test_trans_simple!(trans_simple_utf16be, "utf-16be", b"\x04\x16", "Ж");
|
||||||
test_trans_simple!(trans_simple_chinese, "chinese", b"\xA7\xA8", "Ж");
|
test_trans_simple!(trans_simple_chinese, "chinese", b"\xA7\xA8", "Ж");
|
||||||
test_trans_simple!(trans_simple_korean, "korean", b"\xAC\xA8", "Ж");
|
test_trans_simple!(trans_simple_korean, "korean", b"\xAC\xA8", "Ж");
|
||||||
test_trans_simple!(trans_simple_big5_hkscs, "big5-hkscs", b"\xC7\xFA", "Ж");
|
test_trans_simple!(
|
||||||
|
trans_simple_big5_hkscs, "big5-hkscs", b"\xC7\xFA", "Ж");
|
||||||
test_trans_simple!(trans_simple_gbk, "gbk", b"\xA7\xA8", "Ж");
|
test_trans_simple!(trans_simple_gbk, "gbk", b"\xA7\xA8", "Ж");
|
||||||
test_trans_simple!(trans_simple_sjis, "sjis", b"\x84\x47", "Ж");
|
test_trans_simple!(trans_simple_sjis, "sjis", b"\x84\x47", "Ж");
|
||||||
test_trans_simple!(trans_simple_eucjp, "euc-jp", b"\xA7\xA8", "Ж");
|
test_trans_simple!(trans_simple_eucjp, "euc-jp", b"\xA7\xA8", "Ж");
|
||||||
|
183
src/printer.rs
183
src/printer.rs
@@ -58,6 +58,8 @@ pub struct Printer<W> {
|
|||||||
/// Whether to print NUL bytes after a file path instead of new lines
|
/// Whether to print NUL bytes after a file path instead of new lines
|
||||||
/// or `:`.
|
/// or `:`.
|
||||||
null: bool,
|
null: bool,
|
||||||
|
/// Print only the matched (non-empty) parts of a matching line
|
||||||
|
only_matching: bool,
|
||||||
/// A string to use as a replacement of each match in a matching line.
|
/// A string to use as a replacement of each match in a matching line.
|
||||||
replace: Option<Vec<u8>>,
|
replace: Option<Vec<u8>>,
|
||||||
/// Whether to prefix each match with the corresponding file name.
|
/// Whether to prefix each match with the corresponding file name.
|
||||||
@@ -83,6 +85,7 @@ impl<W: WriteColor> Printer<W> {
|
|||||||
heading: false,
|
heading: false,
|
||||||
line_per_match: false,
|
line_per_match: false,
|
||||||
null: false,
|
null: false,
|
||||||
|
only_matching: false,
|
||||||
replace: None,
|
replace: None,
|
||||||
with_filename: false,
|
with_filename: false,
|
||||||
colors: ColorSpecs::default(),
|
colors: ColorSpecs::default(),
|
||||||
@@ -144,6 +147,12 @@ impl<W: WriteColor> Printer<W> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Print only the matched (non-empty) parts of a matching line
|
||||||
|
pub fn only_matching(mut self, yes: bool) -> Printer<W> {
|
||||||
|
self.only_matching = yes;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// A separator to use when printing file paths. When empty, use the
|
/// A separator to use when printing file paths. When empty, use the
|
||||||
/// default separator for the current platform. (/ on Unix, \ on Windows.)
|
/// default separator for the current platform. (/ on Unix, \ on Windows.)
|
||||||
pub fn path_separator(mut self, sep: Option<u8>) -> Printer<W> {
|
pub fn path_separator(mut self, sep: Option<u8>) -> Printer<W> {
|
||||||
@@ -153,9 +162,6 @@ impl<W: WriteColor> Printer<W> {
|
|||||||
|
|
||||||
/// Replace every match in each matching line with the replacement string
|
/// Replace every match in each matching line with the replacement string
|
||||||
/// given.
|
/// given.
|
||||||
///
|
|
||||||
/// The replacement string syntax is documented here:
|
|
||||||
/// https://doc.rust-lang.org/regex/regex/bytes/struct.Captures.html#method.expand
|
|
||||||
pub fn replace(mut self, replacement: Vec<u8>) -> Printer<W> {
|
pub fn replace(mut self, replacement: Vec<u8>) -> Printer<W> {
|
||||||
self.replace = Some(replacement);
|
self.replace = Some(replacement);
|
||||||
self
|
self
|
||||||
@@ -204,22 +210,14 @@ impl<W: WriteColor> Printer<W> {
|
|||||||
pub fn path<P: AsRef<Path>>(&mut self, path: P) {
|
pub fn path<P: AsRef<Path>>(&mut self, path: P) {
|
||||||
let path = strip_prefix("./", path.as_ref()).unwrap_or(path.as_ref());
|
let path = strip_prefix("./", path.as_ref()).unwrap_or(path.as_ref());
|
||||||
self.write_path(path);
|
self.write_path(path);
|
||||||
if self.null {
|
self.write_path_eol();
|
||||||
self.write(b"\x00");
|
|
||||||
} else {
|
|
||||||
self.write_eol();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints the given path and a count of the number of matches found.
|
/// Prints the given path and a count of the number of matches found.
|
||||||
pub fn path_count<P: AsRef<Path>>(&mut self, path: P, count: u64) {
|
pub fn path_count<P: AsRef<Path>>(&mut self, path: P, count: u64) {
|
||||||
if self.with_filename {
|
if self.with_filename {
|
||||||
self.write_path(path);
|
self.write_path(path);
|
||||||
if self.null {
|
self.write_path_sep(b':');
|
||||||
self.write(b"\x00");
|
|
||||||
} else {
|
|
||||||
self.write(b":");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.write(count.to_string().as_bytes());
|
self.write(count.to_string().as_bytes());
|
||||||
self.write_eol();
|
self.write_eol();
|
||||||
@@ -227,13 +225,11 @@ impl<W: WriteColor> Printer<W> {
|
|||||||
|
|
||||||
/// Prints the context separator.
|
/// Prints the context separator.
|
||||||
pub fn context_separate(&mut self) {
|
pub fn context_separate(&mut self) {
|
||||||
// N.B. We can't use `write` here because of borrowing restrictions.
|
|
||||||
if self.context_separator.is_empty() {
|
if self.context_separator.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.has_printed = true;
|
|
||||||
let _ = self.wtr.write_all(&self.context_separator);
|
let _ = self.wtr.write_all(&self.context_separator);
|
||||||
let _ = self.wtr.write_all(&[self.eol]);
|
self.write_eol();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn matched<P: AsRef<Path>>(
|
pub fn matched<P: AsRef<Path>>(
|
||||||
@@ -245,7 +241,7 @@ impl<W: WriteColor> Printer<W> {
|
|||||||
end: usize,
|
end: usize,
|
||||||
line_number: Option<u64>,
|
line_number: Option<u64>,
|
||||||
) {
|
) {
|
||||||
if !self.line_per_match {
|
if !self.line_per_match && !self.only_matching {
|
||||||
let column =
|
let column =
|
||||||
if self.column {
|
if self.column {
|
||||||
Some(re.find(&buf[start..end])
|
Some(re.find(&buf[start..end])
|
||||||
@@ -280,16 +276,17 @@ impl<W: WriteColor> Printer<W> {
|
|||||||
) {
|
) {
|
||||||
if self.heading && self.with_filename && !self.has_printed {
|
if self.heading && self.with_filename && !self.has_printed {
|
||||||
self.write_file_sep();
|
self.write_file_sep();
|
||||||
self.write_heading(path.as_ref());
|
self.write_path(path);
|
||||||
|
self.write_path_eol();
|
||||||
} else if !self.heading && self.with_filename {
|
} else if !self.heading && self.with_filename {
|
||||||
self.write_non_heading_path(path.as_ref());
|
self.write_path(path);
|
||||||
|
self.write_path_sep(b':');
|
||||||
}
|
}
|
||||||
if let Some(line_number) = line_number {
|
if let Some(line_number) = line_number {
|
||||||
self.line_number(line_number, b':');
|
self.line_number(line_number, b':');
|
||||||
}
|
}
|
||||||
if let Some(c) = column {
|
if let Some(c) = column {
|
||||||
self.write((c + 1).to_string().as_bytes());
|
self.column_number(c + 1, b':');
|
||||||
self.write(b":");
|
|
||||||
}
|
}
|
||||||
if self.replace.is_some() {
|
if self.replace.is_some() {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
@@ -299,11 +296,9 @@ impl<W: WriteColor> Printer<W> {
|
|||||||
re.replace_all(&buf[start..end], replacer)
|
re.replace_all(&buf[start..end], replacer)
|
||||||
};
|
};
|
||||||
if self.max_columns.map_or(false, |m| line.len() > m) {
|
if self.max_columns.map_or(false, |m| line.len() > m) {
|
||||||
let _ = self.wtr.set_color(self.colors.matched());
|
|
||||||
let msg = format!(
|
let msg = format!(
|
||||||
"[Omitted long line with {} replacements]", count);
|
"[Omitted long line with {} replacements]", count);
|
||||||
self.write(msg.as_bytes());
|
self.write_colored(msg.as_bytes(), |colors| colors.matched());
|
||||||
let _ = self.wtr.reset();
|
|
||||||
self.write_eol();
|
self.write_eol();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -312,7 +307,13 @@ impl<W: WriteColor> Printer<W> {
|
|||||||
self.write_eol();
|
self.write_eol();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.write_matched_line(re, &buf[start..end]);
|
let line_buf = if self.only_matching {
|
||||||
|
let m = re.find(&buf[start..end]).unwrap();
|
||||||
|
&buf[start + m.start()..start + m.end()]
|
||||||
|
} else {
|
||||||
|
&buf[start..end]
|
||||||
|
};
|
||||||
|
self.write_matched_line(re, line_buf);
|
||||||
// write_matched_line guarantees to write a newline.
|
// write_matched_line guarantees to write a newline.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -320,10 +321,8 @@ impl<W: WriteColor> Printer<W> {
|
|||||||
fn write_matched_line(&mut self, re: &Regex, buf: &[u8]) {
|
fn write_matched_line(&mut self, re: &Regex, buf: &[u8]) {
|
||||||
if self.max_columns.map_or(false, |m| buf.len() > m) {
|
if self.max_columns.map_or(false, |m| buf.len() > m) {
|
||||||
let count = re.find_iter(buf).count();
|
let count = re.find_iter(buf).count();
|
||||||
let _ = self.wtr.set_color(self.colors.matched());
|
|
||||||
let msg = format!("[Omitted long line with {} matches]", count);
|
let msg = format!("[Omitted long line with {} matches]", count);
|
||||||
self.write(msg.as_bytes());
|
self.write_colored(msg.as_bytes(), |colors| colors.matched());
|
||||||
let _ = self.wtr.reset();
|
|
||||||
self.write_eol();
|
self.write_eol();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -333,9 +332,8 @@ impl<W: WriteColor> Printer<W> {
|
|||||||
let mut last_written = 0;
|
let mut last_written = 0;
|
||||||
for m in re.find_iter(buf) {
|
for m in re.find_iter(buf) {
|
||||||
self.write(&buf[last_written..m.start()]);
|
self.write(&buf[last_written..m.start()]);
|
||||||
let _ = self.wtr.set_color(self.colors.matched());
|
self.write_colored(
|
||||||
self.write(&buf[m.start()..m.end()]);
|
&buf[m.start()..m.end()], |colors| colors.matched());
|
||||||
let _ = self.wtr.reset();
|
|
||||||
last_written = m.end();
|
last_written = m.end();
|
||||||
}
|
}
|
||||||
self.write(&buf[last_written..]);
|
self.write(&buf[last_written..]);
|
||||||
@@ -355,14 +353,11 @@ impl<W: WriteColor> Printer<W> {
|
|||||||
) {
|
) {
|
||||||
if self.heading && self.with_filename && !self.has_printed {
|
if self.heading && self.with_filename && !self.has_printed {
|
||||||
self.write_file_sep();
|
self.write_file_sep();
|
||||||
self.write_heading(path.as_ref());
|
self.write_path(path);
|
||||||
|
self.write_path_eol();
|
||||||
} else if !self.heading && self.with_filename {
|
} else if !self.heading && self.with_filename {
|
||||||
self.write_path(path.as_ref());
|
self.write_path(path);
|
||||||
if self.null {
|
self.write_path_sep(b'-');
|
||||||
self.write(b"\x00");
|
|
||||||
} else {
|
|
||||||
self.write(b"-");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if let Some(line_number) = line_number {
|
if let Some(line_number) = line_number {
|
||||||
self.line_number(line_number, b'-');
|
self.line_number(line_number, b'-');
|
||||||
@@ -378,10 +373,19 @@ impl<W: WriteColor> Printer<W> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_heading<P: AsRef<Path>>(&mut self, path: P) {
|
fn separator(&mut self, sep: &[u8]) {
|
||||||
let _ = self.wtr.set_color(self.colors.path());
|
self.write(&sep);
|
||||||
self.write_path(path.as_ref());
|
}
|
||||||
let _ = self.wtr.reset();
|
|
||||||
|
fn write_path_sep(&mut self, sep: u8) {
|
||||||
|
if self.null {
|
||||||
|
self.write(b"\x00");
|
||||||
|
} else {
|
||||||
|
self.separator(&[sep]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_path_eol(&mut self) {
|
||||||
if self.null {
|
if self.null {
|
||||||
self.write(b"\x00");
|
self.write(b"\x00");
|
||||||
} else {
|
} else {
|
||||||
@@ -389,52 +393,43 @@ impl<W: WriteColor> Printer<W> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_non_heading_path<P: AsRef<Path>>(&mut self, path: P) {
|
|
||||||
let _ = self.wtr.set_color(self.colors.path());
|
|
||||||
self.write_path(path.as_ref());
|
|
||||||
let _ = self.wtr.reset();
|
|
||||||
if self.null {
|
|
||||||
self.write(b"\x00");
|
|
||||||
} else {
|
|
||||||
self.write(b":");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn line_number(&mut self, n: u64, sep: u8) {
|
|
||||||
let _ = self.wtr.set_color(self.colors.line());
|
|
||||||
self.write(n.to_string().as_bytes());
|
|
||||||
let _ = self.wtr.reset();
|
|
||||||
self.write(&[sep]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn write_path<P: AsRef<Path>>(&mut self, path: P) {
|
fn write_path<P: AsRef<Path>>(&mut self, path: P) {
|
||||||
use std::os::unix::ffi::OsStrExt;
|
use std::os::unix::ffi::OsStrExt;
|
||||||
|
|
||||||
let path = path.as_ref().as_os_str().as_bytes();
|
let path = path.as_ref().as_os_str().as_bytes();
|
||||||
match self.path_separator {
|
self.write_path_replace_separator(path);
|
||||||
None => self.write(path),
|
|
||||||
Some(sep) => self.write_path_with_sep(path, sep),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
fn write_path<P: AsRef<Path>>(&mut self, path: P) {
|
fn write_path<P: AsRef<Path>>(&mut self, path: P) {
|
||||||
let path = path.as_ref().to_string_lossy();
|
let path = path.as_ref().to_string_lossy();
|
||||||
|
self.write_path_replace_separator(path.as_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_path_replace_separator(&mut self, path: &[u8]) {
|
||||||
match self.path_separator {
|
match self.path_separator {
|
||||||
None => self.write(path.as_bytes()),
|
None => self.write_colored(path, |colors| colors.path()),
|
||||||
Some(sep) => self.write_path_with_sep(path.as_bytes(), sep),
|
Some(sep) => {
|
||||||
|
let transformed_path: Vec<_> = path.iter().map(|&b| {
|
||||||
|
if b == b'/' || (cfg!(windows) && b == b'\\') {
|
||||||
|
sep
|
||||||
|
} else {
|
||||||
|
b
|
||||||
|
}
|
||||||
|
}).collect();
|
||||||
|
self.write_colored(&transformed_path, |colors| colors.path());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_path_with_sep(&mut self, path: &[u8], sep: u8) {
|
fn line_number(&mut self, n: u64, sep: u8) {
|
||||||
let mut path = path.to_vec();
|
self.write_colored(n.to_string().as_bytes(), |colors| colors.line());
|
||||||
for b in &mut path {
|
self.separator(&[sep]);
|
||||||
if *b == b'/' || (cfg!(windows) && *b == b'\\') {
|
}
|
||||||
*b = sep;
|
|
||||||
}
|
fn column_number(&mut self, n: u64, sep: u8) {
|
||||||
}
|
self.write_colored(n.to_string().as_bytes(), |colors| colors.column());
|
||||||
self.write(&path);
|
self.separator(&[sep]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&mut self, buf: &[u8]) {
|
fn write(&mut self, buf: &[u8]) {
|
||||||
@@ -447,6 +442,14 @@ impl<W: WriteColor> Printer<W> {
|
|||||||
self.write(&[eol]);
|
self.write(&[eol]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn write_colored<F>(&mut self, buf: &[u8], get_color: F)
|
||||||
|
where F: Fn(&ColorSpecs) -> &ColorSpec
|
||||||
|
{
|
||||||
|
let _ = self.wtr.set_color( get_color(&self.colors) );
|
||||||
|
self.write(buf);
|
||||||
|
let _ = self.wtr.reset();
|
||||||
|
}
|
||||||
|
|
||||||
fn write_file_sep(&mut self) {
|
fn write_file_sep(&mut self) {
|
||||||
if let Some(ref sep) = self.file_separator {
|
if let Some(ref sep) = self.file_separator {
|
||||||
self.has_printed = true;
|
self.has_printed = true;
|
||||||
@@ -492,7 +495,7 @@ impl fmt::Display for Error {
|
|||||||
match *self {
|
match *self {
|
||||||
Error::UnrecognizedOutType(ref name) => {
|
Error::UnrecognizedOutType(ref name) => {
|
||||||
write!(f, "Unrecognized output type '{}'. Choose from: \
|
write!(f, "Unrecognized output type '{}'. Choose from: \
|
||||||
path, line, match.", name)
|
path, line, column, match.", name)
|
||||||
}
|
}
|
||||||
Error::UnrecognizedSpecType(ref name) => {
|
Error::UnrecognizedSpecType(ref name) => {
|
||||||
write!(f, "Unrecognized spec type '{}'. Choose from: \
|
write!(f, "Unrecognized spec type '{}'. Choose from: \
|
||||||
@@ -503,12 +506,14 @@ impl fmt::Display for Error {
|
|||||||
}
|
}
|
||||||
Error::UnrecognizedStyle(ref name) => {
|
Error::UnrecognizedStyle(ref name) => {
|
||||||
write!(f, "Unrecognized style attribute '{}'. Choose from: \
|
write!(f, "Unrecognized style attribute '{}'. Choose from: \
|
||||||
nobold, bold.", name)
|
nobold, bold, nointense, intense.", name)
|
||||||
}
|
}
|
||||||
Error::InvalidFormat(ref original) => {
|
Error::InvalidFormat(ref original) => {
|
||||||
write!(f, "Invalid color speci format: '{}'. Valid format \
|
write!(
|
||||||
is '(path|line|match):(fg|bg|style):(value)'.",
|
f,
|
||||||
original)
|
"Invalid color speci format: '{}'. Valid format \
|
||||||
|
is '(path|line|column|match):(fg|bg|style):(value)'.",
|
||||||
|
original)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -525,6 +530,7 @@ impl From<ParseColorError> for Error {
|
|||||||
pub struct ColorSpecs {
|
pub struct ColorSpecs {
|
||||||
path: ColorSpec,
|
path: ColorSpec,
|
||||||
line: ColorSpec,
|
line: ColorSpec,
|
||||||
|
column: ColorSpec,
|
||||||
matched: ColorSpec,
|
matched: ColorSpec,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,7 +560,7 @@ pub struct ColorSpecs {
|
|||||||
/// The format of a `Spec` is a triple: `{type}:{attribute}:{value}`. Each
|
/// The format of a `Spec` is a triple: `{type}:{attribute}:{value}`. Each
|
||||||
/// component is defined as follows:
|
/// component is defined as follows:
|
||||||
///
|
///
|
||||||
/// * `{type}` can be one of `path`, `line` or `match`.
|
/// * `{type}` can be one of `path`, `line`, `column` or `match`.
|
||||||
/// * `{attribute}` can be one of `fg`, `bg` or `style`. `{attribute}` may also
|
/// * `{attribute}` can be one of `fg`, `bg` or `style`. `{attribute}` may also
|
||||||
/// be the special value `none`, in which case, `{value}` can be omitted.
|
/// be the special value `none`, in which case, `{value}` can be omitted.
|
||||||
/// * `{value}` is either a color name (for `fg`/`bg`) or a style instruction.
|
/// * `{value}` is either a color name (for `fg`/`bg`) or a style instruction.
|
||||||
@@ -593,6 +599,7 @@ enum SpecValue {
|
|||||||
enum OutType {
|
enum OutType {
|
||||||
Path,
|
Path,
|
||||||
Line,
|
Line,
|
||||||
|
Column,
|
||||||
Match,
|
Match,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,6 +630,7 @@ impl ColorSpecs {
|
|||||||
match user_spec.ty {
|
match user_spec.ty {
|
||||||
OutType::Path => user_spec.merge_into(&mut specs.path),
|
OutType::Path => user_spec.merge_into(&mut specs.path),
|
||||||
OutType::Line => user_spec.merge_into(&mut specs.line),
|
OutType::Line => user_spec.merge_into(&mut specs.line),
|
||||||
|
OutType::Column => user_spec.merge_into(&mut specs.column),
|
||||||
OutType::Match => user_spec.merge_into(&mut specs.matched),
|
OutType::Match => user_spec.merge_into(&mut specs.matched),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -639,6 +647,11 @@ impl ColorSpecs {
|
|||||||
&self.line
|
&self.line
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the color specification for coloring column numbers.
|
||||||
|
fn column(&self) -> &ColorSpec {
|
||||||
|
&self.column
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the color specification for coloring matched text.
|
/// Return the color specification for coloring matched text.
|
||||||
fn matched(&self) -> &ColorSpec {
|
fn matched(&self) -> &ColorSpec {
|
||||||
&self.matched
|
&self.matched
|
||||||
@@ -714,6 +727,7 @@ impl FromStr for OutType {
|
|||||||
match &*s.to_lowercase() {
|
match &*s.to_lowercase() {
|
||||||
"path" => Ok(OutType::Path),
|
"path" => Ok(OutType::Path),
|
||||||
"line" => Ok(OutType::Line),
|
"line" => Ok(OutType::Line),
|
||||||
|
"column" => Ok(OutType::Column),
|
||||||
"match" => Ok(OutType::Match),
|
"match" => Ok(OutType::Match),
|
||||||
_ => Err(Error::UnrecognizedOutType(s.to_string())),
|
_ => Err(Error::UnrecognizedOutType(s.to_string())),
|
||||||
}
|
}
|
||||||
@@ -765,6 +779,7 @@ mod tests {
|
|||||||
assert_eq!(ColorSpecs::new(user_specs), ColorSpecs {
|
assert_eq!(ColorSpecs::new(user_specs), ColorSpecs {
|
||||||
path: ColorSpec::default(),
|
path: ColorSpec::default(),
|
||||||
line: ColorSpec::default(),
|
line: ColorSpec::default(),
|
||||||
|
column: ColorSpec::default(),
|
||||||
matched: expect_matched,
|
matched: expect_matched,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -800,6 +815,12 @@ mod tests {
|
|||||||
ty: OutType::Line,
|
ty: OutType::Line,
|
||||||
value: SpecValue::None,
|
value: SpecValue::None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let spec: Spec = "column:bg:green".parse().unwrap();
|
||||||
|
assert_eq!(spec, Spec {
|
||||||
|
ty: OutType::Column,
|
||||||
|
value: SpecValue::Bg(Color::Green),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@@ -3,8 +3,8 @@ The `search_buffer` module is responsible for searching a single file all in a
|
|||||||
single buffer. Typically, the source of the buffer is a memory map. This can
|
single buffer. Typically, the source of the buffer is a memory map. This can
|
||||||
be useful for when memory maps are faster than streaming search.
|
be useful for when memory maps are faster than streaming search.
|
||||||
|
|
||||||
Note that this module doesn't quite support everything that `search_stream` does.
|
Note that this module doesn't quite support everything that `search_stream`
|
||||||
Notably, showing contexts.
|
does. Notably, showing contexts.
|
||||||
*/
|
*/
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
3
termcolor/COPYING
Normal file
3
termcolor/COPYING
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
This project is dual-licensed under the Unlicense and MIT licenses.
|
||||||
|
|
||||||
|
You may use this code under the terms of either license.
|
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "0.3.1" #:version
|
version = "0.3.2" #:version
|
||||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||||
description = """
|
description = """
|
||||||
A simple cross platform library for writing colored text to a terminal.
|
A simple cross platform library for writing colored text to a terminal.
|
||||||
|
21
termcolor/LICENSE-MIT
Normal file
21
termcolor/LICENSE-MIT
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Andrew Gallant
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
24
termcolor/UNLICENSE
Normal file
24
termcolor/UNLICENSE
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
distribute this software, either in source code form or as a compiled
|
||||||
|
binary, for any purpose, commercial or non-commercial, and by any
|
||||||
|
means.
|
||||||
|
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors
|
||||||
|
of this software dedicate any and all copyright interest in the
|
||||||
|
software to the public domain. We make this dedication for the benefit
|
||||||
|
of the public at large and to the detriment of our heirs and
|
||||||
|
successors. We intend this dedication to be an overt act of
|
||||||
|
relinquishment in perpetuity of all present and future rights to this
|
||||||
|
software under copyright law.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
For more information, please refer to <http://unlicense.org/>
|
@@ -1057,6 +1057,33 @@ clean!(regression_405, "test", ".", |wd: WorkDir, mut cmd: Command| {
|
|||||||
assert_eq!(lines, format!("{}:test\n", path("bar/foo/file2.txt")));
|
assert_eq!(lines, format!("{}:test\n", path("bar/foo/file2.txt")));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/issues/428
|
||||||
|
clean!(regression_428_color_context_path, "foo", ".", |wd: WorkDir, mut cmd: Command| {
|
||||||
|
wd.create("sherlock", "foo\nbar");
|
||||||
|
cmd.arg("-A1").arg("-H").arg("--no-heading").arg("-N")
|
||||||
|
.arg("--colors=match:none").arg("--color=always");
|
||||||
|
|
||||||
|
let lines: String = wd.stdout(&mut cmd);
|
||||||
|
let expected = format!("\
|
||||||
|
{colored_path}:foo
|
||||||
|
{colored_path}-bar
|
||||||
|
", colored_path=format!("\x1b\x5b\x6d\x1b\x5b\x33\x35\x6d{path}\x1b\x5b\x6d", path=path("sherlock")));
|
||||||
|
assert_eq!(lines, expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/issues/428
|
||||||
|
clean!(regression_428_unrecognized_style, "Sherlok", ".", |wd: WorkDir, mut cmd: Command| {
|
||||||
|
cmd.arg("--colors=match:style:");
|
||||||
|
wd.assert_err(&mut cmd);
|
||||||
|
|
||||||
|
let output = cmd.output().unwrap();
|
||||||
|
let err = String::from_utf8_lossy(&output.stderr);
|
||||||
|
let expected = "\
|
||||||
|
Unrecognized style attribute ''. Choose from: nobold, bold, nointense, intense.
|
||||||
|
";
|
||||||
|
assert_eq!(err, expected);
|
||||||
|
});
|
||||||
|
|
||||||
// See: https://github.com/BurntSushi/ripgrep/issues/1
|
// See: https://github.com/BurntSushi/ripgrep/issues/1
|
||||||
clean!(feature_1_sjis, "Шерлок Холмс", ".", |wd: WorkDir, mut cmd: Command| {
|
clean!(feature_1_sjis, "Шерлок Холмс", ".", |wd: WorkDir, mut cmd: Command| {
|
||||||
let sherlock =
|
let sherlock =
|
||||||
@@ -1139,6 +1166,32 @@ be, to a very large extent, the result of luck. Sherlock Holmes
|
|||||||
assert_eq!(lines, expected);
|
assert_eq!(lines, expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/issues/34
|
||||||
|
sherlock!(feature_34_only_matching, "Sherlock", ".",
|
||||||
|
|wd: WorkDir, mut cmd: Command| {
|
||||||
|
cmd.arg("--only-matching");
|
||||||
|
|
||||||
|
let lines: String = wd.stdout(&mut cmd);
|
||||||
|
let expected = "\
|
||||||
|
sherlock:Sherlock
|
||||||
|
sherlock:Sherlock
|
||||||
|
";
|
||||||
|
assert_eq!(lines, expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/issues/34
|
||||||
|
sherlock!(feature_34_only_matching_line_column, "Sherlock", ".",
|
||||||
|
|wd: WorkDir, mut cmd: Command| {
|
||||||
|
cmd.arg("--only-matching").arg("--column").arg("--line-number");
|
||||||
|
|
||||||
|
let lines: String = wd.stdout(&mut cmd);
|
||||||
|
let expected = "\
|
||||||
|
sherlock:1:57:Sherlock
|
||||||
|
sherlock:3:49:Sherlock
|
||||||
|
";
|
||||||
|
assert_eq!(lines, expected);
|
||||||
|
});
|
||||||
|
|
||||||
// See: https://github.com/BurntSushi/ripgrep/issues/45
|
// See: https://github.com/BurntSushi/ripgrep/issues/45
|
||||||
sherlock!(feature_45_relative_cwd, "test", ".",
|
sherlock!(feature_45_relative_cwd, "test", ".",
|
||||||
|wd: WorkDir, mut cmd: Command| {
|
|wd: WorkDir, mut cmd: Command| {
|
||||||
@@ -1390,6 +1443,15 @@ clean!(feature_275_pathsep, "test", ".", |wd: WorkDir, mut cmd: Command| {
|
|||||||
assert_eq!(lines, "fooZbar:test\n");
|
assert_eq!(lines, "fooZbar:test\n");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/issues/419
|
||||||
|
sherlock!(feature_419_zero_as_shortcut_for_null, "Sherlock", ".",
|
||||||
|
|wd: WorkDir, mut cmd: Command| {
|
||||||
|
cmd.arg("-0").arg("--count");
|
||||||
|
|
||||||
|
let lines: String = wd.stdout(&mut cmd);
|
||||||
|
assert_eq!(lines, "sherlock\x002\n");
|
||||||
|
});
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn binary_nosearch() {
|
fn binary_nosearch() {
|
||||||
let wd = WorkDir::new("binary_nosearch");
|
let wd = WorkDir::new("binary_nosearch");
|
||||||
|
Reference in New Issue
Block a user