mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-05-19 09:40:22 -07:00
Compare commits
107 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6dfaec03e8 | ||
|
5fbc4fee64 | ||
|
004370bd16 | ||
|
de4baa1002 | ||
|
163ac157d3 | ||
|
e2362d4d51 | ||
|
d6b59feff8 | ||
|
94305125ef | ||
|
79cbe89deb | ||
|
bf63fe8f25 | ||
|
8bd5950296 | ||
|
6e0539ab91 | ||
|
4649aa9700 | ||
|
c009652e77 | ||
|
b9f7a9ba2b | ||
|
a1960877cf | ||
|
bb0925af91 | ||
|
be117dbafa | ||
|
06dc13ad2d | ||
|
c6c2e69b8f | ||
|
e67c868ddd | ||
|
d33f2e2f70 | ||
|
082edafffa | ||
|
7c8dc332b3 | ||
|
ea961915b5 | ||
|
7943bdfe82 | ||
|
312a7884fc | ||
|
ac02f54c89 | ||
|
24b337b940 | ||
|
a5083f99ce | ||
|
f89cdba5df | ||
|
f7b677d136 | ||
|
3f68a8f3d7 | ||
|
9d738ad0c0 | ||
|
6c5108ed17 | ||
|
e0f1000df6 | ||
|
ea99421ec8 | ||
|
af8c386d5e | ||
|
71d71d2d98 | ||
|
c9ebcbd8ab | ||
|
dec0dc3196 | ||
|
2f0a269f07 | ||
|
0a0893a765 | ||
|
35160a1cdb | ||
|
f1d23c06e3 | ||
|
22b677900f | ||
|
bb6f0f5519 | ||
|
b6ef99ee55 | ||
|
bb8601b2ba | ||
|
02b47b7469 | ||
|
d922b7ac11 | ||
|
2acf25c689 | ||
|
80007698d3 | ||
|
3ad0e83471 | ||
|
eca13f08a2 | ||
|
4f99f82b19 | ||
|
327d74f161 | ||
|
9da0995df4 | ||
|
e9abbc1a02 | ||
|
9bd30e8e48 | ||
|
59212d08d3 | ||
|
6ebebb2aaa | ||
|
e92e2ef813 | ||
|
4a30819302 | ||
|
9b42af96f0 | ||
|
648a65f197 | ||
|
bdf01f46a6 | ||
|
1c775f3a82 | ||
|
e50df40a19 | ||
|
1fa76d2a42 | ||
|
44aa5a417d | ||
|
2c3897585d | ||
|
6e9141a9ca | ||
|
c8e4a84519 | ||
|
f02a50a69d | ||
|
b9c774937f | ||
|
67dd809a80 | ||
|
e0a85678e1 | ||
|
23af5fb043 | ||
|
5dec4b8e37 | ||
|
827082a33a | ||
|
6c2a550e1e | ||
|
8e8fc9c503 | ||
|
2057023dc5 | ||
|
3f2fe0afee | ||
|
56c7ad175a | ||
|
5b7a30846f | ||
|
2a4dba3fbf | ||
|
84d65865e6 | ||
|
d9aaa11873 | ||
|
67ad9917ad | ||
|
daa157b5f9 | ||
|
ca5e294ad6 | ||
|
6c7947b819 | ||
|
9acb4a5405 | ||
|
0096c74c11 | ||
|
8c48355b03 | ||
|
f9b86de963 | ||
|
d23b74975a | ||
|
a5cbdb3dfe | ||
|
b6bac8484e | ||
|
805fa32d18 | ||
|
2d518dd1f9 | ||
|
8575d26179 | ||
|
2e81a7adfe | ||
|
cd5440fb62 | ||
|
2ee690e87a |
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
github: [BurntSushi]
|
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -24,7 +24,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: What version of ripgrep are you using?
|
label: What version of ripgrep are you using?
|
||||||
description: Enter the output of `rg --version`.
|
description: Enter the output of `rg --version`.
|
||||||
placeholder: ex. ripgrep 13.0.0
|
placeholder: ex. ripgrep 0.2.1
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
|
27
.github/workflows/ci.yml
vendored
27
.github/workflows/ci.yml
vendored
@ -75,6 +75,18 @@ jobs:
|
|||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
rust: stable
|
rust: stable
|
||||||
target: aarch64-unknown-linux-gnu
|
target: aarch64-unknown-linux-gnu
|
||||||
|
- build: stable-arm-gnueabihf
|
||||||
|
os: ubuntu-latest
|
||||||
|
rust: stable
|
||||||
|
target: armv7-unknown-linux-gnueabihf
|
||||||
|
- build: stable-arm-musleabihf
|
||||||
|
os: ubuntu-latest
|
||||||
|
rust: stable
|
||||||
|
target: armv7-unknown-linux-musleabihf
|
||||||
|
- build: stable-arm-musleabi
|
||||||
|
os: ubuntu-latest
|
||||||
|
rust: stable
|
||||||
|
target: armv7-unknown-linux-musleabi
|
||||||
- build: stable-powerpc64
|
- build: stable-powerpc64
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
rust: stable
|
rust: stable
|
||||||
@ -177,6 +189,21 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: ${{ env.CARGO }} test --bin rg ${{ env.TARGET_FLAGS }} flags::defs::tests::available_shorts -- --nocapture
|
run: ${{ env.CARGO }} test --bin rg ${{ env.TARGET_FLAGS }} flags::defs::tests::available_shorts -- --nocapture
|
||||||
|
|
||||||
|
# Setup and compile on the wasm32-wasip1 target
|
||||||
|
wasm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Install Rust
|
||||||
|
uses: dtolnay/rust-toolchain@master
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
- name: Add wasm32-wasip1 target
|
||||||
|
run: rustup target add wasm32-wasip1
|
||||||
|
- name: Basic build
|
||||||
|
run: cargo build --verbose
|
||||||
|
|
||||||
rustfmt:
|
rustfmt:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
46
.github/workflows/release.yml
vendored
46
.github/workflows/release.yml
vendored
@ -80,6 +80,24 @@ jobs:
|
|||||||
target: aarch64-unknown-linux-gnu
|
target: aarch64-unknown-linux-gnu
|
||||||
strip: aarch64-linux-gnu-strip
|
strip: aarch64-linux-gnu-strip
|
||||||
qemu: qemu-aarch64
|
qemu: qemu-aarch64
|
||||||
|
- build: stable-arm-gnueabihf
|
||||||
|
os: ubuntu-latest
|
||||||
|
rust: stable
|
||||||
|
target: armv7-unknown-linux-gnueabihf
|
||||||
|
strip: arm-linux-gnueabihf-strip
|
||||||
|
qemu: qemu-arm
|
||||||
|
- build: stable-arm-musleabihf
|
||||||
|
os: ubuntu-latest
|
||||||
|
rust: stable
|
||||||
|
target: armv7-unknown-linux-musleabihf
|
||||||
|
strip: arm-linux-musleabihf-strip
|
||||||
|
qemu: qemu-arm
|
||||||
|
- build: stable-arm-musleabi
|
||||||
|
os: ubuntu-latest
|
||||||
|
rust: stable
|
||||||
|
target: armv7-unknown-linux-musleabi
|
||||||
|
strip: arm-linux-musleabi-strip
|
||||||
|
qemu: qemu-arm
|
||||||
- build: stable-powerpc64
|
- build: stable-powerpc64
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
rust: stable
|
rust: stable
|
||||||
@ -175,9 +193,9 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
docker run --rm -v \
|
docker run --rm -v \
|
||||||
"$PWD/target:/target:Z" \
|
"$PWD/target:/target:Z" \
|
||||||
"rustembedded/cross:${{ matrix.target }}" \
|
"ghcr.io/cross-rs/${{ matrix.target }}:main" \
|
||||||
"${{ matrix.strip }}" \
|
"${{ matrix.strip }}" \
|
||||||
"/target/${{ matrix.target }}/release/rg"
|
"/$BIN"
|
||||||
|
|
||||||
- name: Determine archive name
|
- name: Determine archive name
|
||||||
shell: bash
|
shell: bash
|
||||||
@ -210,31 +228,31 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
docker run --rm -v \
|
docker run --rm -v \
|
||||||
"$PWD/target:/target:Z" \
|
"$PWD/target:/target:Z" \
|
||||||
"rustembedded/cross:${{ matrix.target }}" \
|
"ghcr.io/cross-rs/${{ matrix.target }}:main" \
|
||||||
"${{ matrix.qemu }}" "/$BIN" --version
|
"${{ matrix.qemu }}" "/$BIN" --version
|
||||||
docker run --rm -v \
|
docker run --rm -v \
|
||||||
"$PWD/target:/target:Z" \
|
"$PWD/target:/target:Z" \
|
||||||
"rustembedded/cross:${{ matrix.target }}" \
|
"ghcr.io/cross-rs/${{ matrix.target }}:main" \
|
||||||
"${{ matrix.qemu }}" "/$BIN" \
|
"${{ matrix.qemu }}" "/$BIN" \
|
||||||
--generate complete-bash > "$ARCHIVE/complete/rg.bash"
|
--generate complete-bash > "$ARCHIVE/complete/rg.bash"
|
||||||
docker run --rm -v \
|
docker run --rm -v \
|
||||||
"$PWD/target:/target:Z" \
|
"$PWD/target:/target:Z" \
|
||||||
"rustembedded/cross:${{ matrix.target }}" \
|
"ghcr.io/cross-rs/${{ matrix.target }}:main" \
|
||||||
"${{ matrix.qemu }}" "/$BIN" \
|
"${{ matrix.qemu }}" "/$BIN" \
|
||||||
--generate complete-fish > "$ARCHIVE/complete/rg.fish"
|
--generate complete-fish > "$ARCHIVE/complete/rg.fish"
|
||||||
docker run --rm -v \
|
docker run --rm -v \
|
||||||
"$PWD/target:/target:Z" \
|
"$PWD/target:/target:Z" \
|
||||||
"rustembedded/cross:${{ matrix.target }}" \
|
"ghcr.io/cross-rs/${{ matrix.target }}:main" \
|
||||||
"${{ matrix.qemu }}" "/$BIN" \
|
"${{ matrix.qemu }}" "/$BIN" \
|
||||||
--generate complete-powershell > "$ARCHIVE/complete/_rg.ps1"
|
--generate complete-powershell > "$ARCHIVE/complete/_rg.ps1"
|
||||||
docker run --rm -v \
|
docker run --rm -v \
|
||||||
"$PWD/target:/target:Z" \
|
"$PWD/target:/target:Z" \
|
||||||
"rustembedded/cross:${{ matrix.target }}" \
|
"ghcr.io/cross-rs/${{ matrix.target }}:main" \
|
||||||
"${{ matrix.qemu }}" "/$BIN" \
|
"${{ matrix.qemu }}" "/$BIN" \
|
||||||
--generate complete-zsh > "$ARCHIVE/complete/_rg"
|
--generate complete-zsh > "$ARCHIVE/complete/_rg"
|
||||||
docker run --rm -v \
|
docker run --rm -v \
|
||||||
"$PWD/target:/target:Z" \
|
"$PWD/target:/target:Z" \
|
||||||
"rustembedded/cross:${{ matrix.target }}" \
|
"ghcr.io/cross-rs/${{ matrix.target }}:main" \
|
||||||
"${{ matrix.qemu }}" "/$BIN" \
|
"${{ matrix.qemu }}" "/$BIN" \
|
||||||
--generate man > "$ARCHIVE/doc/rg.1"
|
--generate man > "$ARCHIVE/doc/rg.1"
|
||||||
|
|
||||||
@ -332,14 +350,15 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cargo deb --profile deb --target ${{ env.TARGET }}
|
cargo deb --profile deb --target ${{ env.TARGET }}
|
||||||
version="${{ needs.create-release.outputs.version }}"
|
version="${{ needs.create-release.outputs.version }}"
|
||||||
deb="target/${{ env.TARGET }}/debian/ripgrep_$version-1_amd64.deb"
|
echo "DEB_DIR=target/${{ env.TARGET }}/debian" >> $GITHUB_ENV
|
||||||
echo "DEB=$deb" >> $GITHUB_ENV
|
echo "DEB_NAME=ripgrep_$version-1_amd64.deb" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Create sha256 sum of deb file
|
- name: Create sha256 sum of deb file
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
sum="$DEB.sha256"
|
cd "$DEB_DIR"
|
||||||
shasum -a 256 "$DEB" > "$sum"
|
sum="$DEB_NAME.sha256"
|
||||||
|
shasum -a 256 "$DEB_NAME" > "$sum"
|
||||||
echo "SUM=$sum" >> $GITHUB_ENV
|
echo "SUM=$sum" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Upload release archive
|
- name: Upload release archive
|
||||||
@ -347,5 +366,6 @@ jobs:
|
|||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
cd "$DEB_DIR"
|
||||||
version="${{ needs.create-release.outputs.version }}"
|
version="${{ needs.create-release.outputs.version }}"
|
||||||
gh release upload "$version" ${{ env.DEB }} ${{ env.SUM }}
|
gh release upload "$version" "$DEB_NAME" "$SUM"
|
||||||
|
85
CHANGELOG.md
85
CHANGELOG.md
@ -1,3 +1,78 @@
|
|||||||
|
TBD
|
||||||
|
===
|
||||||
|
Unreleased changes. Release notes have not yet been written.
|
||||||
|
|
||||||
|
|
||||||
|
14.1.1 (2024-09-08)
|
||||||
|
===================
|
||||||
|
This is a minor release with a bug fix for a matching bug. In particular, a bug
|
||||||
|
was found that could cause ripgrep to ignore lines that should match. That is,
|
||||||
|
false negatives. It is difficult to characterize the specific set of regexes
|
||||||
|
in which this occurs as it requires multiple different optimization strategies
|
||||||
|
to collide and produce an incorrect result. But as one reported example, in
|
||||||
|
ripgrep, the regex `(?i:e.x|ex)` does not match `e-x` when it should. (This
|
||||||
|
bug is a result of an inner literal optimization performed in the `grep-regex`
|
||||||
|
crate and not in the `regex` crate.)
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* [BUG #2884](https://github.com/BurntSushi/ripgrep/issues/2884):
|
||||||
|
Fix bug where ripgrep could miss some matches that it should report.
|
||||||
|
|
||||||
|
Miscellaneous:
|
||||||
|
|
||||||
|
* [MISC #2748](https://github.com/BurntSushi/ripgrep/issues/2748):
|
||||||
|
Remove ripgrep's `simd-accel` feature because it was frequently broken.
|
||||||
|
|
||||||
|
|
||||||
|
14.1.0 (2024-01-06)
|
||||||
|
===================
|
||||||
|
This is a minor release with a few small new features and bug fixes. This
|
||||||
|
release contains a bug fix for unbounded memory growth while walking a
|
||||||
|
directory tree. This release also includes improvements to the completions for
|
||||||
|
the `fish` shell, and release binaries for several additional ARM targets.
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* [BUG #2664](https://github.com/BurntSushi/ripgrep/issues/2690):
|
||||||
|
Fix unbounded memory growth in the `ignore` crate.
|
||||||
|
|
||||||
|
Feature enhancements:
|
||||||
|
|
||||||
|
* Added or improved file type filtering for Lean and Meson.
|
||||||
|
* [FEATURE #2684](https://github.com/BurntSushi/ripgrep/issues/2684):
|
||||||
|
Improve completions for the `fish` shell.
|
||||||
|
* [FEATURE #2702](https://github.com/BurntSushi/ripgrep/pull/2702):
|
||||||
|
Add release binaries for `armv7-unknown-linux-gnueabihf`,
|
||||||
|
`armv7-unknown-linux-musleabihf` and `armv7-unknown-linux-musleabi`.
|
||||||
|
|
||||||
|
|
||||||
|
14.0.3 (2023-11-28)
|
||||||
|
===================
|
||||||
|
This is a patch release with a bug fix for the `--sortr` flag.
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* [BUG #2664](https://github.com/BurntSushi/ripgrep/issues/2664):
|
||||||
|
Fix `--sortr=path`. I left a `todo!()` in the source. Oof.
|
||||||
|
|
||||||
|
|
||||||
|
14.0.2 (2023-11-27)
|
||||||
|
===================
|
||||||
|
This is a patch release with a few small bug fixes.
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* [BUG #2654](https://github.com/BurntSushi/ripgrep/issues/2654):
|
||||||
|
Fix `deb` release sha256 sum file.
|
||||||
|
* [BUG #2658](https://github.com/BurntSushi/ripgrep/issues/2658):
|
||||||
|
Fix partial regression in the behavior of `--null-data --line-regexp`.
|
||||||
|
* [BUG #2659](https://github.com/BurntSushi/ripgrep/issues/2659):
|
||||||
|
Fix Fish shell completions.
|
||||||
|
* [BUG #2662](https://github.com/BurntSushi/ripgrep/issues/2662):
|
||||||
|
Fix typo in documentation for `-i/--ignore-case`.
|
||||||
|
|
||||||
|
|
||||||
14.0.1 (2023-11-26)
|
14.0.1 (2023-11-26)
|
||||||
===================
|
===================
|
||||||
This a patch release meant to fix `cargo install ripgrep` on Windows.
|
This a patch release meant to fix `cargo install ripgrep` on Windows.
|
||||||
@ -13,7 +88,7 @@ Bug fixes:
|
|||||||
ripgrep 14 is a new major version release of ripgrep that has some new
|
ripgrep 14 is a new major version release of ripgrep that has some new
|
||||||
features, performance improvements and a lot of bug fixes.
|
features, performance improvements and a lot of bug fixes.
|
||||||
|
|
||||||
The headling feature in this release is hyperlink support. In this release,
|
The headlining feature in this release is hyperlink support. In this release,
|
||||||
they are an opt-in feature but may change to an opt-out feature in the future.
|
they are an opt-in feature but may change to an opt-out feature in the future.
|
||||||
To enable them, try passing `--hyperlink-format default`. If you use [VS Code],
|
To enable them, try passing `--hyperlink-format default`. If you use [VS Code],
|
||||||
then try passing `--hyperlink-format vscode`. Please [report your experience
|
then try passing `--hyperlink-format vscode`. Please [report your experience
|
||||||
@ -22,10 +97,10 @@ with hyperlinks][report-hyperlinks], positive or negative.
|
|||||||
[VS Code]: https://code.visualstudio.com/
|
[VS Code]: https://code.visualstudio.com/
|
||||||
[report-hyperlinks]: https://github.com/BurntSushi/ripgrep/discussions/2611
|
[report-hyperlinks]: https://github.com/BurntSushi/ripgrep/discussions/2611
|
||||||
|
|
||||||
Another headling development in this release is that it contains a rewrite of
|
Another headlining development in this release is that it contains a rewrite
|
||||||
its regex engine. You generally shouldn't notice any changes, except for some
|
of its regex engine. You generally shouldn't notice any changes, except for
|
||||||
searches may get faster. You can read more about the [regex engine rewrite on
|
some searches may get faster. You can read more about the [regex engine rewrite
|
||||||
my blog][regex-internals]. Please [report your performance improvements or
|
on my blog][regex-internals]. Please [report your performance improvements or
|
||||||
regressions that you notice][report-perf].
|
regressions that you notice][report-perf].
|
||||||
|
|
||||||
[report-perf]: https://github.com/BurntSushi/ripgrep/discussions/2652
|
[report-perf]: https://github.com/BurntSushi/ripgrep/discussions/2652
|
||||||
|
304
Cargo.lock
generated
304
Cargo.lock
generated
@ -4,30 +4,24 @@ version = 3
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "1.1.2"
|
version = "1.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.75"
|
version = "1.0.87"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bstr"
|
name = "bstr"
|
||||||
version = "1.8.0"
|
version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c"
|
checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-automata",
|
"regex-automata",
|
||||||
@ -36,12 +30,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.83"
|
version = "1.1.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jobserver",
|
"jobserver",
|
||||||
"libc",
|
"libc",
|
||||||
|
"shlex",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -52,55 +47,45 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-channel"
|
name = "crossbeam-channel"
|
||||||
version = "0.5.8"
|
version = "0.5.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
|
checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-deque"
|
name = "crossbeam-deque"
|
||||||
version = "0.8.3"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
|
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
|
||||||
"crossbeam-epoch",
|
"crossbeam-epoch",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-epoch"
|
name = "crossbeam-epoch"
|
||||||
version = "0.9.15"
|
version = "0.9.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
|
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
|
||||||
"cfg-if",
|
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"memoffset",
|
|
||||||
"scopeguard",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.16"
|
version = "0.8.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
|
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encoding_rs"
|
name = "encoding_rs"
|
||||||
version = "0.8.33"
|
version = "0.8.34"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1"
|
checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"packed_simd",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -120,7 +105,7 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "globset"
|
name = "globset"
|
||||||
version = "0.4.14"
|
version = "0.4.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"bstr",
|
"bstr",
|
||||||
@ -134,7 +119,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "grep"
|
name = "grep"
|
||||||
version = "0.3.0"
|
version = "0.3.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"grep-cli",
|
"grep-cli",
|
||||||
"grep-matcher",
|
"grep-matcher",
|
||||||
@ -148,7 +133,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "grep-cli"
|
name = "grep-cli"
|
||||||
version = "0.1.10"
|
version = "0.1.11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bstr",
|
"bstr",
|
||||||
"globset",
|
"globset",
|
||||||
@ -168,7 +153,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "grep-pcre2"
|
name = "grep-pcre2"
|
||||||
version = "0.1.7"
|
version = "0.1.8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"grep-matcher",
|
"grep-matcher",
|
||||||
"log",
|
"log",
|
||||||
@ -177,7 +162,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "grep-printer"
|
name = "grep-printer"
|
||||||
version = "0.2.0"
|
version = "0.2.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bstr",
|
"bstr",
|
||||||
"grep-matcher",
|
"grep-matcher",
|
||||||
@ -191,7 +176,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "grep-regex"
|
name = "grep-regex"
|
||||||
version = "0.1.12"
|
version = "0.1.13"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bstr",
|
"bstr",
|
||||||
"grep-matcher",
|
"grep-matcher",
|
||||||
@ -202,7 +187,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "grep-searcher"
|
name = "grep-searcher"
|
||||||
version = "0.1.12"
|
version = "0.1.14"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bstr",
|
"bstr",
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
@ -217,7 +202,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ignore"
|
name = "ignore"
|
||||||
version = "0.4.21"
|
version = "0.4.23"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bstr",
|
"bstr",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
@ -233,9 +218,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.9"
|
version = "1.0.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jemalloc-sys"
|
name = "jemalloc-sys"
|
||||||
@ -259,9 +244,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jobserver"
|
name = "jobserver"
|
||||||
version = "0.1.27"
|
version = "0.1.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d"
|
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
@ -274,71 +259,36 @@ checksum = "baff4b617f7df3d896f97fe922b64817f6cd9a756bb81d40f8883f2f66dcb401"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.150"
|
version = "0.2.158"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libm"
|
|
||||||
version = "0.2.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.20"
|
version = "0.4.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.6.4"
|
version = "2.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memmap2"
|
name = "memmap2"
|
||||||
version = "0.9.0"
|
version = "0.9.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "deaba38d7abf1d4cca21cc89e932e542ba2b9258664d2a9ef0e61512039c9375"
|
checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memoffset"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-traits"
|
|
||||||
version = "0.2.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"libm",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "packed_simd"
|
|
||||||
version = "0.3.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1f9f08af0c877571712e2e3e686ad79efad9657dbf0f7c3c8ba943ff6c38932d"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pcre2"
|
name = "pcre2"
|
||||||
version = "0.2.6"
|
version = "0.2.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4c9d53a8ea5fc3d3568d3de4bebc12606fd0eb8234c602576f1f1ee4880488a7"
|
checksum = "3be55c43ac18044541d58d897e8f4c55157218428953ebd39d86df3ba0286b2b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
@ -347,9 +297,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pcre2-sys"
|
name = "pcre2-sys"
|
||||||
version = "0.2.7"
|
version = "0.2.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f8f5556f23cf2c0b481949fdfc19a7cd9b27ddcb00ef3477b0f4935cbdaedf2"
|
checksum = "550f5d18fb1b90c20b87e161852c10cde77858c3900c5059b5ad2a1449f11d8a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
@ -358,33 +308,33 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkg-config"
|
name = "pkg-config"
|
||||||
version = "0.3.27"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.70"
|
version = "1.0.86"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
|
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.33"
|
version = "1.0.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.10.2"
|
version = "1.10.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
|
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
@ -394,9 +344,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-automata"
|
name = "regex-automata"
|
||||||
version = "0.4.3"
|
version = "0.4.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
|
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
@ -405,13 +355,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.8.2"
|
version = "0.8.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ripgrep"
|
name = "ripgrep"
|
||||||
version = "14.0.1"
|
version = "14.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bstr",
|
"bstr",
|
||||||
@ -430,9 +380,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.15"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "same-file"
|
name = "same-file"
|
||||||
@ -443,26 +393,20 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "scopeguard"
|
|
||||||
version = "1.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.193"
|
version = "1.0.210"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
|
checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.193"
|
version = "1.0.210"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -471,20 +415,27 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.108"
|
version = "1.0.128"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
|
checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
|
"memchr",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "shlex"
|
||||||
version = "2.0.39"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.77"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -493,18 +444,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.4.0"
|
version = "1.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449"
|
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "textwrap"
|
name = "textwrap"
|
||||||
version = "0.16.0"
|
version = "0.16.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
|
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
@ -514,41 +465,92 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "walkdir"
|
||||||
version = "2.4.0"
|
version = "2.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
|
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"same-file",
|
"same-file",
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi"
|
|
||||||
version = "0.3.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
|
||||||
dependencies = [
|
|
||||||
"winapi-i686-pc-windows-gnu",
|
|
||||||
"winapi-x86_64-pc-windows-gnu",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-i686-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-util"
|
name = "winapi-util"
|
||||||
version = "0.1.6"
|
version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
name = "windows-sys"
|
||||||
version = "0.4.0"
|
version = "0.59.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm",
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_gnullvm",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_gnullvm",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
19
Cargo.toml
19
Cargo.toml
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ripgrep"
|
name = "ripgrep"
|
||||||
version = "14.0.1" #:version
|
version = "14.1.1" #:version
|
||||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||||
description = """
|
description = """
|
||||||
ripgrep is a line-oriented search tool that recursively searches the current
|
ripgrep is a line-oriented search tool that recursively searches the current
|
||||||
@ -51,8 +51,8 @@ members = [
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.75"
|
anyhow = "1.0.75"
|
||||||
bstr = "1.7.0"
|
bstr = "1.7.0"
|
||||||
grep = { version = "0.3.0", path = "crates/grep" }
|
grep = { version = "0.3.2", path = "crates/grep" }
|
||||||
ignore = { version = "0.4.21", path = "crates/ignore" }
|
ignore = { version = "0.4.23", path = "crates/ignore" }
|
||||||
lexopt = "0.3.0"
|
lexopt = "0.3.0"
|
||||||
log = "0.4.5"
|
log = "0.4.5"
|
||||||
serde_json = "1.0.23"
|
serde_json = "1.0.23"
|
||||||
@ -68,12 +68,23 @@ serde_derive = "1.0.77"
|
|||||||
walkdir = "2"
|
walkdir = "2"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
simd-accel = ["grep/simd-accel"]
|
|
||||||
pcre2 = ["grep/pcre2"]
|
pcre2 = ["grep/pcre2"]
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
debug = 1
|
debug = 1
|
||||||
|
|
||||||
|
[profile.release-lto]
|
||||||
|
inherits = "release"
|
||||||
|
opt-level = 3
|
||||||
|
debug = "none"
|
||||||
|
strip = "symbols"
|
||||||
|
debug-assertions = false
|
||||||
|
overflow-checks = false
|
||||||
|
lto = "fat"
|
||||||
|
panic = "abort"
|
||||||
|
incremental = false
|
||||||
|
codegen-units = 1
|
||||||
|
|
||||||
# This is the main way to strip binaries in the deb package created by
|
# This is the main way to strip binaries in the deb package created by
|
||||||
# 'cargo deb'. For other release binaries, we (currently) call 'strip'
|
# 'cargo deb'. For other release binaries, we (currently) call 'strip'
|
||||||
# explicitly in the release process.
|
# explicitly in the release process.
|
||||||
|
14
Cross.toml
14
Cross.toml
@ -1,14 +0,0 @@
|
|||||||
[target.x86_64-unknown-linux-musl]
|
|
||||||
image = "burntsushi/cross:x86_64-unknown-linux-musl"
|
|
||||||
|
|
||||||
[target.i686-unknown-linux-gnu]
|
|
||||||
image = "burntsushi/cross:i686-unknown-linux-gnu"
|
|
||||||
|
|
||||||
[target.aarch64-unknown-linux-gnu]
|
|
||||||
image = "burntsushi/cross:aarch64-unknown-linux-gnu"
|
|
||||||
|
|
||||||
[target.powerpc64-unknown-linux-gnu]
|
|
||||||
image = "burntsushi/cross:powerpc64-unknown-linux-gnu"
|
|
||||||
|
|
||||||
[target.s390x-unknown-linux-gnu]
|
|
||||||
image = "burntsushi/cross:s390x-unknown-linux-gnu"
|
|
23
FAQ.md
23
FAQ.md
@ -94,7 +94,7 @@ Does ripgrep have support for shell auto-completion?
|
|||||||
|
|
||||||
Yes! If you installed ripgrep through a package manager on a Unix system, then
|
Yes! If you installed ripgrep through a package manager on a Unix system, then
|
||||||
the shell completion files included in the release archive should have been
|
the shell completion files included in the release archive should have been
|
||||||
installed for you automatically. If not, you can generate completes using
|
installed for you automatically. If not, you can generate completions using
|
||||||
ripgrep's command line interface.
|
ripgrep's command line interface.
|
||||||
|
|
||||||
For **bash**:
|
For **bash**:
|
||||||
@ -113,14 +113,31 @@ $ mkdir -p "$dir"
|
|||||||
$ rg --generate complete-fish > "$dir/rg.fish"
|
$ rg --generate complete-fish > "$dir/rg.fish"
|
||||||
```
|
```
|
||||||
|
|
||||||
For **zsh**:
|
For **zsh**, the recommended approach is:
|
||||||
|
|
||||||
```
|
```zsh
|
||||||
$ dir="$HOME/.zsh-complete"
|
$ dir="$HOME/.zsh-complete"
|
||||||
$ mkdir -p "$dir"
|
$ mkdir -p "$dir"
|
||||||
$ rg --generate complete-zsh > "$dir/_rg"
|
$ rg --generate complete-zsh > "$dir/_rg"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
And then add `$HOME/.zsh-complete` to your `fpath` in, e.g., your
|
||||||
|
`$HOME/.zshrc` file:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
fpath=($HOME/.zsh-complete $fpath)
|
||||||
|
```
|
||||||
|
|
||||||
|
Or if you'd prefer to load and generate completions at the same time, you can
|
||||||
|
add the following to your `$HOME/.zshrc` file:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
$ source <(rg --generate complete-zsh)
|
||||||
|
```
|
||||||
|
|
||||||
|
Note though that while this approach is easier to setup, is generally slower
|
||||||
|
than the previous method, and will add more time to loading your shell prompt.
|
||||||
|
|
||||||
For **PowerShell**, create the completions:
|
For **PowerShell**, create the completions:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
122
README.md
122
README.md
@ -42,7 +42,7 @@ This example searches the entire
|
|||||||
[Linux kernel source tree](https://github.com/BurntSushi/linux)
|
[Linux kernel source tree](https://github.com/BurntSushi/linux)
|
||||||
(after running `make defconfig && make -j8`) for `[A-Z]+_SUSPEND`, where
|
(after running `make defconfig && make -j8`) for `[A-Z]+_SUSPEND`, where
|
||||||
all matches must be words. Timings were collected on a system with an Intel
|
all matches must be words. Timings were collected on a system with an Intel
|
||||||
i7-6900K 3.2 GHz.
|
i9-12900K 5.2 GHz.
|
||||||
|
|
||||||
Please remember that a single benchmark is never enough! See my
|
Please remember that a single benchmark is never enough! See my
|
||||||
[blog post on ripgrep](https://blog.burntsushi.net/ripgrep/)
|
[blog post on ripgrep](https://blog.burntsushi.net/ripgrep/)
|
||||||
@ -50,13 +50,14 @@ for a very detailed comparison with more benchmarks and analysis.
|
|||||||
|
|
||||||
| Tool | Command | Line count | Time |
|
| Tool | Command | Line count | Time |
|
||||||
| ---- | ------- | ---------- | ---- |
|
| ---- | ------- | ---------- | ---- |
|
||||||
| ripgrep (Unicode) | `rg -n -w '[A-Z]+_SUSPEND'` | 452 | **0.136s** |
|
| ripgrep (Unicode) | `rg -n -w '[A-Z]+_SUSPEND'` | 536 | **0.082s** (1.00x) |
|
||||||
| [git grep](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `git grep -P -n -w '[A-Z]+_SUSPEND'` | 452 | 0.348s |
|
| [hypergrep](https://github.com/p-ranav/hypergrep) | `hgrep -n -w '[A-Z]+_SUSPEND'` | 536 | 0.167s (2.04x) |
|
||||||
| [ugrep (Unicode)](https://github.com/Genivia/ugrep) | `ugrep -r --ignore-files --no-hidden -I -w '[A-Z]+_SUSPEND'` | 452 | 0.506s |
|
| [git grep](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `git grep -P -n -w '[A-Z]+_SUSPEND'` | 536 | 0.273s (3.34x) |
|
||||||
| [The Silver Searcher](https://github.com/ggreer/the_silver_searcher) | `ag -w '[A-Z]+_SUSPEND'` | 452 | 0.654s |
|
| [The Silver Searcher](https://github.com/ggreer/the_silver_searcher) | `ag -w '[A-Z]+_SUSPEND'` | 534 | 0.443s (5.43x) |
|
||||||
| [git grep](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `LC_ALL=C git grep -E -n -w '[A-Z]+_SUSPEND'` | 452 | 1.150s |
|
| [ugrep](https://github.com/Genivia/ugrep) | `ugrep -r --ignore-files --no-hidden -I -w '[A-Z]+_SUSPEND'` | 536 | 0.639s (7.82x) |
|
||||||
| [ack](https://github.com/beyondgrep/ack3) | `ack -w '[A-Z]+_SUSPEND'` | 452 | 4.054s |
|
| [git grep](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `LC_ALL=C git grep -E -n -w '[A-Z]+_SUSPEND'` | 536 | 0.727s (8.91x) |
|
||||||
| [git grep (Unicode)](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `LC_ALL=en_US.UTF-8 git grep -E -n -w '[A-Z]+_SUSPEND'` | 452 | 4.205s |
|
| [git grep (Unicode)](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `LC_ALL=en_US.UTF-8 git grep -E -n -w '[A-Z]+_SUSPEND'` | 536 | 2.670s (32.70x) |
|
||||||
|
| [ack](https://github.com/beyondgrep/ack3) | `ack -w '[A-Z]+_SUSPEND'` | 2677 | 2.935s (35.94x) |
|
||||||
|
|
||||||
Here's another benchmark on the same corpus as above that disregards gitignore
|
Here's another benchmark on the same corpus as above that disregards gitignore
|
||||||
files and searches with a whitelist instead. The corpus is the same as in the
|
files and searches with a whitelist instead. The corpus is the same as in the
|
||||||
@ -65,24 +66,52 @@ doing equivalent work:
|
|||||||
|
|
||||||
| Tool | Command | Line count | Time |
|
| Tool | Command | Line count | Time |
|
||||||
| ---- | ------- | ---------- | ---- |
|
| ---- | ------- | ---------- | ---- |
|
||||||
| ripgrep | `rg -uuu -tc -n -w '[A-Z]+_SUSPEND'` | 388 | **0.096s** |
|
| ripgrep | `rg -uuu -tc -n -w '[A-Z]+_SUSPEND'` | 447 | **0.063s** (1.00x) |
|
||||||
| [ugrep](https://github.com/Genivia/ugrep) | `ugrep -r -n --include='*.c' --include='*.h' -w '[A-Z]+_SUSPEND'` | 388 | 0.493s |
|
| [ugrep](https://github.com/Genivia/ugrep) | `ugrep -r -n --include='*.c' --include='*.h' -w '[A-Z]+_SUSPEND'` | 447 | 0.607s (9.62x) |
|
||||||
| [GNU grep](https://www.gnu.org/software/grep/) | `egrep -r -n --include='*.c' --include='*.h' -w '[A-Z]+_SUSPEND'` | 388 | 0.806s |
|
| [GNU grep](https://www.gnu.org/software/grep/) | `grep -E -r -n --include='*.c' --include='*.h' -w '[A-Z]+_SUSPEND'` | 447 | 0.674s (10.69x) |
|
||||||
|
|
||||||
And finally, a straight-up comparison between ripgrep, ugrep and GNU grep on a
|
Now we'll move to searching on single large file. Here is a straight-up
|
||||||
single large file cached in memory
|
comparison between ripgrep, ugrep and GNU grep on a file cached in memory
|
||||||
(~13GB, [`OpenSubtitles.raw.en.gz`](http://opus.nlpl.eu/download.php?f=OpenSubtitles/v2018/mono/OpenSubtitles.raw.en.gz)):
|
(~13GB, [`OpenSubtitles.raw.en.gz`](http://opus.nlpl.eu/download.php?f=OpenSubtitles/v2018/mono/OpenSubtitles.raw.en.gz), decompressed):
|
||||||
|
|
||||||
| Tool | Command | Line count | Time |
|
| Tool | Command | Line count | Time |
|
||||||
| ---- | ------- | ---------- | ---- |
|
| ---- | ------- | ---------- | ---- |
|
||||||
| ripgrep | `rg -w 'Sherlock [A-Z]\w+'` | 7882 | **2.769s** |
|
| ripgrep (Unicode) | `rg -w 'Sherlock [A-Z]\w+'` | 7882 | **1.042s** (1.00x) |
|
||||||
| [ugrep](https://github.com/Genivia/ugrep) | `ugrep -w 'Sherlock [A-Z]\w+'` | 7882 | 6.802s |
|
| [ugrep](https://github.com/Genivia/ugrep) | `ugrep -w 'Sherlock [A-Z]\w+'` | 7882 | 1.339s (1.28x) |
|
||||||
| [GNU grep](https://www.gnu.org/software/grep/) | `LC_ALL=en_US.UTF-8 egrep -w 'Sherlock [A-Z]\w+'` | 7882 | 9.027s |
|
| [GNU grep (Unicode)](https://www.gnu.org/software/grep/) | `LC_ALL=en_US.UTF-8 egrep -w 'Sherlock [A-Z]\w+'` | 7882 | 6.577s (6.31x) |
|
||||||
|
|
||||||
In the above benchmark, passing the `-n` flag (for showing line numbers)
|
In the above benchmark, passing the `-n` flag (for showing line numbers)
|
||||||
increases the times to `3.423s` for ripgrep and `13.031s` for GNU grep. ugrep
|
increases the times to `1.664s` for ripgrep and `9.484s` for GNU grep. ugrep
|
||||||
times are unaffected by the presence or absence of `-n`.
|
times are unaffected by the presence or absence of `-n`.
|
||||||
|
|
||||||
|
Beware of performance cliffs though:
|
||||||
|
|
||||||
|
| Tool | Command | Line count | Time |
|
||||||
|
| ---- | ------- | ---------- | ---- |
|
||||||
|
| ripgrep (Unicode) | `rg -w '[A-Z]\w+ Sherlock [A-Z]\w+'` | 485 | **1.053s** (1.00x) |
|
||||||
|
| [GNU grep (Unicode)](https://www.gnu.org/software/grep/) | `LC_ALL=en_US.UTF-8 grep -E -w '[A-Z]\w+ Sherlock [A-Z]\w+'` | 485 | 6.234s (5.92x) |
|
||||||
|
| [ugrep](https://github.com/Genivia/ugrep) | `ugrep -w '[A-Z]\w+ Sherlock [A-Z]\w+'` | 485 | 28.973s (27.51x) |
|
||||||
|
|
||||||
|
And performance can drop precipitously across the board when searching big
|
||||||
|
files for patterns without any opportunities for literal optimizations:
|
||||||
|
|
||||||
|
| Tool | Command | Line count | Time |
|
||||||
|
| ---- | ------- | ---------- | ---- |
|
||||||
|
| ripgrep | `rg '[A-Za-z]{30}'` | 6749 | **15.569s** (1.00x) |
|
||||||
|
| [ugrep](https://github.com/Genivia/ugrep) | `ugrep -E '[A-Za-z]{30}'` | 6749 | 21.857s (1.40x) |
|
||||||
|
| [GNU grep](https://www.gnu.org/software/grep/) | `LC_ALL=C grep -E '[A-Za-z]{30}'` | 6749 | 32.409s (2.08x) |
|
||||||
|
| [GNU grep (Unicode)](https://www.gnu.org/software/grep/) | `LC_ALL=en_US.UTF-8 grep -E '[A-Za-z]{30}'` | 6795 | 8m30s (32.74x) |
|
||||||
|
|
||||||
|
Finally, high match counts also tend to both tank performance and smooth
|
||||||
|
out the differences between tools (because performance is dominated by how
|
||||||
|
quickly one can handle a match and not the algorithm used to detect the match,
|
||||||
|
generally speaking):
|
||||||
|
|
||||||
|
| Tool | Command | Line count | Time |
|
||||||
|
| ---- | ------- | ---------- | ---- |
|
||||||
|
| ripgrep | `rg the` | 83499915 | **6.948s** (1.00x) |
|
||||||
|
| [ugrep](https://github.com/Genivia/ugrep) | `ugrep the` | 83499915 | 11.721s (1.69x) |
|
||||||
|
| [GNU grep](https://www.gnu.org/software/grep/) | `LC_ALL=C grep the` | 83499915 | 15.217s (2.19x) |
|
||||||
|
|
||||||
### Why should I use ripgrep?
|
### Why should I use ripgrep?
|
||||||
|
|
||||||
@ -109,7 +138,7 @@ times are unaffected by the presence or absence of `-n`.
|
|||||||
backreferences in your patterns, which are not supported in ripgrep's default
|
backreferences in your patterns, which are not supported in ripgrep's default
|
||||||
regex engine. PCRE2 support can be enabled with `-P/--pcre2` (use PCRE2
|
regex engine. PCRE2 support can be enabled with `-P/--pcre2` (use PCRE2
|
||||||
always) or `--auto-hybrid-regex` (use PCRE2 only if needed). An alternative
|
always) or `--auto-hybrid-regex` (use PCRE2 only if needed). An alternative
|
||||||
syntax is provided via the `--engine (default|pcre2|auto-hybrid)` option.
|
syntax is provided via the `--engine (default|pcre2|auto)` option.
|
||||||
* ripgrep has [rudimentary support for replacements](GUIDE.md#replacements),
|
* ripgrep has [rudimentary support for replacements](GUIDE.md#replacements),
|
||||||
which permit rewriting output based on what was matched.
|
which permit rewriting output based on what was matched.
|
||||||
* ripgrep supports [searching files in text encodings](GUIDE.md#file-encoding)
|
* ripgrep supports [searching files in text encodings](GUIDE.md#file-encoding)
|
||||||
@ -191,6 +220,16 @@ configuration files, passthru, support for searching compressed files,
|
|||||||
multiline search and opt-in fancy regex support via PCRE2.
|
multiline search and opt-in fancy regex support via PCRE2.
|
||||||
|
|
||||||
|
|
||||||
|
### Playground
|
||||||
|
|
||||||
|
If you'd like to try ripgrep before installing, there's an unofficial
|
||||||
|
[playground](https://codapi.org/ripgrep/) and an [interactive
|
||||||
|
tutorial](https://codapi.org/try/ripgrep/).
|
||||||
|
|
||||||
|
If you have any questions about these, please open an issue in the [tutorial
|
||||||
|
repo](https://github.com/nalgeon/tryxinyminutes).
|
||||||
|
|
||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
|
|
||||||
The binary name for ripgrep is `rg`.
|
The binary name for ripgrep is `rg`.
|
||||||
@ -279,11 +318,17 @@ If you're a **Nix** user, you can install ripgrep from
|
|||||||
$ nix-env --install ripgrep
|
$ nix-env --install ripgrep
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you're a **Flox** user, you can install ripgrep as follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ flox install ripgrep
|
||||||
|
```
|
||||||
|
|
||||||
If you're a **Guix** user, you can install ripgrep from the official
|
If you're a **Guix** user, you can install ripgrep from the official
|
||||||
package collection:
|
package collection:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ sudo guix install ripgrep
|
$ guix install ripgrep
|
||||||
```
|
```
|
||||||
|
|
||||||
If you're a **Debian** user (or a user of a Debian derivative like **Ubuntu**),
|
If you're a **Debian** user (or a user of a Debian derivative like **Ubuntu**),
|
||||||
@ -291,8 +336,8 @@ then ripgrep can be installed using a binary `.deb` file provided in each
|
|||||||
[ripgrep release](https://github.com/BurntSushi/ripgrep/releases).
|
[ripgrep release](https://github.com/BurntSushi/ripgrep/releases).
|
||||||
|
|
||||||
```
|
```
|
||||||
$ curl -LO https://github.com/BurntSushi/ripgrep/releases/download/13.0.0/ripgrep_13.0.0_amd64.deb
|
$ curl -LO https://github.com/BurntSushi/ripgrep/releases/download/14.1.0/ripgrep_14.1.0-1_amd64.deb
|
||||||
$ sudo dpkg -i ripgrep_13.0.0_amd64.deb
|
$ sudo dpkg -i ripgrep_14.1.0-1_amd64.deb
|
||||||
```
|
```
|
||||||
|
|
||||||
If you run Debian stable, ripgrep is [officially maintained by
|
If you run Debian stable, ripgrep is [officially maintained by
|
||||||
@ -358,9 +403,16 @@ same port as Haiku x86_64 using the x86 secondary architecture build:
|
|||||||
$ sudo pkgman install ripgrep_x86
|
$ sudo pkgman install ripgrep_x86
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you're a **Void Linux** user, then you can install ripgrep from the
|
||||||
|
[official repository](https://voidlinux.org/packages/?arch=x86_64&q=ripgrep):
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo xbps-install -Syv ripgrep
|
||||||
|
```
|
||||||
|
|
||||||
If you're a **Rust programmer**, ripgrep can be installed with `cargo`.
|
If you're a **Rust programmer**, ripgrep can be installed with `cargo`.
|
||||||
|
|
||||||
* Note that the minimum supported version of Rust for ripgrep is **1.70.0**,
|
* Note that the minimum supported version of Rust for ripgrep is **1.72.0**,
|
||||||
although ripgrep may work with older versions.
|
although ripgrep may work with older versions.
|
||||||
* Note that the binary may be bigger than expected because it contains debug
|
* Note that the binary may be bigger than expected because it contains debug
|
||||||
symbols. This is intentional. To remove debug symbols and therefore reduce
|
symbols. This is intentional. To remove debug symbols and therefore reduce
|
||||||
@ -383,7 +435,7 @@ $ cargo binstall ripgrep
|
|||||||
|
|
||||||
ripgrep is written in Rust, so you'll need to grab a
|
ripgrep is written in Rust, so you'll need to grab a
|
||||||
[Rust installation](https://www.rust-lang.org/) in order to compile it.
|
[Rust installation](https://www.rust-lang.org/) in order to compile it.
|
||||||
ripgrep compiles with Rust 1.70.0 (stable) or newer. In general, ripgrep tracks
|
ripgrep compiles with Rust 1.72.0 (stable) or newer. In general, ripgrep tracks
|
||||||
the latest stable release of the Rust compiler.
|
the latest stable release of the Rust compiler.
|
||||||
|
|
||||||
To build ripgrep:
|
To build ripgrep:
|
||||||
@ -396,18 +448,13 @@ $ ./target/release/rg --version
|
|||||||
0.1.3
|
0.1.3
|
||||||
```
|
```
|
||||||
|
|
||||||
If you have a Rust nightly compiler and a recent Intel CPU, then you can enable
|
**NOTE:** In the past, ripgrep supported a `simd-accel` Cargo feature when
|
||||||
additional optional SIMD acceleration like so:
|
using a Rust nightly compiler. This only benefited UTF-16 transcoding.
|
||||||
|
Since it required unstable features, this build mode was prone to breakage.
|
||||||
```
|
Because of that, support for it has been removed. If you want SIMD
|
||||||
RUSTFLAGS="-C target-cpu=native" cargo build --release --features 'simd-accel'
|
optimizations for UTF-16 transcoding, then you'll have to petition the
|
||||||
```
|
[`encoding_rs`](https://github.com/hsivonen/encoding_rs) project to use stable
|
||||||
|
APIs.
|
||||||
The `simd-accel` feature enables SIMD support in certain ripgrep dependencies
|
|
||||||
(responsible for transcoding). They are not necessary to get SIMD optimizations
|
|
||||||
for search; those are enabled automatically. Hopefully, some day, the
|
|
||||||
`simd-accel` feature will similarly become unnecessary. **WARNING:** Currently,
|
|
||||||
enabling this option can increase compilation times dramatically.
|
|
||||||
|
|
||||||
Finally, optional PCRE2 support can be built with ripgrep by enabling the
|
Finally, optional PCRE2 support can be built with ripgrep by enabling the
|
||||||
`pcre2` feature:
|
`pcre2` feature:
|
||||||
@ -416,9 +463,6 @@ Finally, optional PCRE2 support can be built with ripgrep by enabling the
|
|||||||
$ cargo build --release --features 'pcre2'
|
$ cargo build --release --features 'pcre2'
|
||||||
```
|
```
|
||||||
|
|
||||||
(Tip: use `--features 'pcre2 simd-accel'` to also include compile time SIMD
|
|
||||||
optimizations, which will only work with a nightly compiler.)
|
|
||||||
|
|
||||||
Enabling the PCRE2 feature works with a stable Rust compiler and will
|
Enabling the PCRE2 feature works with a stable Rust compiler and will
|
||||||
attempt to automatically find and link with your system's PCRE2 library via
|
attempt to automatically find and link with your system's PCRE2 library via
|
||||||
`pkg-config`. If one doesn't exist, then ripgrep will build PCRE2 from source
|
`pkg-config`. If one doesn't exist, then ripgrep will build PCRE2 from source
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
These are Docker images used for cross compilation in CI builds (or locally)
|
|
||||||
via the [Cross](https://github.com/rust-embedded/cross) tool.
|
|
||||||
|
|
||||||
The Cross tool actually provides its own Docker images, and all Docker images
|
|
||||||
in this directory are derived from one of them. We provide our own in order to
|
|
||||||
customize the environment. For example, we need to install compression tools
|
|
||||||
like `xz` so that tests for the `-z/--search-zip` flag are run.
|
|
||||||
|
|
||||||
If you make a change to a Docker image, then you can re-build it. `cd` into the
|
|
||||||
directory containing the `Dockerfile` and run:
|
|
||||||
|
|
||||||
$ cd x86_64-unknown-linux-musl
|
|
||||||
$ ./build
|
|
||||||
|
|
||||||
At this point, subsequent uses of `cross` will now use your built image since
|
|
||||||
Docker prefers local images over remote images. In order to make these changes
|
|
||||||
stick, they need to be pushed to Docker Hub:
|
|
||||||
|
|
||||||
$ docker push burntsushi/cross:x86_64-unknown-linux-musl
|
|
||||||
|
|
||||||
Of course, only I (BurntSushi) can push to that location. To make `cross` use
|
|
||||||
a different location, then edit `Cross.toml` in the root of this repo to use
|
|
||||||
a different image name for the desired target.
|
|
@ -1,4 +0,0 @@
|
|||||||
FROM rustembedded/cross:aarch64-unknown-linux-gnu
|
|
||||||
|
|
||||||
COPY stage/ubuntu-install-packages /
|
|
||||||
RUN /ubuntu-install-packages
|
|
@ -1,5 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
mkdir -p stage
|
|
||||||
cp ../../ubuntu-install-packages ./stage/
|
|
||||||
docker build -t burntsushi/cross:aarch64-unknown-linux-gnu .
|
|
@ -1,4 +0,0 @@
|
|||||||
FROM rustembedded/cross:i686-unknown-linux-gnu
|
|
||||||
|
|
||||||
COPY stage/ubuntu-install-packages /
|
|
||||||
RUN /ubuntu-install-packages
|
|
@ -1,5 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
mkdir -p stage
|
|
||||||
cp ../../ubuntu-install-packages ./stage/
|
|
||||||
docker build -t burntsushi/cross:i686-unknown-linux-gnu .
|
|
@ -1,4 +0,0 @@
|
|||||||
FROM rustembedded/cross:powerpc64-unknown-linux-gnu
|
|
||||||
|
|
||||||
COPY stage/ubuntu-install-packages /
|
|
||||||
RUN /ubuntu-install-packages
|
|
@ -1,5 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
mkdir -p stage
|
|
||||||
cp ../../ubuntu-install-packages ./stage/
|
|
||||||
docker build -t burntsushi/cross:powerpc64-unknown-linux-gnu .
|
|
@ -1,4 +0,0 @@
|
|||||||
FROM rustembedded/cross:s390x-unknown-linux-gnu
|
|
||||||
|
|
||||||
COPY stage/ubuntu-install-packages /
|
|
||||||
RUN /ubuntu-install-packages
|
|
@ -1,5 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
mkdir -p stage
|
|
||||||
cp ../../ubuntu-install-packages ./stage/
|
|
||||||
docker build -t burntsushi/cross:s390x-unknown-linux-gnu .
|
|
@ -1,4 +0,0 @@
|
|||||||
FROM rustembedded/cross:x86_64-unknown-linux-musl
|
|
||||||
|
|
||||||
COPY stage/ubuntu-install-packages /
|
|
||||||
RUN /ubuntu-install-packages
|
|
@ -1,5 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
mkdir -p stage
|
|
||||||
cp ../../ubuntu-install-packages ./stage/
|
|
||||||
docker build -t burntsushi/cross:x86_64-unknown-linux-musl .
|
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "grep-cli"
|
name = "grep-cli"
|
||||||
version = "0.1.10" #:version
|
version = "0.1.11" #:version
|
||||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||||
description = """
|
description = """
|
||||||
Utilities for search oriented command line applications.
|
Utilities for search oriented command line applications.
|
||||||
@ -15,7 +15,7 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bstr = { version = "1.6.2", features = ["std"] }
|
bstr = { version = "1.6.2", features = ["std"] }
|
||||||
globset = { version = "0.4.14", path = "../globset" }
|
globset = { version = "0.4.15", path = "../globset" }
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
termcolor = "1.3.0"
|
termcolor = "1.3.0"
|
||||||
|
|
||||||
|
@ -25,10 +25,10 @@ pub fn hostname() -> io::Result<OsString> {
|
|||||||
}
|
}
|
||||||
#[cfg(not(any(windows, unix)))]
|
#[cfg(not(any(windows, unix)))]
|
||||||
{
|
{
|
||||||
io::Error::new(
|
Err(io::Error::new(
|
||||||
io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"hostname could not be found on unsupported platform",
|
"hostname could not be found on unsupported platform",
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,22 +178,71 @@ pub fn is_readable_stdin() -> bool {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let stdin = std::io::stdin();
|
let stdin = std::io::stdin();
|
||||||
let Ok(fd) = stdin.as_fd().try_clone_to_owned() else { return false };
|
let fd = match stdin.as_fd().try_clone_to_owned() {
|
||||||
|
Ok(fd) => fd,
|
||||||
|
Err(err) => {
|
||||||
|
log::debug!(
|
||||||
|
"for heuristic stdin detection on Unix, \
|
||||||
|
could not clone stdin file descriptor \
|
||||||
|
(thus assuming stdin is not readable): {err}",
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
let file = File::from(fd);
|
let file = File::from(fd);
|
||||||
let Ok(md) = file.metadata() else { return false };
|
let md = match file.metadata() {
|
||||||
|
Ok(md) => md,
|
||||||
|
Err(err) => {
|
||||||
|
log::debug!(
|
||||||
|
"for heuristic stdin detection on Unix, \
|
||||||
|
could not get file metadata for stdin \
|
||||||
|
(thus assuming stdin is not readable): {err}",
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
let ft = md.file_type();
|
let ft = md.file_type();
|
||||||
ft.is_file() || ft.is_fifo() || ft.is_socket()
|
let is_file = ft.is_file();
|
||||||
|
let is_fifo = ft.is_fifo();
|
||||||
|
let is_socket = ft.is_socket();
|
||||||
|
let is_readable = is_file || is_fifo || is_socket;
|
||||||
|
log::debug!(
|
||||||
|
"for heuristic stdin detection on Unix, \
|
||||||
|
found that \
|
||||||
|
is_file={is_file}, is_fifo={is_fifo} and is_socket={is_socket}, \
|
||||||
|
and thus concluded that is_stdin_readable={is_readable}",
|
||||||
|
);
|
||||||
|
is_readable
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn imp() -> bool {
|
fn imp() -> bool {
|
||||||
winapi_util::file::typ(winapi_util::HandleRef::stdin())
|
let stdin = winapi_util::HandleRef::stdin();
|
||||||
.map(|t| t.is_disk() || t.is_pipe())
|
let typ = match winapi_util::file::typ(stdin) {
|
||||||
.unwrap_or(false)
|
Ok(typ) => typ,
|
||||||
|
Err(err) => {
|
||||||
|
log::debug!(
|
||||||
|
"for heuristic stdin detection on Windows, \
|
||||||
|
could not get file type of stdin \
|
||||||
|
(thus assuming stdin is not readable): {err}",
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let is_disk = typ.is_disk();
|
||||||
|
let is_pipe = typ.is_pipe();
|
||||||
|
let is_readable = is_disk || is_pipe;
|
||||||
|
log::debug!(
|
||||||
|
"for heuristic stdin detection on Windows, \
|
||||||
|
found that is_disk={is_disk} and is_pipe={is_pipe}, \
|
||||||
|
and thus concluded that is_stdin_readable={is_readable}",
|
||||||
|
);
|
||||||
|
is_readable
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(unix, windows)))]
|
#[cfg(not(any(unix, windows)))]
|
||||||
fn imp() -> bool {
|
fn imp() -> bool {
|
||||||
|
log::debug!("on non-{{Unix,Windows}}, assuming stdin is not readable");
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::io::{self, IsTerminal};
|
use std::io::{self, IsTerminal};
|
||||||
|
|
||||||
use termcolor::{self, HyperlinkSpec};
|
use termcolor::HyperlinkSpec;
|
||||||
|
|
||||||
/// A writer that supports coloring with either line or block buffering.
|
/// A writer that supports coloring with either line or block buffering.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
29
crates/core/flags/complete/encodings.sh
Normal file
29
crates/core/flags/complete/encodings.sh
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# This is impossible to read, but these encodings rarely if ever change, so
|
||||||
|
# it probably does not matter. They are derived from the list given here:
|
||||||
|
# https://encoding.spec.whatwg.org/#concept-encoding-get
|
||||||
|
#
|
||||||
|
# The globbing here works in both fish and zsh (though they expand it in
|
||||||
|
# different orders). It may work in other shells too.
|
||||||
|
|
||||||
|
{{,us-}ascii,arabic,chinese,cyrillic,greek{,8},hebrew,korean}
|
||||||
|
logical visual mac {,cs}macintosh x-mac-{cyrillic,roman,ukrainian}
|
||||||
|
866 ibm{819,866} csibm866
|
||||||
|
big5{,-hkscs} {cn-,cs}big5 x-x-big5
|
||||||
|
cp{819,866,125{0,1,2,3,4,5,6,7,8}} x-cp125{0,1,2,3,4,5,6,7,8}
|
||||||
|
csiso2022{jp,kr} csiso8859{6,8}{e,i}
|
||||||
|
csisolatin{1,2,3,4,5,6,9} csisolatin{arabic,cyrillic,greek,hebrew}
|
||||||
|
ecma-{114,118} asmo-708 elot_928 sun_eu_greek
|
||||||
|
euc-{jp,kr} x-euc-jp cseuckr cseucpkdfmtjapanese
|
||||||
|
{,x-}gbk csiso58gb231280 gb18030 {,cs}gb2312 gb_2312{,-80} hz-gb-2312
|
||||||
|
iso-2022-{cn,cn-ext,jp,kr}
|
||||||
|
iso8859{,-}{1,2,3,4,5,6,7,8,9,10,11,13,14,15}
|
||||||
|
iso-8859-{1,2,3,4,5,6,7,8,9,10,11,{6,8}-{e,i},13,14,15,16} iso_8859-{1,2,3,4,5,6,7,8,9,15}
|
||||||
|
iso_8859-{1,2,6,7}:1987 iso_8859-{3,4,5,8}:1988 iso_8859-9:1989
|
||||||
|
iso-ir-{58,100,101,109,110,126,127,138,144,148,149,157}
|
||||||
|
koi{,8,8-r,8-ru,8-u,8_r} cskoi8r
|
||||||
|
ks_c_5601-{1987,1989} ksc{,_}5691 csksc56011987
|
||||||
|
latin{1,2,3,4,5,6} l{1,2,3,4,5,6,9}
|
||||||
|
shift{-,_}jis csshiftjis {,x-}sjis ms_kanji ms932
|
||||||
|
utf{,-}8 utf-16{,be,le} unicode-1-1-utf-8
|
||||||
|
windows-{31j,874,949,125{0,1,2,3,4,5,6,7,8}} dos-874 tis-620 ansi_x3.4-1968
|
||||||
|
x-user-defined auto none
|
@ -2,17 +2,13 @@
|
|||||||
Provides completions for ripgrep's CLI for the fish shell.
|
Provides completions for ripgrep's CLI for the fish shell.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::flags::defs::FLAGS;
|
use crate::flags::{defs::FLAGS, CompletionType};
|
||||||
|
|
||||||
const TEMPLATE: &'static str =
|
const TEMPLATE: &'static str = "complete -c rg !SHORT! -l !LONG! -d '!DOC!'";
|
||||||
"complete -c rg -n '__fish_use_subcommand' !SHORT! !LONG! !DOC!\n";
|
const TEMPLATE_NEGATED: &'static str =
|
||||||
const TEMPLATE_CHOICES: &'static str =
|
"complete -c rg -l !NEGATED! -n '__fish_contains_opt !SHORT! !LONG!' -d '!DOC!'\n";
|
||||||
"complete -c rg -n '__fish_use_subcommand' !SHORT! !LONG! !DOC! -r -f -a '!CHOICES!'\n";
|
|
||||||
|
|
||||||
/// Generate completions for Fish.
|
/// Generate completions for Fish.
|
||||||
///
|
|
||||||
/// Note that these completions are based on what was produced for ripgrep <=13
|
|
||||||
/// using Clap 2.x. Improvements on this are welcome.
|
|
||||||
pub(crate) fn generate() -> String {
|
pub(crate) fn generate() -> String {
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
for flag in FLAGS.iter() {
|
for flag in FLAGS.iter() {
|
||||||
@ -20,25 +16,50 @@ pub(crate) fn generate() -> String {
|
|||||||
None => "".to_string(),
|
None => "".to_string(),
|
||||||
Some(byte) => format!("-s {}", char::from(byte)),
|
Some(byte) => format!("-s {}", char::from(byte)),
|
||||||
};
|
};
|
||||||
let long = format!("-l '{}'", flag.name_long().replace("'", "\\'"));
|
let long = flag.name_long();
|
||||||
let doc = format!("-d '{}'", flag.doc_short().replace("'", "\\'"));
|
let doc = flag.doc_short().replace("'", "\\'");
|
||||||
let template = if flag.doc_choices().is_empty() {
|
let mut completion = TEMPLATE
|
||||||
TEMPLATE.to_string()
|
|
||||||
} else {
|
|
||||||
TEMPLATE_CHOICES
|
|
||||||
.replace("!CHOICES!", &flag.doc_choices().join(" "))
|
|
||||||
};
|
|
||||||
out.push_str(
|
|
||||||
&template
|
|
||||||
.replace("!SHORT!", &short)
|
.replace("!SHORT!", &short)
|
||||||
.replace("!LONG!", &long)
|
.replace("!LONG!", &long)
|
||||||
.replace("!DOC!", &doc),
|
.replace("!DOC!", &doc);
|
||||||
|
|
||||||
|
match flag.completion_type() {
|
||||||
|
CompletionType::Filename => {
|
||||||
|
completion.push_str(" -r -F");
|
||||||
|
}
|
||||||
|
CompletionType::Executable => {
|
||||||
|
completion.push_str(" -r -f -a '(__fish_complete_command)'");
|
||||||
|
}
|
||||||
|
CompletionType::Filetype => {
|
||||||
|
completion.push_str(
|
||||||
|
" -r -f -a '(rg --type-list | string replace : \\t)'",
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
CompletionType::Encoding => {
|
||||||
|
completion.push_str(" -r -f -a '");
|
||||||
|
completion.push_str(super::ENCODINGS);
|
||||||
|
completion.push_str("'");
|
||||||
|
}
|
||||||
|
CompletionType::Other if !flag.doc_choices().is_empty() => {
|
||||||
|
completion.push_str(" -r -f -a '");
|
||||||
|
completion.push_str(&flag.doc_choices().join(" "));
|
||||||
|
completion.push_str("'");
|
||||||
|
}
|
||||||
|
CompletionType::Other if !flag.is_switch() => {
|
||||||
|
completion.push_str(" -r -f");
|
||||||
|
}
|
||||||
|
CompletionType::Other => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
completion.push('\n');
|
||||||
|
out.push_str(&completion);
|
||||||
|
|
||||||
if let Some(negated) = flag.name_negated() {
|
if let Some(negated) = flag.name_negated() {
|
||||||
out.push_str(
|
out.push_str(
|
||||||
&template
|
&TEMPLATE_NEGATED
|
||||||
.replace("!SHORT!", "")
|
.replace("!NEGATED!", &negated)
|
||||||
.replace("!LONG!", &negated)
|
.replace("!SHORT!", &short)
|
||||||
|
.replace("!LONG!", &long)
|
||||||
.replace("!DOC!", &doc),
|
.replace("!DOC!", &doc),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
Modules for generating completions for various shells.
|
Modules for generating completions for various shells.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static ENCODINGS: &'static str = include_str!("encodings.sh");
|
||||||
|
|
||||||
pub(super) mod bash;
|
pub(super) mod bash;
|
||||||
pub(super) mod fish;
|
pub(super) mod fish;
|
||||||
pub(super) mod powershell;
|
pub(super) mod powershell;
|
||||||
|
@ -413,32 +413,8 @@ _rg_encodings() {
|
|||||||
local -a expl
|
local -a expl
|
||||||
local -aU _encodings
|
local -aU _encodings
|
||||||
|
|
||||||
# This is impossible to read, but these encodings rarely if ever change, so it
|
|
||||||
# probably doesn't matter. They are derived from the list given here:
|
|
||||||
# https://encoding.spec.whatwg.org/#concept-encoding-get
|
|
||||||
_encodings=(
|
_encodings=(
|
||||||
{{,us-}ascii,arabic,chinese,cyrillic,greek{,8},hebrew,korean}
|
!ENCODINGS!
|
||||||
logical visual mac {,cs}macintosh x-mac-{cyrillic,roman,ukrainian}
|
|
||||||
866 ibm{819,866} csibm866
|
|
||||||
big5{,-hkscs} {cn-,cs}big5 x-x-big5
|
|
||||||
cp{819,866,125{0..8}} x-cp125{0..8}
|
|
||||||
csiso2022{jp,kr} csiso8859{6,8}{e,i}
|
|
||||||
csisolatin{{1..6},9} csisolatin{arabic,cyrillic,greek,hebrew}
|
|
||||||
ecma-{114,118} asmo-708 elot_928 sun_eu_greek
|
|
||||||
euc-{jp,kr} x-euc-jp cseuckr cseucpkdfmtjapanese
|
|
||||||
{,x-}gbk csiso58gb231280 gb18030 {,cs}gb2312 gb_2312{,-80} hz-gb-2312
|
|
||||||
iso-2022-{cn,cn-ext,jp,kr}
|
|
||||||
iso8859{,-}{{1..11},13,14,15}
|
|
||||||
iso-8859-{{1..11},{6,8}-{e,i},13,14,15,16} iso_8859-{{1..9},15}
|
|
||||||
iso_8859-{1,2,6,7}:1987 iso_8859-{3,4,5,8}:1988 iso_8859-9:1989
|
|
||||||
iso-ir-{58,100,101,109,110,126,127,138,144,148,149,157}
|
|
||||||
koi{,8,8-r,8-ru,8-u,8_r} cskoi8r
|
|
||||||
ks_c_5601-{1987,1989} ksc{,_}5691 csksc56011987
|
|
||||||
latin{1..6} l{{1..6},9}
|
|
||||||
shift{-,_}jis csshiftjis {,x-}sjis ms_kanji ms932
|
|
||||||
utf{,-}8 utf-16{,be,le} unicode-1-1-utf-8
|
|
||||||
windows-{31j,874,949,125{0..8}} dos-874 tis-620 ansi_x3.4-1968
|
|
||||||
x-user-defined auto none
|
|
||||||
)
|
)
|
||||||
|
|
||||||
_wanted encodings expl encoding compadd -a "$@" - _encodings
|
_wanted encodings expl encoding compadd -a "$@" - _encodings
|
||||||
@ -458,7 +434,15 @@ _rg_types() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
_rg "$@"
|
# Don't run the completion function when being sourced by itself.
|
||||||
|
#
|
||||||
|
# See https://github.com/BurntSushi/ripgrep/issues/2956
|
||||||
|
# See https://github.com/BurntSushi/ripgrep/pull/2957
|
||||||
|
if [[ $funcstack[1] == _rg ]] || (( ! $+functions[compdef] )); then
|
||||||
|
_rg "$@"
|
||||||
|
else
|
||||||
|
compdef _rg rg
|
||||||
|
fi
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# ZSH COMPLETION REFERENCE
|
# ZSH COMPLETION REFERENCE
|
||||||
|
@ -19,5 +19,5 @@ long as it meets criteria 3 and 4 above.
|
|||||||
|
|
||||||
/// Generate completions for zsh.
|
/// Generate completions for zsh.
|
||||||
pub(crate) fn generate() -> String {
|
pub(crate) fn generate() -> String {
|
||||||
include_str!("rg.zsh").to_string()
|
include_str!("rg.zsh").replace("!ENCODINGS!", super::ENCODINGS.trim_end())
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,8 @@ use crate::flags::{
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use crate::flags::parse::parse_low_raw;
|
use crate::flags::parse::parse_low_raw;
|
||||||
|
|
||||||
|
use super::CompletionType;
|
||||||
|
|
||||||
/// A list of all flags in ripgrep via implementations of `Flag`.
|
/// A list of all flags in ripgrep via implementations of `Flag`.
|
||||||
///
|
///
|
||||||
/// The order of these flags matter. It determines the order of the flags in
|
/// The order of these flags matter. It determines the order of the flags in
|
||||||
@ -1582,6 +1584,9 @@ The encoding detection that ripgrep uses can be reverted to its automatic mode
|
|||||||
via the \flag-negate{encoding} flag.
|
via the \flag-negate{encoding} flag.
|
||||||
"
|
"
|
||||||
}
|
}
|
||||||
|
fn completion_type(&self) -> CompletionType {
|
||||||
|
CompletionType::Encoding
|
||||||
|
}
|
||||||
|
|
||||||
fn update(&self, v: FlagValue, args: &mut LowArgs) -> anyhow::Result<()> {
|
fn update(&self, v: FlagValue, args: &mut LowArgs) -> anyhow::Result<()> {
|
||||||
let value = match v {
|
let value = match v {
|
||||||
@ -1977,6 +1982,9 @@ When \flag{file} or \flag{regexp} is used, then ripgrep treats all positional
|
|||||||
arguments as files or directories to search.
|
arguments as files or directories to search.
|
||||||
"
|
"
|
||||||
}
|
}
|
||||||
|
fn completion_type(&self) -> CompletionType {
|
||||||
|
CompletionType::Filename
|
||||||
|
}
|
||||||
|
|
||||||
fn update(&self, v: FlagValue, args: &mut LowArgs) -> anyhow::Result<()> {
|
fn update(&self, v: FlagValue, args: &mut LowArgs) -> anyhow::Result<()> {
|
||||||
let path = PathBuf::from(v.unwrap_value());
|
let path = PathBuf::from(v.unwrap_value());
|
||||||
@ -2619,7 +2627,7 @@ of printing the file path as a prefix for each matched line.
|
|||||||
This is the default mode when printing to a tty.
|
This is the default mode when printing to a tty.
|
||||||
.sp
|
.sp
|
||||||
When \fBstdout\fP is not a tty, then ripgrep will default to the standard
|
When \fBstdout\fP is not a tty, then ripgrep will default to the standard
|
||||||
grep-like format. Once can force this format in Unix-like environments by
|
grep-like format. One can force this format in Unix-like environments by
|
||||||
piping the output of ripgrep to \fBcat\fP. For example, \fBrg\fP \fIfoo\fP \fB|
|
piping the output of ripgrep to \fBcat\fP. For example, \fBrg\fP \fIfoo\fP \fB|
|
||||||
cat\fP.
|
cat\fP.
|
||||||
"
|
"
|
||||||
@ -2738,7 +2746,7 @@ impl Flag for Hidden {
|
|||||||
Search hidden files and directories. By default, hidden files and directories
|
Search hidden files and directories. By default, hidden files and directories
|
||||||
are skipped. Note that if a hidden file or a directory is whitelisted in
|
are skipped. Note that if a hidden file or a directory is whitelisted in
|
||||||
an ignore file, then it will be searched even if this flag isn't provided.
|
an ignore file, then it will be searched even if this flag isn't provided.
|
||||||
Similarly if a hidden file or directory is given explicitly as an argumnet to
|
Similarly if a hidden file or directory is given explicitly as an argument to
|
||||||
ripgrep.
|
ripgrep.
|
||||||
.sp
|
.sp
|
||||||
A file or directory is considered hidden if its base name starts with a dot
|
A file or directory is considered hidden if its base name starts with a dot
|
||||||
@ -2808,6 +2816,9 @@ to calling \fBgethostname\fP. On Windows, this corresponds to calling
|
|||||||
ripgrep uses your system's hostname for producing hyperlinks.
|
ripgrep uses your system's hostname for producing hyperlinks.
|
||||||
"#
|
"#
|
||||||
}
|
}
|
||||||
|
fn completion_type(&self) -> CompletionType {
|
||||||
|
CompletionType::Executable
|
||||||
|
}
|
||||||
|
|
||||||
fn update(&self, v: FlagValue, args: &mut LowArgs) -> anyhow::Result<()> {
|
fn update(&self, v: FlagValue, args: &mut LowArgs) -> anyhow::Result<()> {
|
||||||
let path = PathBuf::from(v.unwrap_value());
|
let path = PathBuf::from(v.unwrap_value());
|
||||||
@ -3078,7 +3089,7 @@ Individual patterns can still be matched case sensitively by using
|
|||||||
inline regex flags. For example, \fB(?\-i)abc\fP will match \fBabc\fP
|
inline regex flags. For example, \fB(?\-i)abc\fP will match \fBabc\fP
|
||||||
case sensitively even when this flag is used.
|
case sensitively even when this flag is used.
|
||||||
.sp
|
.sp
|
||||||
This flag overrides \flag{case-sensitive} and flag{smart-case}.
|
This flag overrides \flag{case-sensitive} and \flag{smart-case}.
|
||||||
"#
|
"#
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3141,6 +3152,9 @@ If you are looking for a way to include or exclude files and directories
|
|||||||
directly on the command line, then use \flag{glob} instead.
|
directly on the command line, then use \flag{glob} instead.
|
||||||
"
|
"
|
||||||
}
|
}
|
||||||
|
fn completion_type(&self) -> CompletionType {
|
||||||
|
CompletionType::Filename
|
||||||
|
}
|
||||||
|
|
||||||
fn update(&self, v: FlagValue, args: &mut LowArgs) -> anyhow::Result<()> {
|
fn update(&self, v: FlagValue, args: &mut LowArgs) -> anyhow::Result<()> {
|
||||||
let path = PathBuf::from(v.unwrap_value());
|
let path = PathBuf::from(v.unwrap_value());
|
||||||
@ -5410,6 +5424,9 @@ format, then \fBpzstd\fP is used to decompress the contents to stdout.
|
|||||||
This overrides the \flag{search-zip} flag.
|
This overrides the \flag{search-zip} flag.
|
||||||
"#
|
"#
|
||||||
}
|
}
|
||||||
|
fn completion_type(&self) -> CompletionType {
|
||||||
|
CompletionType::Executable
|
||||||
|
}
|
||||||
|
|
||||||
fn update(&self, v: FlagValue, args: &mut LowArgs) -> anyhow::Result<()> {
|
fn update(&self, v: FlagValue, args: &mut LowArgs) -> anyhow::Result<()> {
|
||||||
let path = match v {
|
let path = match v {
|
||||||
@ -6781,6 +6798,9 @@ any rules found in ignore files.
|
|||||||
To see the list of available file types, use the \flag{type-list} flag.
|
To see the list of available file types, use the \flag{type-list} flag.
|
||||||
"#
|
"#
|
||||||
}
|
}
|
||||||
|
fn completion_type(&self) -> CompletionType {
|
||||||
|
CompletionType::Filetype
|
||||||
|
}
|
||||||
|
|
||||||
fn update(&self, v: FlagValue, args: &mut LowArgs) -> anyhow::Result<()> {
|
fn update(&self, v: FlagValue, args: &mut LowArgs) -> anyhow::Result<()> {
|
||||||
args.type_changes.push(TypeChange::Select {
|
args.type_changes.push(TypeChange::Select {
|
||||||
@ -7000,6 +7020,9 @@ will only search files that are unrecognized by its type definitions.
|
|||||||
To see the list of available file types, use the \flag{type-list} flag.
|
To see the list of available file types, use the \flag{type-list} flag.
|
||||||
"#
|
"#
|
||||||
}
|
}
|
||||||
|
fn completion_type(&self) -> CompletionType {
|
||||||
|
CompletionType::Filetype
|
||||||
|
}
|
||||||
|
|
||||||
fn update(&self, v: FlagValue, args: &mut LowArgs) -> anyhow::Result<()> {
|
fn update(&self, v: FlagValue, args: &mut LowArgs) -> anyhow::Result<()> {
|
||||||
args.type_changes.push(TypeChange::Negate {
|
args.type_changes.push(TypeChange::Negate {
|
||||||
@ -7238,7 +7261,7 @@ impl Flag for Vimgrep {
|
|||||||
Category::Output
|
Category::Output
|
||||||
}
|
}
|
||||||
fn doc_short(&self) -> &'static str {
|
fn doc_short(&self) -> &'static str {
|
||||||
r"Print results im a vim compatible format."
|
r"Print results in a vim compatible format."
|
||||||
}
|
}
|
||||||
fn doc_long(&self) -> &'static str {
|
fn doc_long(&self) -> &'static str {
|
||||||
r"
|
r"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.TH RG 1 2023-11-26 "!!VERSION!!" "User Commands"
|
.TH RG 1 2024-09-08 "!!VERSION!!" "User Commands"
|
||||||
.
|
.
|
||||||
.
|
.
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@ -43,10 +43,10 @@ configuration file. The file can specify one shell argument per line. Lines
|
|||||||
starting with \fB#\fP are ignored. For more details, see \fBCONFIGURATION
|
starting with \fB#\fP are ignored. For more details, see \fBCONFIGURATION
|
||||||
FILES\fP below.
|
FILES\fP below.
|
||||||
.sp
|
.sp
|
||||||
ripgrep will automatically detect if stdin exists and search stdin for a regex
|
ripgrep will automatically detect if stdin is a readable file and search stdin
|
||||||
pattern, e.g. \fBls | rg foo\fP. In some environments, stdin may exist when
|
for a regex pattern, e.g. \fBls | rg foo\fP. In some environments, stdin may
|
||||||
it shouldn't. To turn off stdin detection, one can explicitly specify the
|
exist when it shouldn't. To turn off stdin detection, one can explicitly
|
||||||
directory to search, e.g. \fBrg foo ./\fP.
|
specify the directory to search, e.g. \fBrg foo ./\fP.
|
||||||
.sp
|
.sp
|
||||||
Like other tools such as \fBls\fP, ripgrep will alter its output depending on
|
Like other tools such as \fBls\fP, ripgrep will alter its output depending on
|
||||||
whether stdout is connected to a tty. By default, when printing a tty, ripgrep
|
whether stdout is connected to a tty. By default, when printing a tty, ripgrep
|
||||||
|
@ -161,9 +161,6 @@ fn compile_cpu_features() -> Vec<String> {
|
|||||||
fn features() -> Vec<String> {
|
fn features() -> Vec<String> {
|
||||||
let mut features = vec![];
|
let mut features = vec![];
|
||||||
|
|
||||||
let simd_accel = cfg!(feature = "simd-accel");
|
|
||||||
features.push(format!("{sign}simd-accel", sign = sign(simd_accel)));
|
|
||||||
|
|
||||||
let pcre2 = cfg!(feature = "pcre2");
|
let pcre2 = cfg!(feature = "pcre2");
|
||||||
features.push(format!("{sign}pcre2", sign = sign(pcre2)));
|
features.push(format!("{sign}pcre2", sign = sign(pcre2)));
|
||||||
|
|
||||||
|
@ -484,9 +484,9 @@ impl HiArgs {
|
|||||||
if self.crlf {
|
if self.crlf {
|
||||||
builder.crlf(true);
|
builder.crlf(true);
|
||||||
}
|
}
|
||||||
// We don't need to set this in multiline mode since mulitline
|
// We don't need to set this in multiline mode since multiline
|
||||||
// matchers don't use optimizations related to line terminators.
|
// matchers don't use optimizations related to line terminators.
|
||||||
// Moreover, a mulitline regex used with --null-data should
|
// Moreover, a multiline regex used with --null-data should
|
||||||
// be allowed to match NUL bytes explicitly, which this would
|
// be allowed to match NUL bytes explicitly, which this would
|
||||||
// otherwise forbid.
|
// otherwise forbid.
|
||||||
if self.null_data {
|
if self.null_data {
|
||||||
@ -771,7 +771,13 @@ impl HiArgs {
|
|||||||
let Some(ref sort) = self.sort else { return Box::new(haystacks) };
|
let Some(ref sort) = self.sort else { return Box::new(haystacks) };
|
||||||
let mut with_timestamps: Vec<_> = match sort.kind {
|
let mut with_timestamps: Vec<_> = match sort.kind {
|
||||||
SortModeKind::Path if !sort.reverse => return Box::new(haystacks),
|
SortModeKind::Path if !sort.reverse => return Box::new(haystacks),
|
||||||
SortModeKind::Path => todo!(),
|
SortModeKind::Path => {
|
||||||
|
let mut haystacks = haystacks.collect::<Vec<Haystack>>();
|
||||||
|
haystacks.sort_by(|ref h1, ref h2| {
|
||||||
|
h1.path().cmp(h2.path()).reverse()
|
||||||
|
});
|
||||||
|
return Box::new(haystacks.into_iter());
|
||||||
|
}
|
||||||
SortModeKind::LastModified => {
|
SortModeKind::LastModified => {
|
||||||
attach_timestamps(haystacks, |md| md.modified()).collect()
|
attach_timestamps(haystacks, |md| md.modified()).collect()
|
||||||
}
|
}
|
||||||
@ -1074,9 +1080,18 @@ impl Paths {
|
|||||||
}
|
}
|
||||||
paths.push(path);
|
paths.push(path);
|
||||||
}
|
}
|
||||||
|
log::debug!("number of paths given to search: {}", paths.len());
|
||||||
if !paths.is_empty() {
|
if !paths.is_empty() {
|
||||||
let is_one_file = paths.len() == 1
|
let is_one_file = paths.len() == 1
|
||||||
&& (paths[0] == Path::new("-") || paths[0].is_file());
|
// Note that we specifically use `!paths[0].is_dir()` here
|
||||||
|
// instead of `paths[0].is_file()`. Namely, the latter can
|
||||||
|
// return `false` even when the path is something resembling
|
||||||
|
// a file. So instead, we just consider the path a file as
|
||||||
|
// long as we know it isn't a directory.
|
||||||
|
//
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/issues/2736
|
||||||
|
&& (paths[0] == Path::new("-") || !paths[0].is_dir());
|
||||||
|
log::debug!("is_one_file? {is_one_file:?}");
|
||||||
return Ok(Paths { paths, has_implicit_path: false, is_one_file });
|
return Ok(Paths { paths, has_implicit_path: false, is_one_file });
|
||||||
}
|
}
|
||||||
// N.B. is_readable_stdin is a heuristic! Part of the issue is that a
|
// N.B. is_readable_stdin is a heuristic! Part of the issue is that a
|
||||||
|
@ -70,7 +70,7 @@ mod parse;
|
|||||||
/// value. Flags that accept multiple values are an unsupported abberation.
|
/// value. Flags that accept multiple values are an unsupported abberation.
|
||||||
trait Flag: Debug + Send + Sync + UnwindSafe + RefUnwindSafe + 'static {
|
trait Flag: Debug + Send + Sync + UnwindSafe + RefUnwindSafe + 'static {
|
||||||
/// Returns true if this flag is a switch. When a flag is a switch, the
|
/// Returns true if this flag is a switch. When a flag is a switch, the
|
||||||
/// CLI parser will look for a value after the flag is seen.
|
/// CLI parser will not look for a value after the flag is seen.
|
||||||
fn is_switch(&self) -> bool;
|
fn is_switch(&self) -> bool;
|
||||||
|
|
||||||
/// A short single byte name for this flag. This returns `None` by default,
|
/// A short single byte name for this flag. This returns `None` by default,
|
||||||
@ -150,6 +150,10 @@ trait Flag: Debug + Send + Sync + UnwindSafe + RefUnwindSafe + 'static {
|
|||||||
&[]
|
&[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn completion_type(&self) -> CompletionType {
|
||||||
|
CompletionType::Other
|
||||||
|
}
|
||||||
|
|
||||||
/// Given the parsed value (which might just be a switch), this should
|
/// Given the parsed value (which might just be a switch), this should
|
||||||
/// update the state in `args` based on the value given for this flag.
|
/// update the state in `args` based on the value given for this flag.
|
||||||
///
|
///
|
||||||
@ -228,6 +232,21 @@ impl Category {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The kind of argument a flag accepts, to be used for shell completions.
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
enum CompletionType {
|
||||||
|
/// No special category. is_switch() and doc_choices() may apply.
|
||||||
|
Other,
|
||||||
|
/// A path to a file.
|
||||||
|
Filename,
|
||||||
|
/// A command in $PATH.
|
||||||
|
Executable,
|
||||||
|
/// The name of a file type, as used by e.g. --type.
|
||||||
|
Filetype,
|
||||||
|
/// The name of an encoding_rs encoding, as used by --encoding.
|
||||||
|
Encoding,
|
||||||
|
}
|
||||||
|
|
||||||
/// Represents a value parsed from the command line.
|
/// Represents a value parsed from the command line.
|
||||||
///
|
///
|
||||||
/// This doesn't include the corresponding flag, but values come in one of
|
/// This doesn't include the corresponding flag, but values come in one of
|
||||||
|
@ -323,7 +323,7 @@ enum FlagLookup<'a> {
|
|||||||
UnrecognizedLong(String),
|
UnrecognizedLong(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The info about a flag associated with a flag's ID in the the flag map.
|
/// The info about a flag associated with a flag's ID in the flag map.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct FlagInfo {
|
struct FlagInfo {
|
||||||
/// The flag object and its associated metadata.
|
/// The flag object and its associated metadata.
|
||||||
|
@ -6,7 +6,7 @@ print to stderr. We therefore avoid bringing in extra dependencies just for
|
|||||||
this functionality.
|
this functionality.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use log::{self, Log};
|
use log::Log;
|
||||||
|
|
||||||
/// The simplest possible logger that logs to stderr.
|
/// The simplest possible logger that logs to stderr.
|
||||||
///
|
///
|
||||||
|
@ -28,7 +28,7 @@ static ERRORED: AtomicBool = AtomicBool::new(false);
|
|||||||
///
|
///
|
||||||
/// This locks stdout, not stderr, even though this prints to stderr. This
|
/// This locks stdout, not stderr, even though this prints to stderr. This
|
||||||
/// avoids the appearance of interleaving output when stdout and stderr both
|
/// avoids the appearance of interleaving output when stdout and stderr both
|
||||||
/// correspond to a tty.)
|
/// correspond to a tty.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! eprintln_locked {
|
macro_rules! eprintln_locked {
|
||||||
($($tt:tt)*) => {{
|
($($tt:tt)*) => {{
|
||||||
@ -39,21 +39,29 @@ macro_rules! eprintln_locked {
|
|||||||
// lock stdout before printing to stderr. This avoids interleaving
|
// lock stdout before printing to stderr. This avoids interleaving
|
||||||
// lines within ripgrep because `search_parallel` uses `termcolor`,
|
// lines within ripgrep because `search_parallel` uses `termcolor`,
|
||||||
// which accesses the same stdout lock when writing lines.
|
// which accesses the same stdout lock when writing lines.
|
||||||
let stdout = std::io::stdout();
|
let stdout = std::io::stdout().lock();
|
||||||
let _handle = stdout.lock();
|
let mut stderr = std::io::stderr().lock();
|
||||||
// We specifically ignore any errors here. One plausible error we
|
// We specifically ignore any errors here. One plausible error we
|
||||||
// can get in some cases is a broken pipe error. And when that
|
// can get in some cases is a broken pipe error. And when that
|
||||||
// occurs, we should exit gracefully. Otherwise, just abort with
|
// occurs, we should exit gracefully. Otherwise, just abort with
|
||||||
// an error code because there isn't much else we can do.
|
// an error code because there isn't much else we can do.
|
||||||
//
|
//
|
||||||
// See: https://github.com/BurntSushi/ripgrep/issues/1966
|
// See: https://github.com/BurntSushi/ripgrep/issues/1966
|
||||||
if let Err(err) = writeln!(std::io::stderr(), $($tt)*) {
|
if let Err(err) = write!(stderr, "rg: ") {
|
||||||
if err.kind() == std::io::ErrorKind::BrokenPipe {
|
if err.kind() == std::io::ErrorKind::BrokenPipe {
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
} else {
|
} else {
|
||||||
std::process::exit(2);
|
std::process::exit(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Err(err) = writeln!(stderr, $($tt)*) {
|
||||||
|
if err.kind() == std::io::ErrorKind::BrokenPipe {
|
||||||
|
std::process::exit(0);
|
||||||
|
} else {
|
||||||
|
std::process::exit(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
drop(stdout);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "globset"
|
name = "globset"
|
||||||
version = "0.4.14" #:version
|
version = "0.4.16" #:version
|
||||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||||
description = """
|
description = """
|
||||||
Cross platform single glob and glob set matching. Glob set matching is the
|
Cross platform single glob and glob set matching. Glob set matching is the
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use std::fmt::Write;
|
||||||
use std::path::{is_separator, Path};
|
use std::path::{is_separator, Path};
|
||||||
|
|
||||||
use regex_automata::meta::Regex;
|
use regex_automata::meta::Regex;
|
||||||
@ -732,7 +733,9 @@ impl Tokens {
|
|||||||
/// Convert a Unicode scalar value to an escaped string suitable for use as
|
/// Convert a Unicode scalar value to an escaped string suitable for use as
|
||||||
/// a literal in a non-Unicode regex.
|
/// a literal in a non-Unicode regex.
|
||||||
fn char_to_escaped_literal(c: char) -> String {
|
fn char_to_escaped_literal(c: char) -> String {
|
||||||
bytes_to_escaped_literal(&c.to_string().into_bytes())
|
let mut buf = [0; 4];
|
||||||
|
let bytes = c.encode_utf8(&mut buf).as_bytes();
|
||||||
|
bytes_to_escaped_literal(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts an arbitrary sequence of bytes to a UTF-8 string. All non-ASCII
|
/// Converts an arbitrary sequence of bytes to a UTF-8 string. All non-ASCII
|
||||||
@ -741,11 +744,12 @@ fn bytes_to_escaped_literal(bs: &[u8]) -> String {
|
|||||||
let mut s = String::with_capacity(bs.len());
|
let mut s = String::with_capacity(bs.len());
|
||||||
for &b in bs {
|
for &b in bs {
|
||||||
if b <= 0x7F {
|
if b <= 0x7F {
|
||||||
s.push_str(®ex_syntax::escape(
|
regex_syntax::escape_into(
|
||||||
char::from(b).encode_utf8(&mut [0; 4]),
|
char::from(b).encode_utf8(&mut [0; 4]),
|
||||||
));
|
&mut s,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
s.push_str(&format!("\\x{:02x}", b));
|
write!(&mut s, "\\x{:02x}", b).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s
|
s
|
||||||
|
@ -928,13 +928,26 @@ impl RequiredExtensionStrategyBuilder {
|
|||||||
///
|
///
|
||||||
/// The escaping works by surrounding meta-characters with brackets. For
|
/// The escaping works by surrounding meta-characters with brackets. For
|
||||||
/// example, `*` becomes `[*]`.
|
/// example, `*` becomes `[*]`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use globset::escape;
|
||||||
|
///
|
||||||
|
/// assert_eq!(escape("foo*bar"), "foo[*]bar");
|
||||||
|
/// assert_eq!(escape("foo?bar"), "foo[?]bar");
|
||||||
|
/// assert_eq!(escape("foo[bar"), "foo[[]bar");
|
||||||
|
/// assert_eq!(escape("foo]bar"), "foo[]]bar");
|
||||||
|
/// assert_eq!(escape("foo{bar"), "foo[{]bar");
|
||||||
|
/// assert_eq!(escape("foo}bar"), "foo[}]bar");
|
||||||
|
/// ```
|
||||||
pub fn escape(s: &str) -> String {
|
pub fn escape(s: &str) -> String {
|
||||||
let mut escaped = String::with_capacity(s.len());
|
let mut escaped = String::with_capacity(s.len());
|
||||||
for c in s.chars() {
|
for c in s.chars() {
|
||||||
match c {
|
match c {
|
||||||
// note that ! does not need escaping because it is only special
|
// note that ! does not need escaping because it is only special
|
||||||
// inside brackets
|
// inside brackets
|
||||||
'?' | '*' | '[' | ']' => {
|
'?' | '*' | '[' | ']' | '{' | '}' => {
|
||||||
escaped.push('[');
|
escaped.push('[');
|
||||||
escaped.push(c);
|
escaped.push(c);
|
||||||
escaped.push(']');
|
escaped.push(']');
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "grep"
|
name = "grep"
|
||||||
version = "0.3.0" #:version
|
version = "0.3.2" #:version
|
||||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||||
description = """
|
description = """
|
||||||
Fast line oriented regex searching as a library.
|
Fast line oriented regex searching as a library.
|
||||||
@ -14,20 +14,20 @@ license = "Unlicense OR MIT"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
grep-cli = { version = "0.1.10", path = "../cli" }
|
grep-cli = { version = "0.1.11", path = "../cli" }
|
||||||
grep-matcher = { version = "0.1.7", path = "../matcher" }
|
grep-matcher = { version = "0.1.7", path = "../matcher" }
|
||||||
grep-pcre2 = { version = "0.1.7", path = "../pcre2", optional = true }
|
grep-pcre2 = { version = "0.1.8", path = "../pcre2", optional = true }
|
||||||
grep-printer = { version = "0.2.0", path = "../printer" }
|
grep-printer = { version = "0.2.2", path = "../printer" }
|
||||||
grep-regex = { version = "0.1.12", path = "../regex" }
|
grep-regex = { version = "0.1.13", path = "../regex" }
|
||||||
grep-searcher = { version = "0.1.12", path = "../searcher" }
|
grep-searcher = { version = "0.1.14", path = "../searcher" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
termcolor = "1.0.4"
|
termcolor = "1.0.4"
|
||||||
walkdir = "2.2.7"
|
walkdir = "2.2.7"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
simd-accel = ["grep-searcher/simd-accel"]
|
|
||||||
pcre2 = ["grep-pcre2"]
|
pcre2 = ["grep-pcre2"]
|
||||||
|
|
||||||
# This feature is DEPRECATED. Runtime dispatch is used for SIMD now.
|
# These features are DEPRECATED. Runtime dispatch is used for SIMD now.
|
||||||
|
simd-accel = []
|
||||||
avx-accel = []
|
avx-accel = []
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ignore"
|
name = "ignore"
|
||||||
version = "0.4.21" #:version
|
version = "0.4.23" #: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`
|
||||||
@ -20,7 +20,7 @@ bench = false
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
crossbeam-deque = "0.8.3"
|
crossbeam-deque = "0.8.3"
|
||||||
globset = { version = "0.4.14", path = "../globset" }
|
globset = { version = "0.4.15", path = "../globset" }
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
memchr = "2.6.3"
|
memchr = "2.6.3"
|
||||||
same-file = "1.0.6"
|
same-file = "1.0.6"
|
||||||
@ -36,7 +36,7 @@ version = "0.1.2"
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
bstr = { version = "1.6.2", default-features = false, features = ["std"] }
|
bstr = { version = "1.6.2", default-features = false, features = ["std"] }
|
||||||
crossbeam-channel = "0.5.8"
|
crossbeam-channel = "0.5.15"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# DEPRECATED. It is a no-op. SIMD is done automatically through runtime
|
# DEPRECATED. It is a no-op. SIMD is done automatically through runtime
|
||||||
|
@ -118,6 +118,7 @@ pub(crate) const DEFAULT_TYPES: &[(&[&str], &[&str])] = &[
|
|||||||
(&["jupyter"], &["*.ipynb", "*.jpynb"]),
|
(&["jupyter"], &["*.ipynb", "*.jpynb"]),
|
||||||
(&["k"], &["*.k"]),
|
(&["k"], &["*.k"]),
|
||||||
(&["kotlin"], &["*.kt", "*.kts"]),
|
(&["kotlin"], &["*.kt", "*.kts"]),
|
||||||
|
(&["lean"], &["*.lean"]),
|
||||||
(&["less"], &["*.less"]),
|
(&["less"], &["*.less"]),
|
||||||
(&["license"], &[
|
(&["license"], &[
|
||||||
// General
|
// General
|
||||||
@ -172,7 +173,7 @@ pub(crate) const DEFAULT_TYPES: &[(&[&str], &[&str])] = &[
|
|||||||
"*.mdx",
|
"*.mdx",
|
||||||
]),
|
]),
|
||||||
(&["matlab"], &["*.m"]),
|
(&["matlab"], &["*.m"]),
|
||||||
(&["meson"], &["meson.build", "meson_options.txt"]),
|
(&["meson"], &["meson.build", "meson_options.txt", "meson.options"]),
|
||||||
(&["minified"], &["*.min.html", "*.min.css", "*.min.js"]),
|
(&["minified"], &["*.min.html", "*.min.css", "*.min.js"]),
|
||||||
(&["mint"], &["*.mint"]),
|
(&["mint"], &["*.mint"]),
|
||||||
(&["mk"], &["mkfile"]),
|
(&["mk"], &["mkfile"]),
|
||||||
@ -231,6 +232,7 @@ pub(crate) const DEFAULT_TYPES: &[(&[&str], &[&str])] = &[
|
|||||||
(&["rust"], &["*.rs"]),
|
(&["rust"], &["*.rs"]),
|
||||||
(&["sass"], &["*.sass", "*.scss"]),
|
(&["sass"], &["*.sass", "*.scss"]),
|
||||||
(&["scala"], &["*.scala", "*.sbt"]),
|
(&["scala"], &["*.scala", "*.sbt"]),
|
||||||
|
(&["seed7"], &["*.sd7", "*.s7i"]),
|
||||||
(&["sh"], &[
|
(&["sh"], &[
|
||||||
// Portable/misc. init files
|
// Portable/misc. init files
|
||||||
".login", ".logout", ".profile", "profile",
|
".login", ".logout", ".profile", "profile",
|
||||||
@ -264,6 +266,7 @@ pub(crate) const DEFAULT_TYPES: &[(&[&str], &[&str])] = &[
|
|||||||
(&["sql"], &["*.sql", "*.psql"]),
|
(&["sql"], &["*.sql", "*.psql"]),
|
||||||
(&["stylus"], &["*.styl"]),
|
(&["stylus"], &["*.styl"]),
|
||||||
(&["sv"], &["*.v", "*.vg", "*.sv", "*.svh", "*.h"]),
|
(&["sv"], &["*.v", "*.vg", "*.sv", "*.svh", "*.h"]),
|
||||||
|
(&["svelte"], &["*.svelte"]),
|
||||||
(&["svg"], &["*.svg"]),
|
(&["svg"], &["*.svg"]),
|
||||||
(&["swift"], &["*.swift"]),
|
(&["swift"], &["*.swift"]),
|
||||||
(&["swig"], &["*.def", "*.i"]),
|
(&["swig"], &["*.def", "*.i"]),
|
||||||
@ -301,7 +304,9 @@ pub(crate) const DEFAULT_TYPES: &[(&[&str], &[&str])] = &[
|
|||||||
(&["vimscript"], &[
|
(&["vimscript"], &[
|
||||||
"*.vim", ".vimrc", ".gvimrc", "vimrc", "gvimrc", "_vimrc", "_gvimrc",
|
"*.vim", ".vimrc", ".gvimrc", "vimrc", "gvimrc", "_vimrc", "_gvimrc",
|
||||||
]),
|
]),
|
||||||
|
(&["vue"], &["*.vue"]),
|
||||||
(&["webidl"], &["*.idl", "*.webidl", "*.widl"]),
|
(&["webidl"], &["*.idl", "*.webidl", "*.widl"]),
|
||||||
|
(&["wgsl"], &["*.wgsl"]),
|
||||||
(&["wiki"], &["*.mediawiki", "*.wiki"]),
|
(&["wiki"], &["*.mediawiki", "*.wiki"]),
|
||||||
(&["xml"], &[
|
(&["xml"], &[
|
||||||
"*.xml", "*.xml.dist", "*.dtd", "*.xsl", "*.xslt", "*.xsd", "*.xjb",
|
"*.xml", "*.xml.dist", "*.dtd", "*.xsl", "*.xslt", "*.xsd", "*.xjb",
|
||||||
|
@ -19,7 +19,7 @@ use std::{
|
|||||||
fs::{File, FileType},
|
fs::{File, FileType},
|
||||||
io::{self, BufRead},
|
io::{self, BufRead},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock, Weak},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -34,11 +34,13 @@ use crate::{
|
|||||||
/// IgnoreMatch represents information about where a match came from when using
|
/// IgnoreMatch represents information about where a match came from when using
|
||||||
/// the `Ignore` matcher.
|
/// the `Ignore` matcher.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
#[allow(dead_code)]
|
||||||
pub(crate) struct IgnoreMatch<'a>(IgnoreMatchInner<'a>);
|
pub(crate) struct IgnoreMatch<'a>(IgnoreMatchInner<'a>);
|
||||||
|
|
||||||
/// IgnoreMatchInner describes precisely where the match information came from.
|
/// IgnoreMatchInner describes precisely where the match information came from.
|
||||||
/// This is private to allow expansion to more matchers in the future.
|
/// This is private to allow expansion to more matchers in the future.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
#[allow(dead_code)]
|
||||||
enum IgnoreMatchInner<'a> {
|
enum IgnoreMatchInner<'a> {
|
||||||
Override(overrides::Glob<'a>),
|
Override(overrides::Glob<'a>),
|
||||||
Gitignore(&'a gitignore::Glob),
|
Gitignore(&'a gitignore::Glob),
|
||||||
@ -99,7 +101,7 @@ struct IgnoreInner {
|
|||||||
/// Note that this is never used during matching, only when adding new
|
/// Note that this is never used during matching, only when adding new
|
||||||
/// parent directory matchers. This avoids needing to rebuild glob sets for
|
/// parent directory matchers. This avoids needing to rebuild glob sets for
|
||||||
/// parent directories if many paths are being searched.
|
/// parent directories if many paths are being searched.
|
||||||
compiled: Arc<RwLock<HashMap<OsString, Ignore>>>,
|
compiled: Arc<RwLock<HashMap<OsString, Weak<IgnoreInner>>>>,
|
||||||
/// The path to the directory that this matcher was built from.
|
/// The path to the directory that this matcher was built from.
|
||||||
dir: PathBuf,
|
dir: PathBuf,
|
||||||
/// An override matcher (default is empty).
|
/// An override matcher (default is empty).
|
||||||
@ -198,10 +200,12 @@ impl Ignore {
|
|||||||
let mut ig = self.clone();
|
let mut ig = self.clone();
|
||||||
for parent in parents.into_iter().rev() {
|
for parent in parents.into_iter().rev() {
|
||||||
let mut compiled = self.0.compiled.write().unwrap();
|
let mut compiled = self.0.compiled.write().unwrap();
|
||||||
if let Some(prebuilt) = compiled.get(parent.as_os_str()) {
|
if let Some(weak) = compiled.get(parent.as_os_str()) {
|
||||||
ig = prebuilt.clone();
|
if let Some(prebuilt) = weak.upgrade() {
|
||||||
|
ig = Ignore(prebuilt);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
let (mut igtmp, err) = ig.add_child_path(parent);
|
let (mut igtmp, err) = ig.add_child_path(parent);
|
||||||
errs.maybe_push(err);
|
errs.maybe_push(err);
|
||||||
igtmp.is_absolute_parent = true;
|
igtmp.is_absolute_parent = true;
|
||||||
@ -212,8 +216,12 @@ impl Ignore {
|
|||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
ig = Ignore(Arc::new(igtmp));
|
let ig_arc = Arc::new(igtmp);
|
||||||
compiled.insert(parent.as_os_str().to_os_string(), ig.clone());
|
ig = Ignore(ig_arc.clone());
|
||||||
|
compiled.insert(
|
||||||
|
parent.as_os_str().to_os_string(),
|
||||||
|
Arc::downgrade(&ig_arc),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
(ig, errs.into_error_option())
|
(ig, errs.into_error_option())
|
||||||
}
|
}
|
||||||
|
@ -390,6 +390,7 @@ impl GitignoreBuilder {
|
|||||||
Err(err) => return Some(Error::Io(err).with_path(path)),
|
Err(err) => return Some(Error::Io(err).with_path(path)),
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
};
|
};
|
||||||
|
log::debug!("opened gitignore file: {}", path.display());
|
||||||
let rdr = BufReader::new(file);
|
let rdr = BufReader::new(file);
|
||||||
let mut errs = PartialErrorBuilder::default();
|
let mut errs = PartialErrorBuilder::default();
|
||||||
for (i, line) in rdr.lines().enumerate() {
|
for (i, line) in rdr.lines().enumerate() {
|
||||||
|
@ -23,9 +23,11 @@ use crate::{
|
|||||||
/// The lifetime `'a` refers to the lifetime of the matcher that produced
|
/// The lifetime `'a` refers to the lifetime of the matcher that produced
|
||||||
/// this glob.
|
/// this glob.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
#[allow(dead_code)]
|
||||||
pub struct Glob<'a>(GlobInner<'a>);
|
pub struct Glob<'a>(GlobInner<'a>);
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
#[allow(dead_code)]
|
||||||
enum GlobInner<'a> {
|
enum GlobInner<'a> {
|
||||||
/// No glob matched, but the file path should still be ignored.
|
/// No glob matched, but the file path should still be ignored.
|
||||||
UnmatchedIgnore,
|
UnmatchedIgnore,
|
||||||
|
@ -11,7 +11,7 @@ use std::{
|
|||||||
use {
|
use {
|
||||||
crossbeam_deque::{Stealer, Worker as Deque},
|
crossbeam_deque::{Stealer, Worker as Deque},
|
||||||
same_file::Handle,
|
same_file::Handle,
|
||||||
walkdir::{self, WalkDir},
|
walkdir::WalkDir,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -591,7 +591,7 @@ impl WalkBuilder {
|
|||||||
///
|
///
|
||||||
/// Note that this *doesn't* return something that implements `Iterator`.
|
/// Note that this *doesn't* return something that implements `Iterator`.
|
||||||
/// Instead, the returned value must be run with a closure. e.g.,
|
/// Instead, the returned value must be run with a closure. e.g.,
|
||||||
/// `builder.build_parallel().run(|| |path| println!("{:?}", path))`.
|
/// `builder.build_parallel().run(|| |path| { println!("{path:?}"); WalkState::Continue })`.
|
||||||
pub fn build_parallel(&self) -> WalkParallel {
|
pub fn build_parallel(&self) -> WalkParallel {
|
||||||
WalkParallel {
|
WalkParallel {
|
||||||
paths: self.paths.clone().into_iter(),
|
paths: self.paths.clone().into_iter(),
|
||||||
|
@ -389,6 +389,15 @@ pub trait Captures {
|
|||||||
/// for the overall match.
|
/// for the overall match.
|
||||||
fn get(&self, i: usize) -> Option<Match>;
|
fn get(&self, i: usize) -> Option<Match>;
|
||||||
|
|
||||||
|
/// Return the overall match for the capture.
|
||||||
|
///
|
||||||
|
/// This returns the match for index `0`. That is it is equivalent to
|
||||||
|
/// `get(0).unwrap()`
|
||||||
|
#[inline]
|
||||||
|
fn as_match(&self) -> Match {
|
||||||
|
self.get(0).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if and only if these captures are empty. This occurs
|
/// Returns true if and only if these captures are empty. This occurs
|
||||||
/// when `len` is `0`.
|
/// when `len` is `0`.
|
||||||
///
|
///
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "grep-pcre2"
|
name = "grep-pcre2"
|
||||||
version = "0.1.7" #:version
|
version = "0.1.8" #:version
|
||||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||||
description = """
|
description = """
|
||||||
Use PCRE2 with the 'grep' crate.
|
Use PCRE2 with the 'grep' crate.
|
||||||
|
@ -428,7 +428,7 @@ fn has_uppercase_literal(pattern: &str) -> bool {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use grep_matcher::{LineMatchKind, Matcher};
|
use grep_matcher::LineMatchKind;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "grep-printer"
|
name = "grep-printer"
|
||||||
version = "0.2.0" #:version
|
version = "0.2.2" #:version
|
||||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||||
description = """
|
description = """
|
||||||
An implementation of the grep crate's Sink trait that provides standard
|
An implementation of the grep crate's Sink trait that provides standard
|
||||||
@ -21,14 +21,14 @@ serde = ["dep:serde", "dep:serde_json"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
bstr = "1.6.2"
|
bstr = "1.6.2"
|
||||||
grep-matcher = { version = "0.1.7", path = "../matcher" }
|
grep-matcher = { version = "0.1.7", path = "../matcher" }
|
||||||
grep-searcher = { version = "0.1.12", path = "../searcher" }
|
grep-searcher = { version = "0.1.14", path = "../searcher" }
|
||||||
log = "0.4.5"
|
log = "0.4.5"
|
||||||
termcolor = "1.3.0"
|
termcolor = "1.3.0"
|
||||||
serde = { version = "1.0.193", optional = true }
|
serde = { version = "1.0.193", optional = true }
|
||||||
serde_json = { version = "1.0.107", optional = true }
|
serde_json = { version = "1.0.107", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
grep-regex = { version = "0.1.12", path = "../regex" }
|
grep-regex = { version = "0.1.13", path = "../regex" }
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
# We want to document all features.
|
# We want to document all features.
|
||||||
|
@ -811,6 +811,13 @@ impl HyperlinkPath {
|
|||||||
Some(HyperlinkPath::encode(with_slash.as_bytes()))
|
Some(HyperlinkPath::encode(with_slash.as_bytes()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// For other platforms (not windows, not unix), return None and log a debug message.
|
||||||
|
#[cfg(not(any(windows, unix)))]
|
||||||
|
pub(crate) fn from_path(original_path: &Path) -> Option<HyperlinkPath> {
|
||||||
|
log::debug!("hyperlinks are not supported on this platform");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
/// Percent-encodes a path.
|
/// Percent-encodes a path.
|
||||||
///
|
///
|
||||||
/// The alphanumeric ASCII characters and "-", ".", "_", "~" are unreserved
|
/// The alphanumeric ASCII characters and "-", ".", "_", "~" are unreserved
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "grep-regex"
|
name = "grep-regex"
|
||||||
version = "0.1.12" #:version
|
version = "0.1.13" #:version
|
||||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||||
description = """
|
description = """
|
||||||
Use Rust's regex library with the 'grep' crate.
|
Use Rust's regex library with the 'grep' crate.
|
||||||
|
@ -233,7 +233,7 @@ impl ConfiguredHIR {
|
|||||||
&self.config
|
&self.config
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a reference to the underyling HIR.
|
/// Return a reference to the underlying HIR.
|
||||||
pub(crate) fn hir(&self) -> &Hir {
|
pub(crate) fn hir(&self) -> &Hir {
|
||||||
&self.hir
|
&self.hir
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ use crate::{config::ConfiguredHIR, error::Error};
|
|||||||
/// that are in turn used to build a simpler regex that is more amenable to
|
/// that are in turn used to build a simpler regex that is more amenable to
|
||||||
/// optimization.
|
/// optimization.
|
||||||
///
|
///
|
||||||
/// The main idea underyling the validity of this technique is the fact
|
/// The main idea underlying the validity of this technique is the fact
|
||||||
/// that ripgrep searches individuals lines and not across lines. (Unless
|
/// that ripgrep searches individuals lines and not across lines. (Unless
|
||||||
/// -U/--multiline is enabled.) Namely, we can pluck literals out of the regex,
|
/// -U/--multiline is enabled.) Namely, we can pluck literals out of the regex,
|
||||||
/// search for them, find the bounds of the line in which that literal occurs
|
/// search for them, find the bounds of the line in which that literal occurs
|
||||||
@ -430,6 +430,7 @@ impl Extractor {
|
|||||||
}
|
}
|
||||||
seq1.union(seq2);
|
seq1.union(seq2);
|
||||||
assert!(seq1.len().map_or(true, |x| x <= self.limit_total));
|
assert!(seq1.len().map_or(true, |x| x <= self.limit_total));
|
||||||
|
seq1.prefix = seq1.prefix && seq2.prefix;
|
||||||
seq1
|
seq1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,10 +587,15 @@ impl TSeq {
|
|||||||
lits.iter().any(is_poisonous)
|
lits.iter().any(is_poisonous)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compare the two sequences and return the one that is believed to be best
|
/// Compare the two sequences and return the one that is believed to be
|
||||||
/// according to a hodge podge of heuristics.
|
/// best according to a hodge podge of heuristics.
|
||||||
fn choose(self, other: TSeq) -> TSeq {
|
fn choose(self, other: TSeq) -> TSeq {
|
||||||
let (seq1, seq2) = (self, other);
|
let (mut seq1, mut seq2) = (self, other);
|
||||||
|
// Whichever one we pick, by virtue of picking one, we choose
|
||||||
|
// to not take the other. So we must consider the result inexact.
|
||||||
|
seq1.make_inexact();
|
||||||
|
seq2.make_inexact();
|
||||||
|
|
||||||
if !seq1.is_finite() {
|
if !seq1.is_finite() {
|
||||||
return seq2;
|
return seq2;
|
||||||
} else if !seq2.is_finite() {
|
} else if !seq2.is_finite() {
|
||||||
@ -681,7 +687,7 @@ mod tests {
|
|||||||
assert_eq!(e(r"foo"), seq([E("foo")]));
|
assert_eq!(e(r"foo"), seq([E("foo")]));
|
||||||
assert_eq!(e(r"[a-z]foo[a-z]"), seq([I("foo")]));
|
assert_eq!(e(r"[a-z]foo[a-z]"), seq([I("foo")]));
|
||||||
assert_eq!(e(r"[a-z](foo)(bar)[a-z]"), seq([I("foobar")]));
|
assert_eq!(e(r"[a-z](foo)(bar)[a-z]"), seq([I("foobar")]));
|
||||||
assert_eq!(e(r"[a-z]([a-z]foo)(bar[a-z])[a-z]"), seq([I("foobar")]));
|
assert_eq!(e(r"[a-z]([a-z]foo)(bar[a-z])[a-z]"), seq([I("foo")]));
|
||||||
assert_eq!(e(r"[a-z]([a-z]foo)([a-z]foo)[a-z]"), seq([I("foo")]));
|
assert_eq!(e(r"[a-z]([a-z]foo)([a-z]foo)[a-z]"), seq([I("foo")]));
|
||||||
assert_eq!(e(r"(\d{1,3}\.){3}\d{1,3}"), seq([I(".")]));
|
assert_eq!(e(r"(\d{1,3}\.){3}\d{1,3}"), seq([I(".")]));
|
||||||
assert_eq!(e(r"[a-z]([a-z]foo){3}[a-z]"), seq([I("foo")]));
|
assert_eq!(e(r"[a-z]([a-z]foo){3}[a-z]"), seq([I("foo")]));
|
||||||
@ -689,7 +695,7 @@ mod tests {
|
|||||||
assert_eq!(e(r"[a-z]([a-z]foo[a-z]){3}[a-z]"), seq([I("foo")]));
|
assert_eq!(e(r"[a-z]([a-z]foo[a-z]){3}[a-z]"), seq([I("foo")]));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
e(r"[a-z]([a-z]foo){3}(bar[a-z]){3}[a-z]"),
|
e(r"[a-z]([a-z]foo){3}(bar[a-z]){3}[a-z]"),
|
||||||
seq([I("foobar")])
|
seq([I("foo")])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -935,14 +941,14 @@ mod tests {
|
|||||||
assert_eq!(Seq::infinite(), e(r"[A-Z]+"));
|
assert_eq!(Seq::infinite(), e(r"[A-Z]+"));
|
||||||
assert_eq!(seq([I("1")]), e(r"1[A-Z]"));
|
assert_eq!(seq([I("1")]), e(r"1[A-Z]"));
|
||||||
assert_eq!(seq([I("1")]), e(r"1[A-Z]2"));
|
assert_eq!(seq([I("1")]), e(r"1[A-Z]2"));
|
||||||
assert_eq!(seq([E("123")]), e(r"[A-Z]+123"));
|
assert_eq!(seq([I("123")]), e(r"[A-Z]+123"));
|
||||||
assert_eq!(seq([I("123")]), e(r"[A-Z]+123[A-Z]+"));
|
assert_eq!(seq([I("123")]), e(r"[A-Z]+123[A-Z]+"));
|
||||||
assert_eq!(Seq::infinite(), e(r"1|[A-Z]|3"));
|
assert_eq!(Seq::infinite(), e(r"1|[A-Z]|3"));
|
||||||
assert_eq!(seq([E("1"), I("2"), E("3")]), e(r"1|2[A-Z]|3"),);
|
assert_eq!(seq([E("1"), I("2"), E("3")]), e(r"1|2[A-Z]|3"),);
|
||||||
assert_eq!(seq([E("1"), I("2"), E("3")]), e(r"1|[A-Z]2[A-Z]|3"),);
|
assert_eq!(seq([E("1"), I("2"), E("3")]), e(r"1|[A-Z]2[A-Z]|3"),);
|
||||||
assert_eq!(seq([E("1"), E("2"), E("3")]), e(r"1|[A-Z]2|3"),);
|
assert_eq!(seq([E("1"), I("2"), E("3")]), e(r"1|[A-Z]2|3"),);
|
||||||
assert_eq!(seq([E("1"), I("2"), E("4")]), e(r"1|2[A-Z]3|4"),);
|
assert_eq!(seq([E("1"), I("2"), E("4")]), e(r"1|2[A-Z]3|4"),);
|
||||||
assert_eq!(seq([E("2")]), e(r"(?:|1)[A-Z]2"));
|
assert_eq!(seq([I("2")]), e(r"(?:|1)[A-Z]2"));
|
||||||
assert_eq!(inexact([I("a")]), e(r"a.z"));
|
assert_eq!(inexact([I("a")]), e(r"a.z"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1005,4 +1011,11 @@ mod tests {
|
|||||||
let s = e(r"foobarfoo|foo| |foofoo");
|
let s = e(r"foobarfoo|foo| |foofoo");
|
||||||
assert_eq!(Seq::infinite(), s);
|
assert_eq!(Seq::infinite(), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regression test for: https://github.com/BurntSushi/ripgrep/issues/2884
|
||||||
|
#[test]
|
||||||
|
fn case_insensitive_alternation() {
|
||||||
|
let s = e(r"(?i:e.x|ex)");
|
||||||
|
assert_eq!(s, seq([I("X"), I("x")]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -552,8 +552,6 @@ impl RegexCaptures {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use grep_matcher::{LineMatchKind, Matcher};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
// Test that enabling word matches does the right thing and demonstrate
|
// Test that enabling word matches does the right thing and demonstrate
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "grep-searcher"
|
name = "grep-searcher"
|
||||||
version = "0.1.12" #:version
|
version = "0.1.14" #:version
|
||||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||||
description = """
|
description = """
|
||||||
Fast line oriented regex searching as a library.
|
Fast line oriented regex searching as a library.
|
||||||
@ -23,11 +23,10 @@ memchr = "2.6.3"
|
|||||||
memmap = { package = "memmap2", version = "0.9.0" }
|
memmap = { package = "memmap2", version = "0.9.0" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
grep-regex = { version = "0.1.12", path = "../regex" }
|
grep-regex = { version = "0.1.13", path = "../regex" }
|
||||||
regex = "1.9.5"
|
regex = "1.9.5"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
simd-accel = ["encoding_rs/simd-accel"]
|
# These features are DEPRECATED. Runtime dispatch is used for SIMD now.
|
||||||
|
simd-accel = []
|
||||||
# This feature is DEPRECATED. Runtime dispatch is used for SIMD now.
|
|
||||||
avx-accel = []
|
avx-accel = []
|
||||||
|
@ -548,7 +548,7 @@ fn replace_bytes(
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use bstr::{ByteSlice, ByteVec};
|
use bstr::ByteVec;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -198,8 +198,6 @@ fn preceding_by_pos(
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use grep_matcher::Match;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
const SHERLOCK: &'static str = "\
|
const SHERLOCK: &'static str = "\
|
||||||
|
@ -612,6 +612,17 @@ impl<'s, M: Matcher, S: Sink> Core<'s, M, S> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if let Some(line_term) = self.matcher.line_terminator() {
|
if let Some(line_term) = self.matcher.line_terminator() {
|
||||||
|
// FIXME: This works around a bug in grep-regex where it does
|
||||||
|
// not set the line terminator of the regex itself, and thus
|
||||||
|
// line anchors like `(?m:^)` and `(?m:$)` will not match
|
||||||
|
// anything except for `\n`. So for now, we just disable the fast
|
||||||
|
// line-by-line searcher which requires the regex to be able to
|
||||||
|
// deal with line terminators correctly. The slow line-by-line
|
||||||
|
// searcher strips line terminators and thus absolves the regex
|
||||||
|
// engine from needing to care about whether they are `\n` or NUL.
|
||||||
|
if line_term.as_byte() == b'\x00' {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if line_term == self.config.line_term {
|
if line_term == self.config.line_term {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use {
|
use {
|
||||||
encoding_rs,
|
|
||||||
encoding_rs_io::DecodeReaderBytesBuilder,
|
encoding_rs_io::DecodeReaderBytesBuilder,
|
||||||
grep_matcher::{LineTerminator, Match, Matcher},
|
grep_matcher::{LineTerminator, Match, Matcher},
|
||||||
};
|
};
|
||||||
@ -1005,6 +1004,7 @@ fn slice_has_bom(slice: &[u8]) -> bool {
|
|||||||
None => return false,
|
None => return false,
|
||||||
Some((enc, _)) => enc,
|
Some((enc, _)) => enc,
|
||||||
};
|
};
|
||||||
|
log::trace!("found byte-order mark (BOM) for encoding {enc:?}");
|
||||||
[encoding_rs::UTF_16LE, encoding_rs::UTF_16BE, encoding_rs::UTF_8]
|
[encoding_rs::UTF_16LE, encoding_rs::UTF_16BE, encoding_rs::UTF_8]
|
||||||
.contains(&enc)
|
.contains(&enc)
|
||||||
}
|
}
|
||||||
|
@ -725,8 +725,6 @@ impl TesterConfig {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use grep_matcher::{Match, Matcher};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
fn m(start: usize, end: usize) -> Match {
|
fn m(start: usize, end: usize) -> Match {
|
||||||
|
317
doc/rg.1.txt.tpl
317
doc/rg.1.txt.tpl
@ -1,317 +0,0 @@
|
|||||||
rg(1)
|
|
||||||
=====
|
|
||||||
|
|
||||||
Name
|
|
||||||
----
|
|
||||||
rg - recursively search the current directory for lines matching a pattern
|
|
||||||
|
|
||||||
|
|
||||||
Synopsis
|
|
||||||
--------
|
|
||||||
*rg* [_OPTIONS_] _PATTERN_ [_PATH_...]
|
|
||||||
|
|
||||||
*rg* [_OPTIONS_] *-e* _PATTERN_... [_PATH_...]
|
|
||||||
|
|
||||||
*rg* [_OPTIONS_] *-f* _PATTERNFILE_... [_PATH_...]
|
|
||||||
|
|
||||||
*rg* [_OPTIONS_] *--files* [_PATH_...]
|
|
||||||
|
|
||||||
*rg* [_OPTIONS_] *--type-list*
|
|
||||||
|
|
||||||
*command* | *rg* [_OPTIONS_] _PATTERN_
|
|
||||||
|
|
||||||
*rg* [_OPTIONS_] *--help*
|
|
||||||
|
|
||||||
*rg* [_OPTIONS_] *--version*
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
-----------
|
|
||||||
ripgrep (rg) recursively searches the current directory for a regex pattern.
|
|
||||||
By default, ripgrep will respect your .gitignore and automatically skip hidden
|
|
||||||
files/directories and binary files.
|
|
||||||
|
|
||||||
ripgrep's default regex engine uses finite automata and guarantees linear
|
|
||||||
time searching. Because of this, features like backreferences and arbitrary
|
|
||||||
look-around are not supported. However, if ripgrep is built with PCRE2, then
|
|
||||||
the *--pcre2* flag can be used to enable backreferences and look-around.
|
|
||||||
|
|
||||||
ripgrep supports configuration files. Set *RIPGREP_CONFIG_PATH* to a
|
|
||||||
configuration file. The file can specify one shell argument per line. Lines
|
|
||||||
starting with *#* are ignored. For more details, see the man page or the
|
|
||||||
*README*.
|
|
||||||
|
|
||||||
ripgrep will automatically detect if stdin exists and search stdin for a regex
|
|
||||||
pattern, e.g. *ls | rg foo*. In some environments, stdin may exist when it
|
|
||||||
shouldn't. To turn off stdin detection explicitly specify the directory to
|
|
||||||
search, e.g. *rg foo ./*.
|
|
||||||
|
|
||||||
Tip: to disable all smart filtering and make ripgrep behave a bit more like
|
|
||||||
classical grep, use *rg -uuu*.
|
|
||||||
|
|
||||||
|
|
||||||
REGEX SYNTAX
|
|
||||||
------------
|
|
||||||
ripgrep uses Rust's regex engine by default, which documents its syntax:
|
|
||||||
https://docs.rs/regex/*/regex/#syntax
|
|
||||||
|
|
||||||
ripgrep uses byte-oriented regexes, which has some additional documentation:
|
|
||||||
https://docs.rs/regex/*/regex/bytes/index.html#syntax
|
|
||||||
|
|
||||||
To a first approximation, ripgrep uses Perl-like regexes without look-around or
|
|
||||||
backreferences. This makes them very similar to the "extended" (ERE) regular
|
|
||||||
expressions supported by *egrep*, but with a few additional features like
|
|
||||||
Unicode character classes.
|
|
||||||
|
|
||||||
If you're using ripgrep with the *--pcre2* flag, then please consult
|
|
||||||
https://www.pcre.org or the PCRE2 man pages for documentation on the supported
|
|
||||||
syntax.
|
|
||||||
|
|
||||||
|
|
||||||
POSITIONAL ARGUMENTS
|
|
||||||
--------------------
|
|
||||||
_PATTERN_::
|
|
||||||
A regular expression used for searching. To match a pattern beginning with a
|
|
||||||
dash, use the -e/--regexp option.
|
|
||||||
|
|
||||||
_PATH_::
|
|
||||||
A file or directory to search. Directories are searched recursively. File
|
|
||||||
paths specified explicitly on the command line override glob and ignore
|
|
||||||
rules.
|
|
||||||
|
|
||||||
|
|
||||||
OPTIONS
|
|
||||||
-------
|
|
||||||
Note that many options can be disabled via flags. In some cases, those flags
|
|
||||||
are not listed in a first class way below. For example, the *--column*
|
|
||||||
flag (listed below) enables column numbers in ripgrep's output, but the
|
|
||||||
*--no-column* flag (not listed below) disables them. The reverse can also
|
|
||||||
exist. For example, the *--no-ignore* flag (listed below) disables ripgrep's
|
|
||||||
*gitignore* logic, but the *--ignore* flag (not listed below) enables it. These
|
|
||||||
flags are useful for overriding a ripgrep configuration file on the command
|
|
||||||
line. Each flag's documentation notes whether an inverted flag exists. In all
|
|
||||||
cases, the flag specified last takes precedence.
|
|
||||||
|
|
||||||
{OPTIONS}
|
|
||||||
|
|
||||||
|
|
||||||
EXIT STATUS
|
|
||||||
-----------
|
|
||||||
If ripgrep finds a match, then the exit status of the program is 0. If no match
|
|
||||||
could be found, then the exit status is 1. If an error occurred, then the exit
|
|
||||||
status is always 2 unless ripgrep was run with the *--quiet* flag and a match
|
|
||||||
was found. In summary:
|
|
||||||
|
|
||||||
* `0` exit status occurs only when at least one match was found, and if
|
|
||||||
no error occurred, unless *--quiet* was given.
|
|
||||||
* `1` exit status occurs only when no match was found and no error occurred.
|
|
||||||
* `2` exit status occurs when an error occurred. This is true for both
|
|
||||||
catastrophic errors (e.g., a regex syntax error) and for soft errors (e.g.,
|
|
||||||
unable to read a file).
|
|
||||||
|
|
||||||
|
|
||||||
AUTOMATIC FILTERING
|
|
||||||
-------------------
|
|
||||||
TL;DR - To disable automatic filtering, use 'rg -uuu'.
|
|
||||||
|
|
||||||
One of ripgrep's most important features is its automatic smart filtering.
|
|
||||||
It is the most apparent differentiating feature between ripgrep and other tools
|
|
||||||
like 'grep'. As such, its behavior may be surprising to users that aren't
|
|
||||||
expecting it.
|
|
||||||
|
|
||||||
ripgrep does four types of filtering automatically:
|
|
||||||
|
|
||||||
1. Files and directories that match ignore rules are not searched.
|
|
||||||
2. Hidden files and directories are not searched.
|
|
||||||
3. Binary files (files with a 'NUL' byte) are not searched.
|
|
||||||
4. Symbolic links are not followed.
|
|
||||||
|
|
||||||
The first type of filtering is the most sophisticated. ripgrep will attempt to
|
|
||||||
respect your gitignore rules as faithfully as possible. In particular, this
|
|
||||||
includes the following:
|
|
||||||
|
|
||||||
* Any global rules, e.g., in '$HOME/.config/git/ignore'.
|
|
||||||
* Any rules in '.gitignore'.
|
|
||||||
* Any local rules, e.g., in '.git/info/exclude'.
|
|
||||||
|
|
||||||
In some cases, ripgrep and git will not always be in sync in terms of which
|
|
||||||
files are ignored. For example, a file that is ignored via '.gitignore' but is
|
|
||||||
tracked by git would not be searched by ripgrep even though git tracks it. This
|
|
||||||
is unlikely to ever be fixed. Instead, you should either make sure your exclude
|
|
||||||
rules match the files you track precisely, or otherwise use 'git grep' for
|
|
||||||
search.
|
|
||||||
|
|
||||||
Additional ignore rules can be provided outside of a git context:
|
|
||||||
|
|
||||||
* Any rules in '.ignore'.
|
|
||||||
* Any rules in '.rgignore'.
|
|
||||||
* Any rules in files specified with the '--ignore-file' flag.
|
|
||||||
|
|
||||||
The precedence of ignore rules is as follows, with later items overriding
|
|
||||||
earlier items:
|
|
||||||
|
|
||||||
* Files given by '--ignore-file'.
|
|
||||||
* Global gitignore rules, e.g., from '$HOME/.config/git/ignore'.
|
|
||||||
* Local rules from '.git/info/exclude'.
|
|
||||||
* Rules from '.gitignore'.
|
|
||||||
* Rules from '.ignore'.
|
|
||||||
* Rules from '.rgignore'.
|
|
||||||
|
|
||||||
So for example, if 'foo' were in a '.gitignore' and '!foo' were in an
|
|
||||||
'.rgignore', then 'foo' would not be ignored since '.rgignore' takes precedence
|
|
||||||
over '.gitignore'.
|
|
||||||
|
|
||||||
Each of the types of filtering can be configured via command line flags:
|
|
||||||
|
|
||||||
* There are several flags starting with '--no-ignore' that toggle which,
|
|
||||||
if any, ignore rules are respected. '--no-ignore' by itself will disable
|
|
||||||
all of them.
|
|
||||||
* '-./--hidden' will force ripgrep to search hidden files and directories.
|
|
||||||
* '--binary' will force ripgrep to search binary files.
|
|
||||||
* '-L/--follow' will force ripgrep to follow symlinks.
|
|
||||||
|
|
||||||
As a special short hand, the `-u` flag can be specified up to three times. Each
|
|
||||||
additional time incrementally decreases filtering:
|
|
||||||
|
|
||||||
* '-u' is equivalent to '--no-ignore'.
|
|
||||||
* '-uu' is equivalent to '--no-ignore --hidden'.
|
|
||||||
* '-uuu' is equivalent to '--no-ignore --hidden --binary'.
|
|
||||||
|
|
||||||
In particular, 'rg -uuu' should search the same exact content as 'grep -r'.
|
|
||||||
|
|
||||||
|
|
||||||
CONFIGURATION FILES
|
|
||||||
-------------------
|
|
||||||
ripgrep supports reading configuration files that change ripgrep's default
|
|
||||||
behavior. The format of the configuration file is an "rc" style and is very
|
|
||||||
simple. It is defined by two rules:
|
|
||||||
|
|
||||||
1. Every line is a shell argument, after trimming whitespace.
|
|
||||||
2. Lines starting with *#* (optionally preceded by any amount of
|
|
||||||
whitespace) are ignored.
|
|
||||||
|
|
||||||
ripgrep will look for a single configuration file if and only if the
|
|
||||||
*RIPGREP_CONFIG_PATH* environment variable is set and is non-empty. ripgrep
|
|
||||||
will parse shell arguments from this file on startup and will behave as if
|
|
||||||
the arguments in this file were prepended to any explicit arguments given to
|
|
||||||
ripgrep on the command line. Note though that the 'rg' command you run must
|
|
||||||
still be valid. That is, it must always contain at least one pattern at the
|
|
||||||
command line, even if the configuration file uses the '-e/--regexp' flag.
|
|
||||||
|
|
||||||
For example, if your ripgreprc file contained a single line:
|
|
||||||
|
|
||||||
--smart-case
|
|
||||||
|
|
||||||
then the following command
|
|
||||||
|
|
||||||
RIPGREP_CONFIG_PATH=wherever/.ripgreprc rg foo
|
|
||||||
|
|
||||||
would behave identically to the following command
|
|
||||||
|
|
||||||
rg --smart-case foo
|
|
||||||
|
|
||||||
another example is adding types
|
|
||||||
|
|
||||||
--type-add
|
|
||||||
web:*.{html,css,js}*
|
|
||||||
|
|
||||||
would behave identically to the following command
|
|
||||||
|
|
||||||
rg --type-add 'web:*.{html,css,js}*' foo
|
|
||||||
|
|
||||||
same with using globs
|
|
||||||
|
|
||||||
--glob=!.git
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
--glob
|
|
||||||
!.git
|
|
||||||
|
|
||||||
would behave identically to the following command
|
|
||||||
|
|
||||||
rg --glob '!.git' foo
|
|
||||||
|
|
||||||
The bottom line is that every shell argument needs to be on its own line. So
|
|
||||||
for example, a config file containing
|
|
||||||
|
|
||||||
-j 4
|
|
||||||
|
|
||||||
is probably not doing what you intend. Instead, you want
|
|
||||||
|
|
||||||
-j
|
|
||||||
4
|
|
||||||
|
|
||||||
ripgrep also provides a flag, *--no-config*, that when present will suppress
|
|
||||||
any and all support for configuration. This includes any future support
|
|
||||||
for auto-loading configuration files from pre-determined paths.
|
|
||||||
|
|
||||||
Conflicts between configuration files and explicit arguments are handled
|
|
||||||
exactly like conflicts in the same command line invocation. That is,
|
|
||||||
this command:
|
|
||||||
|
|
||||||
RIPGREP_CONFIG_PATH=wherever/.ripgreprc rg foo --case-sensitive
|
|
||||||
|
|
||||||
is exactly equivalent to
|
|
||||||
|
|
||||||
rg --smart-case foo --case-sensitive
|
|
||||||
|
|
||||||
in which case, the *--case-sensitive* flag would override the *--smart-case*
|
|
||||||
flag.
|
|
||||||
|
|
||||||
|
|
||||||
SHELL COMPLETION
|
|
||||||
----------------
|
|
||||||
Shell completion files are included in the release tarball for Bash, Fish, Zsh
|
|
||||||
and PowerShell.
|
|
||||||
|
|
||||||
For *bash*, move *rg.bash* to *$XDG_CONFIG_HOME/bash_completion*
|
|
||||||
or */etc/bash_completion.d/*.
|
|
||||||
|
|
||||||
For *fish*, move *rg.fish* to *$HOME/.config/fish/completions*.
|
|
||||||
|
|
||||||
For *zsh*, move *_rg* to one of your *$fpath* directories.
|
|
||||||
|
|
||||||
|
|
||||||
CAVEATS
|
|
||||||
-------
|
|
||||||
ripgrep may abort unexpectedly when using default settings if it searches a
|
|
||||||
file that is simultaneously truncated. This behavior can be avoided by passing
|
|
||||||
the *--no-mmap* flag which will forcefully disable the use of memory maps in
|
|
||||||
all cases.
|
|
||||||
|
|
||||||
ripgrep may use a large amount of memory depending on a few factors. Firstly,
|
|
||||||
if ripgrep uses parallelism for search (the default), then the entire output
|
|
||||||
for each individual file is buffered into memory in order to prevent
|
|
||||||
interleaving matches in the output. To avoid this, you can disable parallelism
|
|
||||||
with the *-j1* flag. Secondly, ripgrep always needs to have at least a single
|
|
||||||
line in memory in order to execute a search. A file with a very long line can
|
|
||||||
thus cause ripgrep to use a lot of memory. Generally, this only occurs when
|
|
||||||
searching binary data with the *-a* flag enabled. (When the *-a* flag isn't
|
|
||||||
enabled, ripgrep will replace all NUL bytes with line terminators, which
|
|
||||||
typically prevents exorbitant memory usage.) Thirdly, when ripgrep searches
|
|
||||||
a large file using a memory map, the process will report its resident memory
|
|
||||||
usage as the size of the file. However, this does not mean ripgrep actually
|
|
||||||
needed to use that much memory; the operating system will generally handle this
|
|
||||||
for you.
|
|
||||||
|
|
||||||
|
|
||||||
VERSION
|
|
||||||
-------
|
|
||||||
{VERSION}
|
|
||||||
|
|
||||||
|
|
||||||
HOMEPAGE
|
|
||||||
--------
|
|
||||||
https://github.com/BurntSushi/ripgrep
|
|
||||||
|
|
||||||
Please report bugs and feature requests in the issue tracker. Please do your
|
|
||||||
best to provide a reproducible test case for bugs. This should include the
|
|
||||||
corpus being searched, the *rg* command, the actual output and the expected
|
|
||||||
output. Please also include the output of running the same *rg* command but
|
|
||||||
with the *--debug* flag.
|
|
||||||
|
|
||||||
|
|
||||||
AUTHORS
|
|
||||||
-------
|
|
||||||
Andrew Gallant <jamslam@gmail.com>
|
|
@ -1,14 +1,14 @@
|
|||||||
class RipgrepBin < Formula
|
class RipgrepBin < Formula
|
||||||
version '13.0.0'
|
version '14.1.1'
|
||||||
desc "Recursively search directories for a regex pattern."
|
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 "d60e1df731119e742c4ca4f30655b697250d3b41153a6e80b925d7b9f992a9aa"
|
sha256 "fc87e78f7cb3fea12d69072e7ef3b21509754717b746368fd40d88963630e2b3"
|
||||||
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 "a18e0b611f9d9976b11ab8c3355a92c68c8bd1965b0d99366777751343e33938"
|
sha256 "4cf9f2741e6c465ffdb7c26f38056a59e2a2544b51f7cc128ef28337eeae4d8e"
|
||||||
end
|
end
|
||||||
|
|
||||||
conflicts_with "ripgrep"
|
conflicts_with "ripgrep"
|
||||||
|
@ -356,6 +356,17 @@ rgtest!(f263_sort_files, |dir: Dir, mut cmd: TestCommand| {
|
|||||||
eqnice!(expected, cmd.arg("--sort-files").arg("test").stdout());
|
eqnice!(expected, cmd.arg("--sort-files").arg("test").stdout());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/issues/263
|
||||||
|
rgtest!(f263_sort_files_reverse, |dir: Dir, mut cmd: TestCommand| {
|
||||||
|
dir.create("foo", "test");
|
||||||
|
dir.create("abc", "test");
|
||||||
|
dir.create("zoo", "test");
|
||||||
|
dir.create("bar", "test");
|
||||||
|
|
||||||
|
let expected = "zoo:test\nfoo:test\nbar:test\nabc:test\n";
|
||||||
|
eqnice!(expected, cmd.arg("--sortr=path").arg("test").stdout());
|
||||||
|
});
|
||||||
|
|
||||||
// See: https://github.com/BurntSushi/ripgrep/issues/275
|
// See: https://github.com/BurntSushi/ripgrep/issues/275
|
||||||
rgtest!(f275_pathsep, |dir: Dir, mut cmd: TestCommand| {
|
rgtest!(f275_pathsep, |dir: Dir, mut cmd: TestCommand| {
|
||||||
dir.create_dir("foo");
|
dir.create_dir("foo");
|
||||||
@ -961,10 +972,10 @@ rgtest!(f1404_nothing_searched_warning, |dir: Dir, mut cmd: TestCommand| {
|
|||||||
cmd.assert_err();
|
cmd.assert_err();
|
||||||
|
|
||||||
// Test that we actually get an error message that we expect.
|
// Test that we actually get an error message that we expect.
|
||||||
let output = cmd.cmd().output().unwrap();
|
let output = cmd.raw_output();
|
||||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
let expected = "\
|
let expected = "\
|
||||||
No files were searched, which means ripgrep probably applied \
|
rg: No files were searched, which means ripgrep probably applied \
|
||||||
a filter you didn't expect.\n\
|
a filter you didn't expect.\n\
|
||||||
Running with --debug will show why files are being skipped.\n\
|
Running with --debug will show why files are being skipped.\n\
|
||||||
";
|
";
|
||||||
@ -984,7 +995,7 @@ rgtest!(f1404_nothing_searched_ignored, |dir: Dir, mut cmd: TestCommand| {
|
|||||||
|
|
||||||
// But since --no-messages is given, there should not be any error message
|
// But since --no-messages is given, there should not be any error message
|
||||||
// printed.
|
// printed.
|
||||||
let output = cmd.cmd().output().unwrap();
|
let output = cmd.raw_output();
|
||||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
let expected = "";
|
let expected = "";
|
||||||
eqnice!(expected, stderr);
|
eqnice!(expected, stderr);
|
||||||
|
@ -411,7 +411,7 @@ rgtest!(include_zero, |dir: Dir, mut cmd: TestCommand| {
|
|||||||
cmd.args(&["--count", "--include-zero", "nada"]);
|
cmd.args(&["--count", "--include-zero", "nada"]);
|
||||||
cmd.assert_err();
|
cmd.assert_err();
|
||||||
|
|
||||||
let output = cmd.cmd().output().unwrap();
|
let output = cmd.raw_output();
|
||||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||||
let expected = "sherlock:0\n";
|
let expected = "sherlock:0\n";
|
||||||
|
|
||||||
@ -423,7 +423,7 @@ rgtest!(include_zero_override, |dir: Dir, mut cmd: TestCommand| {
|
|||||||
cmd.args(&["--count", "--include-zero", "--no-include-zero", "nada"]);
|
cmd.args(&["--count", "--include-zero", "--no-include-zero", "nada"]);
|
||||||
cmd.assert_err();
|
cmd.assert_err();
|
||||||
|
|
||||||
let output = cmd.cmd().output().unwrap();
|
let output = cmd.raw_output();
|
||||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||||
assert!(stdout.is_empty());
|
assert!(stdout.is_empty());
|
||||||
});
|
});
|
||||||
|
@ -399,10 +399,10 @@ rgtest!(r428_unrecognized_style, |dir: Dir, mut cmd: TestCommand| {
|
|||||||
cmd.arg("--colors=match:style:").arg("Sherlock");
|
cmd.arg("--colors=match:style:").arg("Sherlock");
|
||||||
cmd.assert_err();
|
cmd.assert_err();
|
||||||
|
|
||||||
let output = cmd.cmd().output().unwrap();
|
let output = cmd.raw_output();
|
||||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
let expected = "\
|
let expected = "\
|
||||||
error parsing flag --colors: \
|
rg: error parsing flag --colors: \
|
||||||
unrecognized style attribute ''. Choose from: nobold, bold, nointense, \
|
unrecognized style attribute ''. Choose from: nobold, bold, nointense, \
|
||||||
intense, nounderline, underline.
|
intense, nounderline, underline.
|
||||||
";
|
";
|
||||||
@ -1210,3 +1210,10 @@ rgtest!(r2574, |dir: Dir, mut cmd: TestCommand| {
|
|||||||
.stdout();
|
.stdout();
|
||||||
eqnice!("some.domain.com\nsome.domain.com\n", got);
|
eqnice!("some.domain.com\nsome.domain.com\n", got);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/issues/2658
|
||||||
|
rgtest!(r2658_null_data_line_regexp, |dir: Dir, mut cmd: TestCommand| {
|
||||||
|
dir.create("haystack", "foo\0bar\0quux\0");
|
||||||
|
let got = cmd.args(&["--null-data", "--line-regexp", r"bar"]).stdout();
|
||||||
|
eqnice!("haystack:bar\0", got);
|
||||||
|
});
|
||||||
|
@ -9,6 +9,8 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
|||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use bstr::ByteSlice;
|
||||||
|
|
||||||
static TEST_DIR: &'static str = "ripgrep-tests";
|
static TEST_DIR: &'static str = "ripgrep-tests";
|
||||||
static NEXT_ID: AtomicUsize = AtomicUsize::new(0);
|
static NEXT_ID: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
@ -282,16 +284,7 @@ impl TestCommand {
|
|||||||
/// Runs and captures the stdout of the given command.
|
/// Runs and captures the stdout of the given command.
|
||||||
pub fn stdout(&mut self) -> String {
|
pub fn stdout(&mut self) -> String {
|
||||||
let o = self.output();
|
let o = self.output();
|
||||||
let stdout = String::from_utf8_lossy(&o.stdout);
|
String::from_utf8_lossy(&o.stdout).into_owned()
|
||||||
match stdout.parse() {
|
|
||||||
Ok(t) => t,
|
|
||||||
Err(err) => {
|
|
||||||
panic!(
|
|
||||||
"could not convert from string: {:?}\n\n{}",
|
|
||||||
err, stdout
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pipe `input` to a command, and collect the output.
|
/// Pipe `input` to a command, and collect the output.
|
||||||
@ -311,27 +304,26 @@ impl TestCommand {
|
|||||||
let output = self.expect_success(child.wait_with_output().unwrap());
|
let output = self.expect_success(child.wait_with_output().unwrap());
|
||||||
worker.join().unwrap().unwrap();
|
worker.join().unwrap().unwrap();
|
||||||
|
|
||||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
String::from_utf8_lossy(&output.stdout).into_owned()
|
||||||
match stdout.parse() {
|
|
||||||
Ok(t) => t,
|
|
||||||
Err(err) => {
|
|
||||||
panic!(
|
|
||||||
"could not convert from string: {:?}\n\n{}",
|
|
||||||
err, stdout
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the output of a command. If the command failed, then this panics.
|
/// Gets the output of a command. If the command failed, then this panics.
|
||||||
pub fn output(&mut self) -> process::Output {
|
pub fn output(&mut self) -> process::Output {
|
||||||
let output = self.cmd.output().unwrap();
|
let output = self.raw_output();
|
||||||
self.expect_success(output)
|
self.expect_success(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the raw output of a command after filtering nonsense like jemalloc
|
||||||
|
/// error messages from stderr.
|
||||||
|
pub fn raw_output(&mut self) -> process::Output {
|
||||||
|
let mut output = self.cmd.output().unwrap();
|
||||||
|
output.stderr = strip_jemalloc_nonsense(&output.stderr);
|
||||||
|
output
|
||||||
|
}
|
||||||
|
|
||||||
/// Runs the command and asserts that it resulted in an error exit code.
|
/// Runs the command and asserts that it resulted in an error exit code.
|
||||||
pub fn assert_err(&mut self) {
|
pub fn assert_err(&mut self) {
|
||||||
let o = self.cmd.output().unwrap();
|
let o = self.raw_output();
|
||||||
if o.status.success() {
|
if o.status.success() {
|
||||||
panic!(
|
panic!(
|
||||||
"\n\n===== {:?} =====\n\
|
"\n\n===== {:?} =====\n\
|
||||||
@ -479,7 +471,7 @@ fn dir_list<P: AsRef<Path>>(dir: P) -> Vec<String> {
|
|||||||
/// So... we just manually handle these cases. So fucking fun.
|
/// So... we just manually handle these cases. So fucking fun.
|
||||||
fn cross_runner() -> Option<String> {
|
fn cross_runner() -> Option<String> {
|
||||||
let runner = std::env::var("CROSS_RUNNER").ok()?;
|
let runner = std::env::var("CROSS_RUNNER").ok()?;
|
||||||
if runner.is_empty() {
|
if runner.is_empty() || runner == "empty" {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if cfg!(target_arch = "powerpc64") {
|
if cfg!(target_arch = "powerpc64") {
|
||||||
@ -500,3 +492,17 @@ fn cross_runner() -> Option<String> {
|
|||||||
pub fn is_cross() -> bool {
|
pub fn is_cross() -> bool {
|
||||||
std::env::var("CROSS_RUNNER").ok().map_or(false, |v| !v.is_empty())
|
std::env::var("CROSS_RUNNER").ok().map_or(false, |v| !v.is_empty())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Strips absolutely fucked `<jemalloc>:` lines from the output.
|
||||||
|
///
|
||||||
|
/// In theory this only happens under qemu, which is where our tests run under
|
||||||
|
/// `cross`. But is messes with our tests, because... they don't expect the
|
||||||
|
/// allocator to fucking write to stderr. I mean, what the fuck? Who prints a
|
||||||
|
/// warning message with absolutely no instruction for what to do with it or
|
||||||
|
/// how to disable it. Absolutely fucking bonkers.
|
||||||
|
fn strip_jemalloc_nonsense(data: &[u8]) -> Vec<u8> {
|
||||||
|
let lines = data
|
||||||
|
.lines_with_terminator()
|
||||||
|
.filter(|line| !line.starts_with_str("<jemalloc>:"));
|
||||||
|
bstr::concat(lines)
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user