mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-08-26 18:03:56 -07:00
Compare commits
31 Commits
ag/changel
...
0.8.1
Author | SHA1 | Date | |
---|---|---|---|
|
c8e9f25b85 | ||
|
9305f89f39 | ||
|
9c216ad9a4 | ||
|
6862e07870 | ||
|
a6d09b2d42 | ||
|
ab1b877c20 | ||
|
2b5c488814 | ||
|
cb47be938e | ||
|
fe9be658f4 | ||
|
8c800adab7 | ||
|
d65966efbc | ||
|
597bf04a56 | ||
|
c78ab9e669 | ||
|
d57fc58081 | ||
|
d09538c974 | ||
|
94768881e1 | ||
|
f3a9ced82c | ||
|
18f549d289 | ||
|
c749b604dc | ||
|
d6748a3445 | ||
|
9b7f420faa | ||
|
361698b90a | ||
|
b71a110ccf | ||
|
5c1af3c25d | ||
|
ad3f55b0e5 | ||
|
b8e6d50bbe | ||
|
81afe8c5a0 | ||
|
c4e0d4bd7b | ||
|
23d1b91ead | ||
|
ac83ed4992 | ||
|
555fbd1201 |
15
.travis.yml
15
.travis.yml
@@ -30,7 +30,8 @@ matrix:
|
|||||||
env: TARGET=x86_64-unknown-linux-musl
|
env: TARGET=x86_64-unknown-linux-musl
|
||||||
- os: osx
|
- os: osx
|
||||||
rust: nightly
|
rust: nightly
|
||||||
env: TARGET=x86_64-apple-darwin
|
# XML_CATALOG_FILES is apparently necessary for asciidoc on macOS.
|
||||||
|
env: TARGET=x86_64-apple-darwin XML_CATALOG_FILES=/usr/local/etc/xml/catalog
|
||||||
- os: linux
|
- os: linux
|
||||||
rust: nightly
|
rust: nightly
|
||||||
env: TARGET=arm-unknown-linux-gnueabihf GCC_VERSION=4.8
|
env: TARGET=arm-unknown-linux-gnueabihf GCC_VERSION=4.8
|
||||||
@@ -41,6 +42,12 @@ matrix:
|
|||||||
- binutils-arm-linux-gnueabihf
|
- binutils-arm-linux-gnueabihf
|
||||||
- libc6-armhf-cross
|
- libc6-armhf-cross
|
||||||
- libc6-dev-armhf-cross
|
- libc6-dev-armhf-cross
|
||||||
|
# For generating man page.
|
||||||
|
- libxslt1-dev
|
||||||
|
- asciidoc
|
||||||
|
- docbook-xsl
|
||||||
|
- xsltproc
|
||||||
|
- libxml2-utils
|
||||||
# Beta channel. We enable these to make sure there are no regressions in
|
# Beta channel. We enable these to make sure there are no regressions in
|
||||||
# Rust beta releases.
|
# Rust beta releases.
|
||||||
- os: linux
|
- os: linux
|
||||||
@@ -67,6 +74,12 @@ matrix:
|
|||||||
- binutils-arm-linux-gnueabihf
|
- binutils-arm-linux-gnueabihf
|
||||||
- libc6-armhf-cross
|
- libc6-armhf-cross
|
||||||
- libc6-dev-armhf-cross
|
- libc6-dev-armhf-cross
|
||||||
|
# For generating man page.
|
||||||
|
- libxslt1-dev
|
||||||
|
- asciidoc
|
||||||
|
- docbook-xsl
|
||||||
|
- xsltproc
|
||||||
|
- libxml2-utils
|
||||||
install: ci/install.sh
|
install: ci/install.sh
|
||||||
script: ci/script.sh
|
script: ci/script.sh
|
||||||
before_deploy: ci/before_deploy.sh
|
before_deploy: ci/before_deploy.sh
|
||||||
|
40
CHANGELOG.md
40
CHANGELOG.md
@@ -1,4 +1,40 @@
|
|||||||
0.8.0 (2017-02-11)
|
0.8.1 (2018-02-20)
|
||||||
|
==================
|
||||||
|
This is a patch release of ripgrep that primarily fixes regressions introduced
|
||||||
|
in 0.8.0 (#820 and #824) in directory traversal on Windows. These regressions
|
||||||
|
do not impact non-Windows users.
|
||||||
|
|
||||||
|
Feature enhancements:
|
||||||
|
|
||||||
|
* Added or improved file type filtering for csv and VHDL.
|
||||||
|
* [FEATURE #798](https://github.com/BurntSushi/ripgrep/issues/798):
|
||||||
|
Add `underline` support to `termcolor` and ripgrep. See documentation on the
|
||||||
|
`--colors` flag for details.
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* [BUG #684](https://github.com/BurntSushi/ripgrep/issues/684):
|
||||||
|
Improve documentation for the `--ignore-file` flag.
|
||||||
|
* [BUG #789](https://github.com/BurntSushi/ripgrep/issues/789):
|
||||||
|
Don't show `(rev )` if the revision wasn't available during the build.
|
||||||
|
* [BUG #791](https://github.com/BurntSushi/ripgrep/issues/791):
|
||||||
|
Add man page to ARM release.
|
||||||
|
* [BUG #797](https://github.com/BurntSushi/ripgrep/issues/797):
|
||||||
|
Improve documentation for "intense" setting in `termcolor`.
|
||||||
|
* [BUG #800](https://github.com/BurntSushi/ripgrep/issues/800):
|
||||||
|
Fix a bug in the `ignore` crate for custom ignore files. This had no impact
|
||||||
|
on ripgrep.
|
||||||
|
* [BUG #807](https://github.com/BurntSushi/ripgrep/issues/807):
|
||||||
|
Fix a bug where `rg --hidden .` behaved differently from `rg --hidden ./`.
|
||||||
|
* [BUG #815](https://github.com/BurntSushi/ripgrep/issues/815):
|
||||||
|
Clarify a common failure mode in user guide.
|
||||||
|
* [BUG #820](https://github.com/BurntSushi/ripgrep/issues/820):
|
||||||
|
Fixes a bug on Windows where symlinks were followed even if not requested.
|
||||||
|
* [BUG #824](https://github.com/BurntSushi/ripgrep/issues/824):
|
||||||
|
Fix a performance regression in directory traversal on Windows.
|
||||||
|
|
||||||
|
|
||||||
|
0.8.0 (2018-02-11)
|
||||||
==================
|
==================
|
||||||
This is a new minor version releae of ripgrep that satisfies several popular
|
This is a new minor version releae of ripgrep that satisfies several popular
|
||||||
feature requests (config files, search compressed files, true colors), fixes
|
feature requests (config files, search compressed files, true colors), fixes
|
||||||
@@ -47,7 +83,7 @@ Feature enhancements:
|
|||||||
Add extended or "true" color support. Works in Windows 10!
|
Add extended or "true" color support. Works in Windows 10!
|
||||||
[See the FAQ for details.](FAQ.md#colors)
|
[See the FAQ for details.](FAQ.md#colors)
|
||||||
* [FEATURE #539](https://github.com/BurntSushi/ripgrep/issues/539):
|
* [FEATURE #539](https://github.com/BurntSushi/ripgrep/issues/539):
|
||||||
Search gzip, bsip2, lzma or xz files when given `-z/--search-zip` flag.
|
Search gzip, bzip2, lzma or xz files when given `-z/--search-zip` flag.
|
||||||
* [FEATURE #544](https://github.com/BurntSushi/ripgrep/issues/544):
|
* [FEATURE #544](https://github.com/BurntSushi/ripgrep/issues/544):
|
||||||
Add support for line number alignment via a new `--line-number-width` flag.
|
Add support for line number alignment via a new `--line-number-width` flag.
|
||||||
* [FEATURE #654](https://github.com/BurntSushi/ripgrep/pull/654):
|
* [FEATURE #654](https://github.com/BurntSushi/ripgrep/pull/654):
|
||||||
|
22
Cargo.lock
generated
22
Cargo.lock
generated
@@ -41,7 +41,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "2.29.4"
|
version = "2.30.0"
|
||||||
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.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -114,7 +114,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ignore"
|
name = "ignore"
|
||||||
version = "0.4.0"
|
version = "0.4.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"globset 0.3.0",
|
"globset 0.3.0",
|
||||||
@@ -125,7 +125,7 @@ dependencies = [
|
|||||||
"same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"walkdir 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -225,15 +225,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ripgrep"
|
name = "ripgrep"
|
||||||
version = "0.7.1"
|
version = "0.8.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bytecount 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytecount 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clap 2.29.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clap 2.30.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"globset 0.3.0",
|
"globset 0.3.0",
|
||||||
"grep 0.1.8",
|
"grep 0.1.8",
|
||||||
"ignore 0.4.0",
|
"ignore 0.4.1",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -242,7 +242,7 @@ dependencies = [
|
|||||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"termcolor 0.3.4",
|
"termcolor 0.3.5",
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -274,7 +274,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "0.3.4"
|
version = "0.3.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wincolor 0.1.6",
|
"wincolor 0.1.6",
|
||||||
]
|
]
|
||||||
@@ -331,7 +331,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "walkdir"
|
||||||
version = "2.1.3"
|
version = "2.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -371,7 +371,7 @@ dependencies = [
|
|||||||
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
|
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
|
||||||
"checksum bytecount 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "882585cd7ec84e902472df34a5e01891202db3bf62614e1f0afe459c1afcf744"
|
"checksum bytecount 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "882585cd7ec84e902472df34a5e01891202db3bf62614e1f0afe459c1afcf744"
|
||||||
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
||||||
"checksum clap 2.29.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7b8f59bcebcfe4269b09f71dab0da15b355c75916a8f975d3876ce81561893ee"
|
"checksum clap 2.30.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1c07b9257a00f3fc93b7f3c417fc15607ec7a56823bc2c37ec744e266387de5b"
|
||||||
"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
|
"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
|
||||||
"checksum encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98fd0f24d1fb71a4a6b9330c8ca04cbd4e7cc5d846b54ca74ff376bc7c9f798d"
|
"checksum encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98fd0f24d1fb71a4a6b9330c8ca04cbd4e7cc5d846b54ca74ff376bc7c9f798d"
|
||||||
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||||
@@ -401,7 +401,7 @@ dependencies = [
|
|||||||
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||||
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
|
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
|
||||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||||
"checksum walkdir 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b167e9a4420d8dddb260e70c90a4a375a1e5691f21f70e715553da87b6c2503a"
|
"checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369"
|
||||||
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
|
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
|
||||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ripgrep"
|
name = "ripgrep"
|
||||||
version = "0.7.1" #:version
|
version = "0.8.1" #: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
|
||||||
|
72
FAQ.md
72
FAQ.md
@@ -20,6 +20,7 @@
|
|||||||
* [How do I create an alias for ripgrep on Windows?](#rg-alias-windows)
|
* [How do I create an alias for ripgrep on Windows?](#rg-alias-windows)
|
||||||
* [How do I create a PowerShell profile?](#powershell-profile)
|
* [How do I create a PowerShell profile?](#powershell-profile)
|
||||||
* [How do I pipe non-ASCII content to ripgrep on Windows?](#pipe-non-ascii-windows)
|
* [How do I pipe non-ASCII content to ripgrep on Windows?](#pipe-non-ascii-windows)
|
||||||
|
* [Can ripgrep replace grep?](#posix4ever)
|
||||||
|
|
||||||
|
|
||||||
<h3 name="config">
|
<h3 name="config">
|
||||||
@@ -189,10 +190,10 @@ The --colors` flag is a bit more complicated. The general format is:
|
|||||||
* `{attribute}` should be one of `fg`, `bg` or `style`, corresponding to
|
* `{attribute}` should be one of `fg`, `bg` or `style`, corresponding to
|
||||||
foreground color, background color, or miscellaneous styling (such as whether
|
foreground color, background color, or miscellaneous styling (such as whether
|
||||||
to bold the output or not).
|
to bold the output or not).
|
||||||
* `{value}` is determined by the value of `{attribute}`. If `{attribute}` is
|
* `{value}` is determined by the value of `{attribute}`. If
|
||||||
`style`, then `{value}` should be one of `nobold`, `bold`, `nointense` or
|
`{attribute}` is `style`, then `{value}` should be one of `nobold`,
|
||||||
`intense`. If `{attribute}` is `fg` or `bg`, then `{value}` should be a
|
`bold`, `nointense`, `intense`, `nounderline` or `underline`. If
|
||||||
color.
|
`{attribute}` is `fg` or `bg`, then `{value}` should be a color.
|
||||||
|
|
||||||
A color is specified by either one of eight of English names, a single 256-bit
|
A color is specified by either one of eight of English names, a single 256-bit
|
||||||
number or an RGB triple (with over 16 million possible values, or "true
|
number or an RGB triple (with over 16 million possible values, or "true
|
||||||
@@ -466,3 +467,66 @@ that the console will use for printing to UTF-8 with
|
|||||||
`[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8`. This
|
`[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8`. This
|
||||||
will also reset when PowerShell is restarted, so you can add that line
|
will also reset when PowerShell is restarted, so you can add that line
|
||||||
to your profile as well if you want to make the setting permanent.
|
to your profile as well if you want to make the setting permanent.
|
||||||
|
|
||||||
|
|
||||||
|
<h3 name="posix4ever">
|
||||||
|
Can ripgrep replace grep?
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
Yes and no.
|
||||||
|
|
||||||
|
If, upon hearing that "ripgrep can replace grep," you *actually* hear, "ripgrep
|
||||||
|
can be used in every instance grep can be used, in exactly the same way, for
|
||||||
|
the same use cases, with exactly the same bug-for-bug behavior," then no,
|
||||||
|
ripgrep trivially *cannot* replace grep. Moreover, ripgrep will *never* replace
|
||||||
|
grep.
|
||||||
|
|
||||||
|
If, upon hearing that "ripgrep can replace grep," you *actually* hear, "ripgrep
|
||||||
|
can replace grep in some cases and not in other use cases," then yes, that is
|
||||||
|
indeed true!
|
||||||
|
|
||||||
|
Let's go over some of those use cases in favor of ripgrep. Some of these may
|
||||||
|
not apply to you. That's OK. There may be other use cases not listed here that
|
||||||
|
do apply to you. That's OK too.
|
||||||
|
|
||||||
|
(For all claims related to performance in the following words, see my
|
||||||
|
[blog post](https://blog.burntsushi.net/ripgrep/)
|
||||||
|
introducing ripgrep.)
|
||||||
|
|
||||||
|
* Are you frequently searching a repository of code? If so, ripgrep might be a
|
||||||
|
good choice since there's likely a good chunk of your repository that you
|
||||||
|
don't want to search. grep, can, of course, be made to filter files using
|
||||||
|
recursive search, and if you don't mind writing out the requisite `--exclude`
|
||||||
|
rules or writing wrapper scripts, then grep might be sufficient. (I'm not
|
||||||
|
kidding, I myself did this with grep for almost a decade before writing
|
||||||
|
ripgrep.) But if you instead enjoy having a search tool respect your
|
||||||
|
`.gitignore`, then ripgrep might be perfect for you!
|
||||||
|
* Are you frequently searching non-ASCII text that is UTF-8 encoded? One of
|
||||||
|
ripgrep's key features is that it can handle Unicode features in your
|
||||||
|
patterns in a way that tends to be faster than GNU grep. Unicode features
|
||||||
|
in ripgrep are enabled by default; there is no need to configure your locale
|
||||||
|
settings to use ripgrep properly because ripgrep doesn't respect your locale
|
||||||
|
settings.
|
||||||
|
* Do you need to search UTF-16 files and you don't want to bother explicitly
|
||||||
|
transcoding them? Great. ripgrep does this for you automatically. No need
|
||||||
|
to enable it.
|
||||||
|
* Do you need to search a large directory of large files? ripgrep uses
|
||||||
|
parallelism by default, which tends to make it faster than a standard
|
||||||
|
`grep -r` search. However, if you're OK writing the occasional
|
||||||
|
`find ./ -print0 | xargs -P8 -0 grep` command, then maybe grep is good
|
||||||
|
enough.
|
||||||
|
|
||||||
|
Here are some cases where you might *not* want to use ripgrep. The same caveats
|
||||||
|
for the previous section apply.
|
||||||
|
|
||||||
|
* Are you writing portable shell scripts intended to work in a variety of
|
||||||
|
environments? Great, probably not a good idea to use ripgrep! ripgrep is has
|
||||||
|
nowhere near the ubquity of grep, so if you do use ripgrep, you might need
|
||||||
|
to futz with the installation process more than you would with grep.
|
||||||
|
* Do you care about POSIX compatibility? If so, then you can't use ripgrep
|
||||||
|
because it never was, isn't and never will be POSIX compatible.
|
||||||
|
* Do you hate tools that try to do something smart? If so, ripgrep is all about
|
||||||
|
being smart, so you might prefer to just stick with grep.
|
||||||
|
* Is there a particular feature of grep you rely on that ripgrep either doesn't
|
||||||
|
have or never will have? If the former, file a bug report, maybe ripgrep can
|
||||||
|
do it! If the latter, well, then, just use grep.
|
||||||
|
4
GUIDE.md
4
GUIDE.md
@@ -58,6 +58,10 @@ $ rg fast README.md
|
|||||||
129: optimizations to make searching very fast.
|
129: optimizations to make searching very fast.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
(**Note:** If you see an error message from ripgrep saying that it didn't
|
||||||
|
search any files, then re-run ripgrep with the `--debug` flag. One likely cause
|
||||||
|
of this is that you have a `*` rule in a `$HOME/.gitignore` file.)
|
||||||
|
|
||||||
So what happened here? ripgrep read the contents of `README.md`, and for each
|
So what happened here? ripgrep read the contents of `README.md`, and for each
|
||||||
line that contained `fast`, ripgrep printed it to your terminal. ripgrep also
|
line that contained `fast`, ripgrep printed it to your terminal. ripgrep also
|
||||||
included the line number for each line by default. If your terminal supports
|
included the line number for each line by default. If your terminal supports
|
||||||
|
22
README.md
22
README.md
@@ -85,9 +85,9 @@ increases the times to `2.640s` for ripgrep and `10.277s` for GNU grep.
|
|||||||
|
|
||||||
### Why should I use ripgrep?
|
### Why should I use ripgrep?
|
||||||
|
|
||||||
* It can replace both The Silver Searcher and GNU grep because it is generally
|
* It can replace many use cases served by both The Silver Searcher and GNU grep
|
||||||
faster than both. (N.B. It is not, strictly speaking, a "drop-in" replacement
|
because it is generally faster than both. (See [the FAQ](FAQ.md#posix4ever)
|
||||||
for both, but the feature sets are far more similar than different.)
|
for more details on whether ripgrep can truly replace grep.)
|
||||||
* Like The Silver Searcher, ripgrep defaults to recursive directory search
|
* Like The Silver Searcher, ripgrep defaults to recursive directory search
|
||||||
and won't search files ignored by your `.gitignore` files. It also ignores
|
and won't search files ignored by your `.gitignore` files. It also ignores
|
||||||
hidden and binary files by default. ripgrep also implements full support
|
hidden and binary files by default. ripgrep also implements full support
|
||||||
@@ -172,8 +172,8 @@ The binary name for ripgrep is `rg`.
|
|||||||
|
|
||||||
**[Archives of precompiled binaries for ripgrep are available for Windows,
|
**[Archives of precompiled binaries for ripgrep are available for Windows,
|
||||||
macOS and Linux.](https://github.com/BurntSushi/ripgrep/releases)** Users of
|
macOS and Linux.](https://github.com/BurntSushi/ripgrep/releases)** Users of
|
||||||
platforms not explicitly mentioned below (such as Debian) are advised
|
platforms not explicitly mentioned below are advised to download one of these
|
||||||
to download one of these archives.
|
archives.
|
||||||
|
|
||||||
Linux binaries are static executables. Windows binaries are available either as
|
Linux binaries are static executables. Windows binaries are available either as
|
||||||
built with MinGW (GNU) or with Microsoft Visual C++ (MSVC). When possible,
|
built with MinGW (GNU) or with Microsoft Visual C++ (MSVC). When possible,
|
||||||
@@ -243,13 +243,23 @@ $ nix-env --install ripgrep
|
|||||||
$ # (Or using the attribute name, which is also ripgrep.)
|
$ # (Or using the attribute name, which is also ripgrep.)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you're a **Debian** user (or a user of a Debian derivative like **Ubuntu**),
|
||||||
|
then ripgrep can be installed using a binary `.deb` file provided in each
|
||||||
|
[ripgrep release](https://github.com/BurntSushi/ripgrep/releases). Note that
|
||||||
|
ripgrep is not in the official Debian or Ubuntu repositories.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ curl -LO https://github.com/BurntSushi/ripgrep/releases/download/0.8.1/ripgrep_0.8.1_amd64.deb
|
||||||
|
$ sudo dpkg -i ripgrep_0.8.1_amd64.deb
|
||||||
|
```
|
||||||
|
|
||||||
If you're an **Ubuntu** user, ripgrep can be installed from the `snap` store.
|
If you're an **Ubuntu** user, ripgrep can be installed from the `snap` store.
|
||||||
* Note that if you are using `16.04 LTS` or later, snap is already installed.
|
* Note that if you are using `16.04 LTS` or later, snap is already installed.
|
||||||
* For older versions you can install snap using
|
* For older versions you can install snap using
|
||||||
[this guide](https://docs.snapcraft.io/core/install-ubuntu).
|
[this guide](https://docs.snapcraft.io/core/install-ubuntu).
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo snap install rg
|
$ sudo snap install rg
|
||||||
```
|
```
|
||||||
|
|
||||||
If you're a **Rust programmer**, ripgrep can be installed with `cargo`.
|
If you're a **Rust programmer**, ripgrep can be installed with `cargo`.
|
||||||
|
9
build.rs
9
build.rs
@@ -58,8 +58,13 @@ fn git_revision_hash() -> Option<String> {
|
|||||||
let result = process::Command::new("git")
|
let result = process::Command::new("git")
|
||||||
.args(&["rev-parse", "--short=10", "HEAD"])
|
.args(&["rev-parse", "--short=10", "HEAD"])
|
||||||
.output();
|
.output();
|
||||||
result.ok().map(|output| {
|
result.ok().and_then(|output| {
|
||||||
String::from_utf8_lossy(&output.stdout).trim().to_string()
|
let v = String::from_utf8_lossy(&output.stdout).trim().to_string();
|
||||||
|
if v.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(v)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@ install_osx_dependencies() {
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
brew install asciidoc
|
brew install asciidoc docbook-xsl
|
||||||
}
|
}
|
||||||
|
|
||||||
configure_cargo() {
|
configure_cargo() {
|
||||||
|
16
ci/script.sh
16
ci/script.sh
@@ -23,6 +23,13 @@ main() {
|
|||||||
# sanity check the file type
|
# sanity check the file type
|
||||||
file target/"$TARGET"/debug/rg
|
file target/"$TARGET"/debug/rg
|
||||||
|
|
||||||
|
# Check that we've generated man page and other shell completions.
|
||||||
|
outdir="$(cargo_out_dir "target/$TARGET/debug")"
|
||||||
|
file "$outdir/rg.bash"
|
||||||
|
file "$outdir/rg.fish"
|
||||||
|
file "$outdir/_rg.ps1"
|
||||||
|
file "$outdir/rg.1"
|
||||||
|
|
||||||
# Apparently tests don't work on arm, so just bail now. I guess we provide
|
# Apparently tests don't work on arm, so just bail now. I guess we provide
|
||||||
# ARM releases on a best effort basis?
|
# ARM releases on a best effort basis?
|
||||||
if is_arm; then
|
if is_arm; then
|
||||||
@@ -32,15 +39,6 @@ main() {
|
|||||||
# Test that zsh completions are in sync with ripgrep's actual args.
|
# Test that zsh completions are in sync with ripgrep's actual args.
|
||||||
"$(dirname "${0}")/test_complete.sh"
|
"$(dirname "${0}")/test_complete.sh"
|
||||||
|
|
||||||
# Check that we've generated man page and other shell completions.
|
|
||||||
outdir="$(cargo_out_dir "target/$TARGET/debug")"
|
|
||||||
file "$outdir/rg.bash"
|
|
||||||
file "$outdir/rg.fish"
|
|
||||||
file "$outdir/_rg.ps1"
|
|
||||||
# N.B. man page isn't generated on ARM cross-compile, but we gave up
|
|
||||||
# long before this anyway.
|
|
||||||
file "$outdir/rg.1"
|
|
||||||
|
|
||||||
# Run tests for ripgrep and all sub-crates.
|
# Run tests for ripgrep and all sub-crates.
|
||||||
cargo test --target "$TARGET" --verbose --all
|
cargo test --target "$TARGET" --verbose --all
|
||||||
}
|
}
|
||||||
|
@@ -125,7 +125,7 @@ _rg() {
|
|||||||
|
|
||||||
[[ "${state}" == 'style' ]] &&
|
[[ "${state}" == 'style' ]] &&
|
||||||
_values -S ':' 'style value' \
|
_values -S ':' 'style value' \
|
||||||
bold nobold intense nointense && return 0
|
bold nobold intense nointense underline nounderline && return 0
|
||||||
;;
|
;;
|
||||||
|
|
||||||
typespec)
|
typespec)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ignore"
|
name = "ignore"
|
||||||
version = "0.4.0" #:version
|
version = "0.4.1" #: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`
|
||||||
|
@@ -73,13 +73,6 @@ struct IgnoreOptions {
|
|||||||
git_exclude: bool,
|
git_exclude: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IgnoreOptions {
|
|
||||||
/// Returns true if at least one type of ignore rules should be matched.
|
|
||||||
fn has_any_ignore_options(&self) -> bool {
|
|
||||||
self.ignore || self.git_global || self.git_ignore || self.git_exclude
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Ignore is a matcher useful for recursively walking one or more directories.
|
/// Ignore is a matcher useful for recursively walking one or more directories.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Ignore(Arc<IgnoreInner>);
|
pub struct Ignore(Arc<IgnoreInner>);
|
||||||
@@ -267,6 +260,15 @@ impl Ignore {
|
|||||||
(ig, errs.into_error_option())
|
(ig, errs.into_error_option())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if at least one type of ignore rule should be matched.
|
||||||
|
fn has_any_ignore_rules(&self) -> bool {
|
||||||
|
let opts = self.0.opts;
|
||||||
|
let has_custom_ignore_files = !self.0.custom_ignore_filenames.is_empty();
|
||||||
|
|
||||||
|
opts.ignore || opts.git_global || opts.git_ignore
|
||||||
|
|| opts.git_exclude || has_custom_ignore_files
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a match indicating whether the given file path should be
|
/// Returns a match indicating whether the given file path should be
|
||||||
/// ignored or not.
|
/// ignored or not.
|
||||||
///
|
///
|
||||||
@@ -295,7 +297,7 @@ impl Ignore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut whitelisted = Match::None;
|
let mut whitelisted = Match::None;
|
||||||
if self.0.opts.has_any_ignore_options() {
|
if self.has_any_ignore_rules() {
|
||||||
let mat = self.matched_ignore(path, is_dir);
|
let mat = self.matched_ignore(path, is_dir);
|
||||||
if mat.is_ignore() {
|
if mat.is_ignore() {
|
||||||
return mat;
|
return mat;
|
||||||
|
@@ -66,6 +66,12 @@ impl Glob {
|
|||||||
pub fn is_only_dir(&self) -> bool {
|
pub fn is_only_dir(&self) -> bool {
|
||||||
self.is_only_dir
|
self.is_only_dir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if and only if this glob has a `**/` prefix.
|
||||||
|
fn has_doublestar_prefix(&self) -> bool {
|
||||||
|
self.actual.starts_with("**/")
|
||||||
|
|| (self.actual == "**" && self.is_only_dir)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gitignore is a matcher for the globs in one or more gitignore files
|
/// Gitignore is a matcher for the globs in one or more gitignore files
|
||||||
@@ -278,7 +284,10 @@ impl Gitignore {
|
|||||||
// BUT, a file name might not have any directory components to it,
|
// BUT, a file name might not have any directory components to it,
|
||||||
// in which case, we don't want to accidentally strip any part of the
|
// in which case, we don't want to accidentally strip any part of the
|
||||||
// file name.
|
// file name.
|
||||||
if !is_file_name(path) {
|
//
|
||||||
|
// As an additional special case, if the root is just `.`, then we
|
||||||
|
// shouldn't try to strip anything, e.g., when path begins with a `.`.
|
||||||
|
if self.root != Path::new(".") && !is_file_name(path) {
|
||||||
if let Some(p) = strip_prefix(&self.root, path) {
|
if let Some(p) = strip_prefix(&self.root, path) {
|
||||||
path = p;
|
path = p;
|
||||||
// If we're left with a leading slash, get rid of it.
|
// If we're left with a leading slash, get rid of it.
|
||||||
@@ -454,7 +463,7 @@ impl GitignoreBuilder {
|
|||||||
// prefix.
|
// prefix.
|
||||||
if !literal_separator {
|
if !literal_separator {
|
||||||
// ... but only if we don't already have a **/ prefix.
|
// ... but only if we don't already have a **/ prefix.
|
||||||
if !(glob.actual.starts_with("**/") || (glob.actual == "**" && glob.is_only_dir)) {
|
if !glob.has_doublestar_prefix() {
|
||||||
glob.actual = format!("**/{}", glob.actual);
|
glob.actual = format!("**/{}", glob.actual);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -620,6 +629,12 @@ mod tests {
|
|||||||
ignored!(ig29, ROOT, "node_modules/ ", "node_modules", true);
|
ignored!(ig29, ROOT, "node_modules/ ", "node_modules", true);
|
||||||
ignored!(ig30, ROOT, "**/", "foo/bar", true);
|
ignored!(ig30, ROOT, "**/", "foo/bar", true);
|
||||||
ignored!(ig31, ROOT, "path1/*", "path1/foo");
|
ignored!(ig31, ROOT, "path1/*", "path1/foo");
|
||||||
|
ignored!(ig32, ROOT, ".a/b", ".a/b");
|
||||||
|
ignored!(ig33, "./", ".a/b", ".a/b");
|
||||||
|
ignored!(ig34, ".", ".a/b", ".a/b");
|
||||||
|
ignored!(ig35, "./.", ".a/b", ".a/b");
|
||||||
|
ignored!(ig36, "././", ".a/b", ".a/b");
|
||||||
|
ignored!(ig37, "././.", ".a/b", ".a/b");
|
||||||
|
|
||||||
not_ignored!(ignot1, ROOT, "amonths", "months");
|
not_ignored!(ignot1, ROOT, "amonths", "months");
|
||||||
not_ignored!(ignot2, ROOT, "monthsa", "months");
|
not_ignored!(ignot2, ROOT, "monthsa", "months");
|
||||||
|
@@ -122,6 +122,7 @@ const DEFAULT_TYPES: &'static [(&'static str, &'static [&'static str])] = &[
|
|||||||
("csharp", &["*.cs"]),
|
("csharp", &["*.cs"]),
|
||||||
("cshtml", &["*.cshtml"]),
|
("cshtml", &["*.cshtml"]),
|
||||||
("css", &["*.css", "*.scss"]),
|
("css", &["*.css", "*.scss"]),
|
||||||
|
("csv", &["*.csv"]),
|
||||||
("cython", &["*.pyx"]),
|
("cython", &["*.pyx"]),
|
||||||
("dart", &["*.dart"]),
|
("dart", &["*.dart"]),
|
||||||
("d", &["*.d"]),
|
("d", &["*.d"]),
|
||||||
@@ -274,6 +275,7 @@ const DEFAULT_TYPES: &'static [(&'static str, &'static [&'static str])] = &[
|
|||||||
("twig", &["*.twig"]),
|
("twig", &["*.twig"]),
|
||||||
("vala", &["*.vala"]),
|
("vala", &["*.vala"]),
|
||||||
("vb", &["*.vb"]),
|
("vb", &["*.vb"]),
|
||||||
|
("vhdl", &["*.vhd", "*.vhdl"]),
|
||||||
("vim", &["*.vim"]),
|
("vim", &["*.vim"]),
|
||||||
("vimscript", &["*.vim"]),
|
("vimscript", &["*.vim"]),
|
||||||
("wiki", &["*.mediawiki", "*.wiki"]),
|
("wiki", &["*.mediawiki", "*.wiki"]),
|
||||||
|
@@ -249,6 +249,14 @@ struct DirEntryRaw {
|
|||||||
/// The underlying inode number (Unix only).
|
/// The underlying inode number (Unix only).
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
ino: u64,
|
ino: u64,
|
||||||
|
/// The underlying metadata (Windows only). We store this on Windows
|
||||||
|
/// because this comes for free while reading a directory.
|
||||||
|
///
|
||||||
|
/// We use this to determine whether an entry is a directory or not, which
|
||||||
|
/// works around a bug in Rust's standard library:
|
||||||
|
/// https://github.com/rust-lang/rust/issues/46484
|
||||||
|
#[cfg(windows)]
|
||||||
|
metadata: fs::Metadata,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for DirEntryRaw {
|
impl fmt::Debug for DirEntryRaw {
|
||||||
@@ -274,6 +282,20 @@ impl DirEntryRaw {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn metadata(&self) -> Result<Metadata, Error> {
|
fn metadata(&self) -> Result<Metadata, Error> {
|
||||||
|
self.metadata_internal()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn metadata_internal(&self) -> Result<fs::Metadata, Error> {
|
||||||
|
if self.follow_link {
|
||||||
|
fs::metadata(&self.path)
|
||||||
|
} else {
|
||||||
|
Ok(self.metadata.clone())
|
||||||
|
}.map_err(|err| Error::Io(io::Error::from(err)).with_path(&self.path))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
fn metadata_internal(&self) -> Result<fs::Metadata, Error> {
|
||||||
if self.follow_link {
|
if self.follow_link {
|
||||||
fs::metadata(&self.path)
|
fs::metadata(&self.path)
|
||||||
} else {
|
} else {
|
||||||
@@ -309,21 +331,29 @@ impl DirEntryRaw {
|
|||||||
err: Box::new(err),
|
err: Box::new(err),
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
Ok(DirEntryRaw::from_entry_os(depth, ent, ty))
|
DirEntryRaw::from_entry_os(depth, ent, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(windows)]
|
||||||
fn from_entry_os(
|
fn from_entry_os(
|
||||||
depth: usize,
|
depth: usize,
|
||||||
ent: &fs::DirEntry,
|
ent: &fs::DirEntry,
|
||||||
ty: fs::FileType,
|
ty: fs::FileType,
|
||||||
) -> DirEntryRaw {
|
) -> Result<DirEntryRaw, Error> {
|
||||||
DirEntryRaw {
|
let md = ent.metadata().map_err(|err| {
|
||||||
|
let err = Error::Io(io::Error::from(err)).with_path(ent.path());
|
||||||
|
Error::WithDepth {
|
||||||
|
depth: depth,
|
||||||
|
err: Box::new(err),
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
Ok(DirEntryRaw {
|
||||||
path: ent.path(),
|
path: ent.path(),
|
||||||
ty: ty,
|
ty: ty,
|
||||||
follow_link: false,
|
follow_link: false,
|
||||||
depth: depth,
|
depth: depth,
|
||||||
}
|
metadata: md,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@@ -331,16 +361,16 @@ impl DirEntryRaw {
|
|||||||
depth: usize,
|
depth: usize,
|
||||||
ent: &fs::DirEntry,
|
ent: &fs::DirEntry,
|
||||||
ty: fs::FileType,
|
ty: fs::FileType,
|
||||||
) -> DirEntryRaw {
|
) -> Result<DirEntryRaw, Error> {
|
||||||
use std::os::unix::fs::DirEntryExt;
|
use std::os::unix::fs::DirEntryExt;
|
||||||
|
|
||||||
DirEntryRaw {
|
Ok(DirEntryRaw {
|
||||||
path: ent.path(),
|
path: ent.path(),
|
||||||
ty: ty,
|
ty: ty,
|
||||||
follow_link: false,
|
follow_link: false,
|
||||||
depth: depth,
|
depth: depth,
|
||||||
ino: ent.ino(),
|
ino: ent.ino(),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
@@ -353,6 +383,7 @@ impl DirEntryRaw {
|
|||||||
ty: md.file_type(),
|
ty: md.file_type(),
|
||||||
follow_link: true,
|
follow_link: true,
|
||||||
depth: depth,
|
depth: depth,
|
||||||
|
metadata: md,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1026,6 +1057,11 @@ impl Work {
|
|||||||
self.dent.is_dir()
|
self.dent.is_dir()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if and only if this work item is a symlink.
|
||||||
|
fn is_symlink(&self) -> bool {
|
||||||
|
self.dent.file_type().map_or(false, |ft| ft.is_symlink())
|
||||||
|
}
|
||||||
|
|
||||||
/// Adds ignore rules for parent directories.
|
/// Adds ignore rules for parent directories.
|
||||||
///
|
///
|
||||||
/// Note that this only applies to entries at depth 0. On all other
|
/// Note that this only applies to entries at depth 0. On all other
|
||||||
@@ -1112,7 +1148,7 @@ impl Worker {
|
|||||||
while let Some(mut work) = self.get_work() {
|
while let Some(mut work) = self.get_work() {
|
||||||
// If the work is not a directory, then we can just execute the
|
// If the work is not a directory, then we can just execute the
|
||||||
// caller's callback immediately and move on.
|
// caller's callback immediately and move on.
|
||||||
if !work.is_dir() {
|
if work.is_symlink() || !work.is_dir() {
|
||||||
if (self.f)(Ok(work.dent)).is_quit() {
|
if (self.f)(Ok(work.dent)).is_quit() {
|
||||||
self.quit_now();
|
self.quit_now();
|
||||||
return;
|
return;
|
||||||
@@ -1585,6 +1621,26 @@ mod tests {
|
|||||||
assert_paths(td.path(), &builder, &["bar", "a", "a/bar"]);
|
assert_paths(td.path(), &builder, &["bar", "a", "a/bar"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn custom_ignore_exclusive_use() {
|
||||||
|
let td = TempDir::new("walk-test-").unwrap();
|
||||||
|
let custom_ignore = ".customignore";
|
||||||
|
mkdirp(td.path().join("a"));
|
||||||
|
wfile(td.path().join(custom_ignore), "foo");
|
||||||
|
wfile(td.path().join("foo"), "");
|
||||||
|
wfile(td.path().join("a/foo"), "");
|
||||||
|
wfile(td.path().join("bar"), "");
|
||||||
|
wfile(td.path().join("a/bar"), "");
|
||||||
|
|
||||||
|
let mut builder = WalkBuilder::new(td.path());
|
||||||
|
builder.ignore(false);
|
||||||
|
builder.git_ignore(false);
|
||||||
|
builder.git_global(false);
|
||||||
|
builder.git_exclude(false);
|
||||||
|
builder.add_custom_ignore_filename(&custom_ignore);
|
||||||
|
assert_paths(td.path(), &builder, &["bar", "a", "a/bar"]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn gitignore() {
|
fn gitignore() {
|
||||||
let td = TempDir::new("walk-test-").unwrap();
|
let td = TempDir::new("walk-test-").unwrap();
|
||||||
|
4
pkg/archlinux/.gitignore
vendored
4
pkg/archlinux/.gitignore
vendored
@@ -1,4 +0,0 @@
|
|||||||
*.xz
|
|
||||||
src
|
|
||||||
pkg
|
|
||||||
*.gz
|
|
@@ -1,37 +0,0 @@
|
|||||||
# Contributor: Andrew Gallant <jamslam@gmail.com>
|
|
||||||
# Maintainer: Andrew Gallant
|
|
||||||
pkgname=ripgrep
|
|
||||||
pkgver=0.2.3
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc="A search tool that combines the usability of The Silver Searcher with the raw speed of grep."
|
|
||||||
arch=('i686' 'x86_64')
|
|
||||||
url="https://github.com/BurntSushi/ripgrep"
|
|
||||||
license=('UNLICENSE')
|
|
||||||
makedepends=('cargo')
|
|
||||||
source=("https://github.com/BurntSushi/$pkgname/archive/$pkgver.tar.gz")
|
|
||||||
sha256sums=('a88531558d2023df76190ea2e52bee50d739eabece8a57df29abbad0c6bdb917')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd "$pkgname-$pkgver"
|
|
||||||
if command -v rustup > /dev/null 2>&1; then
|
|
||||||
RUSTFLAGS="-C target-cpu=native" rustup run nightly \
|
|
||||||
cargo build --release --features simd-accel
|
|
||||||
elif rustc --version | grep -q nightly; then
|
|
||||||
RUSTFLAGS="-C target-cpu=native" \
|
|
||||||
cargo build --release --features simd-accel
|
|
||||||
else
|
|
||||||
cargo build --release
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd "$pkgname-$pkgver"
|
|
||||||
|
|
||||||
install -Dm755 "target/release/rg" "$pkgdir/usr/bin/rg"
|
|
||||||
install -Dm644 "doc/rg.1" "$pkgdir/usr/share/man/man1/rg.1"
|
|
||||||
install -Dm644 "README.md" "$pkgdir/usr/share/doc/ripgrep/README.md"
|
|
||||||
install -Dm644 "COPYING" "$pkgdir/usr/share/doc/ripgrep/COPYING"
|
|
||||||
install -Dm644 "LICENSE-MIT" "$pkgdir/usr/share/doc/ripgrep/LICENSE-MIT"
|
|
||||||
install -Dm644 "UNLICENSE" "$pkgdir/usr/share/doc/ripgrep/UNLICENSE"
|
|
||||||
install -Dm644 "CHANGELOG.md" "$pkgdir/usr/share/doc/ripgrep/CHANGELOG.md"
|
|
||||||
}
|
|
@@ -1,23 +1,23 @@
|
|||||||
class RipgrepBin < Formula
|
class RipgrepBin < Formula
|
||||||
version '0.7.1'
|
version '0.8.0'
|
||||||
desc "Search tool like grep and The Silver Searcher."
|
desc "Recursively search directories for a regex pattern."
|
||||||
homepage "https://github.com/BurntSushi/ripgrep"
|
homepage "https://github.com/BurntSushi/ripgrep"
|
||||||
|
|
||||||
if OS.mac?
|
if OS.mac?
|
||||||
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 "ee670b0fba46323ee9a2d1c5b8bee46fa3e45778f6f105f2e8e9ee29e8bd0d45"
|
sha256 "fb35e92fd57d28a1e68daf964764c3da7f027ad30cca7a07a1848224776f36b2"
|
||||||
elsif OS.linux?
|
elsif OS.linux?
|
||||||
url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-unknown-linux-musl.tar.gz"
|
url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-unknown-linux-musl.tar.gz"
|
||||||
sha256 "ac595c2239b9a30e0e0744578afa6b73e32cdd8ae61d4f1c0ee5d6b55adbadcf"
|
sha256 "621f2f16f65203aa37e7c10ecfb22384c4c01e70ebbd30a13c0d6944ffc6e59e"
|
||||||
end
|
end
|
||||||
|
|
||||||
conflicts_with "ripgrep"
|
conflicts_with "ripgrep"
|
||||||
|
|
||||||
def install
|
def install
|
||||||
bin.install "rg"
|
bin.install "rg"
|
||||||
man1.install "rg.1"
|
man1.install "doc/rg.1"
|
||||||
|
|
||||||
bash_completion.install "complete/rg.bash-completion"
|
bash_completion.install "complete/rg.bash"
|
||||||
fish_completion.install "complete/rg.fish"
|
fish_completion.install "complete/rg.fish"
|
||||||
zsh_completion.install "complete/_rg"
|
zsh_completion.install "complete/_rg"
|
||||||
end
|
end
|
||||||
|
17
src/app.rs
17
src/app.rs
@@ -682,7 +682,8 @@ fn flag_colors(args: &mut Vec<RGArg>) {
|
|||||||
This flag specifies color settings for use in the output. This flag may be
|
This flag specifies color settings for use in the output. This flag may be
|
||||||
provided multiple times. Settings are applied iteratively. Colors are limited
|
provided multiple times. Settings are applied iteratively. Colors are limited
|
||||||
to one of eight choices: red, blue, green, cyan, magenta, yellow, white and
|
to one of eight choices: red, blue, green, cyan, magenta, yellow, white and
|
||||||
black. Styles are limited to nobold, bold, nointense or intense.
|
black. Styles are limited to nobold, bold, nointense, intense, nounderline
|
||||||
|
or underline.
|
||||||
|
|
||||||
The format of the flag is `{type}:{attribute}:{value}`. `{type}` should be
|
The format of the flag is `{type}:{attribute}:{value}`. `{type}` should be
|
||||||
one of path, line, column or match. `{attribute}` can be fg, bg or style.
|
one of path, line, column or match. `{attribute}` can be fg, bg or style.
|
||||||
@@ -848,7 +849,7 @@ fn flag_files_with_matches(args: &mut Vec<RGArg>) {
|
|||||||
const LONG: &str = long!("\
|
const LONG: &str = long!("\
|
||||||
Only print the paths with at least one match.
|
Only print the paths with at least one match.
|
||||||
|
|
||||||
This overrides --file-without-match.
|
This overrides --files-without-match.
|
||||||
");
|
");
|
||||||
let arg = RGArg::switch("files-with-matches").short("l")
|
let arg = RGArg::switch("files-with-matches").short("l")
|
||||||
.help(SHORT).long_help(LONG)
|
.help(SHORT).long_help(LONG)
|
||||||
@@ -1000,12 +1001,12 @@ This flag overrides -s/--case-sensitive and -S/--smart-case.
|
|||||||
fn flag_ignore_file(args: &mut Vec<RGArg>) {
|
fn flag_ignore_file(args: &mut Vec<RGArg>) {
|
||||||
const SHORT: &str = "Specify additional ignore files.";
|
const SHORT: &str = "Specify additional ignore files.";
|
||||||
const LONG: &str = long!("\
|
const LONG: &str = long!("\
|
||||||
Specify one or more files which contain ignore patterns. These patterns are
|
Specifies a path to one or more .gitignore format rules files. These patterns
|
||||||
applied after the patterns found in .gitignore and .ignore are applied. Ignore
|
are applied after the patterns found in .gitignore and .ignore are applied
|
||||||
patterns should be in the gitignore format and are matched relative to the
|
and are matched relative to the current working directory. Multiple additional
|
||||||
current working directory. Multiple additional ignore files can be specified
|
ignore files can be specified by using the --ignore-file flag several times.
|
||||||
by using the --ignore-file flag several times. When specifying multiple ignore
|
When specifying multiple ignore files, earlier files have lower precedence
|
||||||
files, earlier files have lower precedence than later files.
|
than later files.
|
||||||
|
|
||||||
If you are looking for a way to include or exclude files and directories
|
If you are looking for a way to include or exclude files and directories
|
||||||
directly on the command line, then used -g instead.
|
directly on the command line, then used -g instead.
|
||||||
|
@@ -555,7 +555,8 @@ 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, nointense, intense.", name)
|
nobold, bold, nointense, intense, nounderline, \
|
||||||
|
underline.", name)
|
||||||
}
|
}
|
||||||
Error::InvalidFormat(ref original) => {
|
Error::InvalidFormat(ref original) => {
|
||||||
write!(
|
write!(
|
||||||
@@ -627,7 +628,8 @@ pub struct ColorSpecs {
|
|||||||
/// Valid colors are `black`, `blue`, `green`, `red`, `cyan`, `magenta`,
|
/// Valid colors are `black`, `blue`, `green`, `red`, `cyan`, `magenta`,
|
||||||
/// `yellow`, `white`.
|
/// `yellow`, `white`.
|
||||||
///
|
///
|
||||||
/// Valid style instructions are `nobold`, `bold`, `intense`, `nointense`.
|
/// Valid style instructions are `nobold`, `bold`, `intense`, `nointense`,
|
||||||
|
/// `underline`, `nounderline`.
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct Spec {
|
pub struct Spec {
|
||||||
ty: OutType,
|
ty: OutType,
|
||||||
@@ -668,6 +670,8 @@ enum Style {
|
|||||||
NoBold,
|
NoBold,
|
||||||
Intense,
|
Intense,
|
||||||
NoIntense,
|
NoIntense,
|
||||||
|
Underline,
|
||||||
|
NoUnderline
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColorSpecs {
|
impl ColorSpecs {
|
||||||
@@ -727,6 +731,8 @@ impl SpecValue {
|
|||||||
Style::NoBold => { cspec.set_bold(false); }
|
Style::NoBold => { cspec.set_bold(false); }
|
||||||
Style::Intense => { cspec.set_intense(true); }
|
Style::Intense => { cspec.set_intense(true); }
|
||||||
Style::NoIntense => { cspec.set_intense(false); }
|
Style::NoIntense => { cspec.set_intense(false); }
|
||||||
|
Style::Underline => { cspec.set_underline(true); }
|
||||||
|
Style::NoUnderline => { cspec.set_underline(false); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -806,6 +812,8 @@ impl FromStr for Style {
|
|||||||
"nobold" => Ok(Style::NoBold),
|
"nobold" => Ok(Style::NoBold),
|
||||||
"intense" => Ok(Style::Intense),
|
"intense" => Ok(Style::Intense),
|
||||||
"nointense" => Ok(Style::NoIntense),
|
"nointense" => Ok(Style::NoIntense),
|
||||||
|
"underline" => Ok(Style::Underline),
|
||||||
|
"nounderline" => Ok(Style::NoUnderline),
|
||||||
_ => Err(Error::UnrecognizedStyle(s.to_string())),
|
_ => Err(Error::UnrecognizedStyle(s.to_string())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -859,6 +867,12 @@ mod tests {
|
|||||||
value: SpecValue::Style(Style::Intense),
|
value: SpecValue::Style(Style::Intense),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let spec: Spec = "match:style:underline".parse().unwrap();
|
||||||
|
assert_eq!(spec, Spec {
|
||||||
|
ty: OutType::Match,
|
||||||
|
value: SpecValue::Style(Style::Underline),
|
||||||
|
});
|
||||||
|
|
||||||
let spec: Spec = "line:none".parse().unwrap();
|
let spec: Spec = "line:none".parse().unwrap();
|
||||||
assert_eq!(spec, Spec {
|
assert_eq!(spec, Spec {
|
||||||
ty: OutType::Line,
|
ty: OutType::Line,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "0.3.4" #:version
|
version = "0.3.5" #: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.
|
||||||
|
@@ -104,7 +104,7 @@ pub trait WriteColor: io::Write {
|
|||||||
fn reset(&mut self) -> io::Result<()>;
|
fn reset(&mut self) -> io::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: WriteColor> WriteColor for &'a mut T {
|
impl<'a, T: ?Sized + WriteColor> WriteColor for &'a mut T {
|
||||||
fn supports_color(&self) -> bool { (&**self).supports_color() }
|
fn supports_color(&self) -> bool { (&**self).supports_color() }
|
||||||
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
|
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
|
||||||
(&mut **self).set_color(spec)
|
(&mut **self).set_color(spec)
|
||||||
@@ -980,6 +980,9 @@ impl<W: io::Write> WriteColor for Ansi<W> {
|
|||||||
if spec.bold {
|
if spec.bold {
|
||||||
self.write_str("\x1B[1m")?;
|
self.write_str("\x1B[1m")?;
|
||||||
}
|
}
|
||||||
|
if spec.underline {
|
||||||
|
self.write_str("\x1B[4m")?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1212,6 +1215,7 @@ pub struct ColorSpec {
|
|||||||
bg_color: Option<Color>,
|
bg_color: Option<Color>,
|
||||||
bold: bool,
|
bold: bool,
|
||||||
intense: bool,
|
intense: bool,
|
||||||
|
underline: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColorSpec {
|
impl ColorSpec {
|
||||||
@@ -1251,10 +1255,37 @@ impl ColorSpec {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get whether this is underline or not.
|
||||||
|
///
|
||||||
|
/// Note that the underline setting has no effect in a Windows console.
|
||||||
|
pub fn underline(&self) -> bool { self.underline }
|
||||||
|
|
||||||
|
/// Set whether the text is underlined or not.
|
||||||
|
///
|
||||||
|
/// Note that the underline setting has no effect in a Windows console.
|
||||||
|
pub fn set_underline(&mut self, yes: bool) -> &mut ColorSpec {
|
||||||
|
self.underline = yes;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Get whether this is intense or not.
|
/// Get whether this is intense or not.
|
||||||
|
///
|
||||||
|
/// On Unix-like systems, this will output the ANSI escape sequence
|
||||||
|
/// that will print a high-intensity version of the color
|
||||||
|
/// specified.
|
||||||
|
///
|
||||||
|
/// On Windows systems, this will output the ANSI escape sequence
|
||||||
|
/// that will print a brighter version of the color specified.
|
||||||
pub fn intense(&self) -> bool { self.intense }
|
pub fn intense(&self) -> bool { self.intense }
|
||||||
|
|
||||||
/// Set whether the text is intense or not.
|
/// Set whether the text is intense or not.
|
||||||
|
///
|
||||||
|
/// On Unix-like systems, this will output the ANSI escape sequence
|
||||||
|
/// that will print a high-intensity version of the color
|
||||||
|
/// specified.
|
||||||
|
///
|
||||||
|
/// On Windows systems, this will output the ANSI escape sequence
|
||||||
|
/// that will print a brighter version of the color specified.
|
||||||
pub fn set_intense(&mut self, yes: bool) -> &mut ColorSpec {
|
pub fn set_intense(&mut self, yes: bool) -> &mut ColorSpec {
|
||||||
self.intense = yes;
|
self.intense = yes;
|
||||||
self
|
self
|
||||||
@@ -1262,7 +1293,8 @@ impl ColorSpec {
|
|||||||
|
|
||||||
/// Returns true if this color specification has no colors or styles.
|
/// Returns true if this color specification has no colors or styles.
|
||||||
pub fn is_none(&self) -> bool {
|
pub fn is_none(&self) -> bool {
|
||||||
self.fg_color.is_none() && self.bg_color.is_none() && !self.bold
|
self.fg_color.is_none() && self.bg_color.is_none()
|
||||||
|
&& !self.bold && !self.underline
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears this color specification so that it has no color/style settings.
|
/// Clears this color specification so that it has no color/style settings.
|
||||||
@@ -1270,6 +1302,7 @@ impl ColorSpec {
|
|||||||
self.fg_color = None;
|
self.fg_color = None;
|
||||||
self.bg_color = None;
|
self.bg_color = None;
|
||||||
self.bold = false;
|
self.bold = false;
|
||||||
|
self.underline = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes this color spec to the given Windows console.
|
/// Writes this color spec to the given Windows console.
|
||||||
|
@@ -1152,7 +1152,8 @@ clean!(regression_428_unrecognized_style, "Sherlok", ".",
|
|||||||
let output = cmd.output().unwrap();
|
let output = cmd.output().unwrap();
|
||||||
let err = String::from_utf8_lossy(&output.stderr);
|
let err = String::from_utf8_lossy(&output.stderr);
|
||||||
let expected = "\
|
let expected = "\
|
||||||
Unrecognized style attribute ''. Choose from: nobold, bold, nointense, intense.
|
Unrecognized style attribute ''. Choose from: nobold, bold, nointense, intense, \
|
||||||
|
nounderline, underline.
|
||||||
";
|
";
|
||||||
assert_eq!(err, expected);
|
assert_eq!(err, expected);
|
||||||
});
|
});
|
||||||
@@ -1232,6 +1233,19 @@ clean!(regression_599, "^$", "input.txt", |wd: WorkDir, mut cmd: Command| {
|
|||||||
assert_eq!(expected, lines);
|
assert_eq!(expected, lines);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/issues/807
|
||||||
|
clean!(regression_807, "test", ".", |wd: WorkDir, mut cmd: Command| {
|
||||||
|
wd.create(".gitignore", ".a/b");
|
||||||
|
wd.create_dir(".a/b");
|
||||||
|
wd.create_dir(".a/c");
|
||||||
|
wd.create(".a/b/file", "test");
|
||||||
|
wd.create(".a/c/file", "test");
|
||||||
|
|
||||||
|
cmd.arg("--hidden");
|
||||||
|
let lines: String = wd.stdout(&mut cmd);
|
||||||
|
assert_eq!(lines, format!("{}:test\n", path(".a/c/file")));
|
||||||
|
});
|
||||||
|
|
||||||
// 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 =
|
||||||
|
Reference in New Issue
Block a user