Compare commits

..

25 Commits
0.5.0 ... 0.5.1

Author SHA1 Message Date
Andrew Gallant
ac1c95a6d9 0.5.1 2017-04-09 09:47:00 -04:00
Andrew Gallant
685b431d80 bump deps 2017-04-09 09:46:37 -04:00
Andrew Gallant
487713aa34 bump ignore 2017-04-09 09:45:00 -04:00
Andrew Gallant
e300541701 changelog 0.5.1 2017-04-09 09:43:16 -04:00
Andrew Gallant
e9df420d2f Add ability to colorize column numbers.
Fixes #377
2017-04-09 09:08:49 -04:00
Andrew Gallant
201b4fc757 update man page 2017-04-09 08:49:19 -04:00
Roman Proskuryakov
90a11dec5e Add -o/--only-matching flag.
Currently, the `--only-matching` flag conflicts with the `--replace`
flag. In the future, this restriction may be relaxed.

Fixes #34
2017-04-09 08:47:35 -04:00
Douman
9456d95e8f Add short note on Windows Tips 2017-04-09 08:32:23 -04:00
Kevin K
0c298f60a6 updates clap and removes home rolled -h/--help distinction
This commit updates clap to v2.23.0

The update contained a bug fix in clap that results in broken code in
ripgrep. ripgrep was relying on the bug, but this commit fixes that
issue. The bug centered around not being able to override the
auto-generated help message by supplying a flag with a long of `help`.

Normally, supplying a flag with a long of `help` means whenever the user
passes `--help`, the consuming code (e.g. ripgrep) is responsible for
displaying the help message. However, due to the bug in clap this wasn't
necessary for ripgrep to do unless the user passed `-h`. With the bug
fixed, it meant the user passing `--help` and clap expected ripgrep to
display the help, yet ripgrep expected clap to display the help. This
has been fixed in this commit of ripgrep.

All well now!

v2.23.0 also brings the abilty to use `Arg::help` or `Arg::long_help`
allowing one to distinguish between `-h` and `--help`. This commit
leaves all doc strings in the `lazy_static!` hashmap however only for
aesthetic reasons.

This means all home rolled handling of `-h`/`--help` has been removed
from ripgrep, yet functionality *and* appearances are 100% the same.
2017-04-05 11:38:58 -04:00
Kosta Welke
79271fcb33 fix typo in comment 2017-04-05 07:06:58 -04:00
Andrew Gallant
fc975af8e9 Enforce 79 column limit. Grr. 2017-03-31 15:59:04 -04:00
Roman Proskuryakov
1425d6735e Bamp clap to 2.22.2
Fixes #426 , #418
2017-03-31 15:56:10 -04:00
Roman Proskuryakov
aed3ccb9c7 Improves Printer, fixes some bugs 2017-03-31 14:44:13 -04:00
Andrew Gallant
33c95d2919 bump deps 2017-03-30 12:33:31 -04:00
Roman Proskuryakov
01deac9427 Add -0 shortcut for --null
Fixes #419
2017-03-28 18:37:40 -04:00
Andrew Gallant
b4bc3b6349 remove uninstall step 2017-03-28 12:14:15 -04:00
Andrew Gallant
685cc6c562 Add vim type.
It's the same as the vimscript type, but shorter and more obvious.

Fixes #415
2017-03-21 07:56:49 -04:00
Andrew Gallant
08c017330f bump termcolor dep 2017-03-15 07:15:39 -04:00
Andrew Gallant
2f3a8c7f69 termcolor-0.3.2 2017-03-15 06:58:09 -04:00
Andrew Gallant
3ac1b68e54 Add license info to termcolor crate.
Fixes #381
2017-03-15 06:57:54 -04:00
Andrew Gallant
0ebd5465b7 remove allow(dead_code) 2017-03-14 15:09:24 -04:00
Andrew Gallant
5cb4bb9ea0 bump ripgrep version in Cargo.lock 2017-03-14 15:09:24 -04:00
Leaf Garland
c8a179b4da Add powershell completions to build artifacts
Use a `ps:` (powershell) command to copy the completions file so that we
can use directory globbing to find the file.
2017-03-14 08:53:04 -04:00
Andrew Gallant
46f94826fd Update whirlwind tour with encoding info.
Fixes #1
2017-03-14 08:22:37 -04:00
Andrew Gallant
75f1855a91 Fix brew tap sha256 sum.
Fixes #407
2017-03-13 06:50:45 -04:00
22 changed files with 366 additions and 183 deletions

View File

@@ -1,3 +1,26 @@
0.5.1 (2017-04-09)
==================
Feature enhancements:
* Added or improved file type filtering for vim.
* [FEATURE #34](https://github.com/BurntSushi/ripgrep/issues/34):
Add a `-o/--only-matching` flag.
* [FEATURE #377](https://github.com/BurntSushi/ripgrep/issues/377):
Column numbers can now be customized with a color. (The default is
no color.)
* [FEATURE #419](https://github.com/BurntSushi/ripgrep/issues/419):
Added `-0` short flag option for `--null`.
Bug fixes:
* [BUG #381](https://github.com/BurntSushi/ripgrep/issues/381):
Include license text in all subcrates.
* [BUG #418](https://github.com/BurntSushi/ripgrep/issues/418),
[BUG #426](https://github.com/BurntSushi/ripgrep/issues/426),
[BUG #439](https://github.com/BurntSushi/ripgrep/issues/439):
Fix a few bugs with `-h/--help` output.
0.5.0 (2017-03-12) 0.5.0 (2017-03-12)
================== ==================
This is a new minor version release of ripgrep that includes one minor breaking This is a new minor version release of ripgrep that includes one minor breaking

38
Cargo.lock generated
View File

@@ -1,15 +1,15 @@
[root] [root]
name = "ripgrep" name = "ripgrep"
version = "0.4.0" version = "0.5.1"
dependencies = [ dependencies = [
"atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bytecount 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "bytecount 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.21.1 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.23.1 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding_rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "encoding_rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"grep 0.1.6", "grep 0.1.6",
"ignore 0.1.8", "ignore 0.1.9",
"lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -17,12 +17,12 @@ dependencies = [
"num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 0.3.1", "termcolor 0.3.2",
] ]
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "0.6.2" version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -45,7 +45,7 @@ dependencies = [
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "0.8.0" version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@@ -63,12 +63,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "clap" name = "clap"
version = "2.21.1" version = "2.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -116,7 +116,7 @@ dependencies = [
name = "globset" name = "globset"
version = "0.1.4" version = "0.1.4"
dependencies = [ dependencies = [
"aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -135,11 +135,11 @@ dependencies = [
[[package]] [[package]]
name = "ignore" name = "ignore"
version = "0.1.8" version = "0.1.9"
dependencies = [ dependencies = [
"crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"globset 0.1.4", "globset 0.1.4",
"lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -158,7 +158,7 @@ dependencies = [
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "0.2.4" version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@@ -203,7 +203,7 @@ name = "regex"
version = "0.2.1" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"simd 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "simd 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -247,7 +247,7 @@ dependencies = [
[[package]] [[package]]
name = "termcolor" name = "termcolor"
version = "0.3.1" version = "0.3.2"
dependencies = [ dependencies = [
"wincolor 0.1.3", "wincolor 0.1.3",
] ]
@@ -332,20 +332,20 @@ dependencies = [
] ]
[metadata] [metadata]
"checksum aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0638fd549427caa90c499814196d1b9e3725eb4d15d7339d6de073a680ed0ca2" "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159" "checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
"checksum bitflags 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e1ab483fc81a8143faa7203c4a3c02888ebd1a782e37e41fa34753ba9a162" "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
"checksum bytecount 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1e8f09fbc8c6726a4b616dcfbd4f54491068d6bb1b93ac03c78ac18ff9a5924a" "checksum bytecount 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1e8f09fbc8c6726a4b616dcfbd4f54491068d6bb1b93ac03c78ac18ff9a5924a"
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c" "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
"checksum clap 2.21.1 (registry+https://github.com/rust-lang/crates.io-index)" = "74a80f603221c9cd9aa27a28f52af452850051598537bb6b359c38a7d61e5cda" "checksum clap 2.23.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d480c39a2e5f9b3a3798c661613e1b0e7a7ae71e005102d4aa910fc3289df484"
"checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97" "checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97"
"checksum encoding_rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a1cca0a26f904955d80d70b9bff1019e4f4cbc06f2fcbccf8bd3d889cc1c9b7" "checksum encoding_rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a1cca0a26f904955d80d70b9bff1019e4f4cbc06f2fcbccf8bd3d889cc1c9b7"
"checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83" "checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83"
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
"checksum fs2 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34edaee07555859dc13ca387e6ae05686bb4d0364c95d649b6dab959511f4baf" "checksum fs2 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34edaee07555859dc13ca387e6ae05686bb4d0364c95d649b6dab959511f4baf"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7291b1dd97d331f752620b02dfdbc231df7fc01bf282a00769e1cdb963c460dc" "checksum lazy_static 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2f61b8421c7a4648c391611625d56fdd5c7567da05af1be655fd8cacc643abb3"
"checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135" "checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135"
"checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad" "checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad"
"checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4" "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "ripgrep" name = "ripgrep"
version = "0.5.0" #:version version = "0.5.1" #:version
authors = ["Andrew Gallant <jamslam@gmail.com>"] authors = ["Andrew Gallant <jamslam@gmail.com>"]
description = """ description = """
Line oriented search tool using Rust's regex library. Combines the raw Line oriented search tool using Rust's regex library. Combines the raw
@@ -28,11 +28,11 @@ path = "tests/tests.rs"
[dependencies] [dependencies]
atty = "0.2.2" atty = "0.2.2"
bytecount = "0.1.4" bytecount = "0.1.4"
clap = "2.20.5" clap = "2.23.1"
encoding_rs = "0.5.0" encoding_rs = "0.5.0"
env_logger = { version = "0.4", default-features = false } env_logger = { version = "0.4", default-features = false }
grep = { version = "0.1.5", path = "grep" } grep = { version = "0.1.5", path = "grep" }
ignore = { version = "0.1.7", path = "ignore" } ignore = { version = "0.1.9", path = "ignore" }
lazy_static = "0.2" lazy_static = "0.2"
libc = "0.2" libc = "0.2"
log = "0.3" log = "0.3"
@@ -44,7 +44,7 @@ same-file = "0.1.1"
termcolor = { version = "0.3.0", path = "termcolor" } termcolor = { version = "0.3.0", path = "termcolor" }
[build-dependencies] [build-dependencies]
clap = "2.18" clap = "2.23.1"
lazy_static = "0.2" lazy_static = "0.2"
[features] [features]

View File

@@ -230,11 +230,10 @@ colorize your output and show line numbers, just like The Silver Searcher.
Coloring works on Windows too! Colors can be controlled more granularly with Coloring works on Windows too! Colors can be controlled more granularly with
the `--color` flag. the `--color` flag.
One last thing before we get started: `ripgrep` assumes UTF-8 *everywhere*. It One last thing before we get started: generally speaking, `ripgrep` assumes the
can still search files that are invalid UTF-8 (like, say, latin-1), but it will input is reading is UTF-8. However, if ripgrep notices a file is encoded as
simply not work on UTF-16 encoded files or other more exotic encodings. UTF-16, then it will know how to search it. For other encodings, you'll need to
[Support for other encodings may explicitly specify them with the `-E/--encoding` flag.
happen.](https://github.com/BurntSushi/ripgrep/issues/1)
To recursively search the current directory, while respecting all `.gitignore` To recursively search the current directory, while respecting all `.gitignore`
files, ignore hidden files and directories and skip binary files: files, ignore hidden files and directories and skip binary files:
@@ -379,6 +378,51 @@ $ cargo test
from the repository root. from the repository root.
### Tips
#### Windows Powershell
##### Powershell Profile
To customize powershell on start-up there is a special powershell script that has to be created.
In order to find its location run command `Get-Command $profile | Select-Object -ExpandProperty Definition`
See [more](https://technet.microsoft.com/en-us/library/bb613488(v=vs.85).aspx) for profile details.
Any powershell code in this file gets evaluated at the start of console.
This way you can have own aliases to be created at start.
##### Setup function alias
Often you can find a need to make alias for the favourite utility.
But powershell function aliases do not behave like your typical linux shell alias.
You always need to propagate arguments and **Stdin** input.
But it cannot be done simply as `function grep() { $input | rg.exe --hidden $args }`
Use below example as reference to how setup alias in powershell.
```powershell
function grep {
$count = @($input).Count
$input.Reset()
if ($count) {
$input | rg.exe --hidden $args
}
else {
rg.exe --hidden $args
}
}
```
Powershell special variables:
* input - is powershell **Stdin** object that allows you to access its content.
* args - is array of arguments passed to this function.
This alias checks whether there is **Stdin** input and propagates only if there is some lines.
Otherwise empty `$input` will make powershell to trigger `rg` to search empty **Stdin**
### Known issues ### Known issues
#### I just hit Ctrl+C in the middle of ripgrep's output and now my terminal's foreground color is wrong! #### I just hit Ctrl+C in the middle of ripgrep's output and now my terminal's foreground color is wrong!

View File

@@ -40,6 +40,7 @@ before_deploy:
- cargo build --release - cargo build --release
- mkdir staging - mkdir staging
- copy target\release\rg.exe staging - copy target\release\rg.exe staging
- ps: copy target\release\build\ripgrep-*\out\_rg.ps1 staging
- cd staging - cd staging
# release zipfile will look like 'rust-everywhere-v1.2.3-x86_64-pc-windows-msvc' # release zipfile will look like 'rust-everywhere-v1.2.3-x86_64-pc-windows-msvc'
- 7z a ../%PROJECT_NAME%-%APPVEYOR_REPO_TAG_NAME%-%TARGET%.zip * - 7z a ../%PROJECT_NAME%-%APPVEYOR_REPO_TAG_NAME%-%TARGET%.zip *

View File

@@ -19,7 +19,7 @@ fn main() {
}; };
fs::create_dir_all(&outdir).unwrap(); fs::create_dir_all(&outdir).unwrap();
let mut app = app::app_short(); let mut app = app::app();
app.gen_completions("rg", Shell::Bash, &outdir); app.gen_completions("rg", Shell::Bash, &outdir);
app.gen_completions("rg", Shell::Fish, &outdir); app.gen_completions("rg", Shell::Fish, &outdir);
app.gen_completions("rg", Shell::Zsh, &outdir); app.gen_completions("rg", Shell::Zsh, &outdir);

View File

@@ -17,9 +17,6 @@ install_c_toolchain() {
} }
install_rustup() { install_rustup() {
# uninstall the rust toolchain installed by travis, we are going to use rustup
sh ~/rust/lib/rustlib/uninstall.sh
curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain=$TRAVIS_RUST_VERSION curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain=$TRAVIS_RUST_VERSION
rustc -V rustc -V

View File

@@ -181,7 +181,7 @@ Styles are limited to nobold, bold, nointense or intense.
.RS .RS
.PP .PP
The format of the flag is {type}:{attribute}:{value}. The format of the flag is {type}:{attribute}:{value}.
{type} should be one of path, line or match. {type} should be one of path, line, column or match.
{attribute} can be fg, bg or style. {attribute} can be fg, bg or style.
Value is either a color (for fg and bg) or a text style. Value is either a color (for fg and bg) or a text style.
A special format, {type}:none, will clear all color settings for {type}. A special format, {type}:none, will clear all color settings for {type}.
@@ -299,6 +299,13 @@ Follow symlinks.
.RS .RS
.RE .RE
.TP .TP
.B \-M, \-\-max\-columns \f[I]NUM\f[]
Don\[aq]t print lines longer than this limit in bytes.
Longer lines are omitted, and only the number of matches in that line is
printed.
.RS
.RE
.TP
.B \-m, \-\-max\-count \f[I]NUM\f[] .B \-m, \-\-max\-count \f[I]NUM\f[]
Limit the number of matching lines per file searched to NUM. Limit the number of matching lines per file searched to NUM.
.RS .RS
@@ -355,7 +362,7 @@ Note that .ignore files will continue to be respected.
.RS .RS
.RE .RE
.TP .TP
.B \-\-null .B \-0, \-\-null
Whenever a file name is printed, follow it with a NUL byte. Whenever a file name is printed, follow it with a NUL byte.
This includes printing filenames before matches, and when printing a This includes printing filenames before matches, and when printing a
list of matching files such as with \-\-count, \-\-files\-with\-matches list of matching files such as with \-\-count, \-\-files\-with\-matches
@@ -363,6 +370,12 @@ and \-\-files.
.RS .RS
.RE .RE
.TP .TP
.B \-o, \-\-only\-matching
Print only the matched (non\-empty) parts of a matching line, with each
such part on a separate output line.
.RS
.RE
.TP
.B \-\-path\-separator \f[I]SEPARATOR\f[] .B \-\-path\-separator \f[I]SEPARATOR\f[]
The path separator to use when printing file paths. The path separator to use when printing file paths.
This defaults to your platform\[aq]s path separator, which is / on Unix This defaults to your platform\[aq]s path separator, which is / on Unix

View File

@@ -123,9 +123,9 @@ Project home page: https://github.com/BurntSushi/ripgrep
black. Styles are limited to nobold, bold, nointense or intense. black. Styles are limited to nobold, bold, nointense or intense.
The format of the flag is {type}:{attribute}:{value}. {type} should be one The format of the flag is {type}:{attribute}:{value}. {type} should be one
of path, line or match. {attribute} can be fg, bg or style. Value is either of path, line, column or match. {attribute} can be fg, bg or style. Value
a color (for fg and bg) or a text style. A special format, {type}:none, is either a color (for fg and bg) or a text style. A special format,
will clear all color settings for {type}. {type}:none, will clear all color settings for {type}.
For example, the following command will change the match color to magenta For example, the following command will change the match color to magenta
and the background color for line numbers to yellow: and the background color for line numbers to yellow:
@@ -243,12 +243,16 @@ Project home page: https://github.com/BurntSushi/ripgrep
: Don't respect version control ignore files (e.g., .gitignore). : Don't respect version control ignore files (e.g., .gitignore).
Note that .ignore files will continue to be respected. Note that .ignore files will continue to be respected.
--null -0, --null
: Whenever a file name is printed, follow it with a NUL byte. : Whenever a file name is printed, follow it with a NUL byte.
This includes printing filenames before matches, and when printing This includes printing filenames before matches, and when printing
a list of matching files such as with --count, --files-with-matches a list of matching files such as with --count, --files-with-matches
and --files. and --files.
-o, --only-matching
: Print only the matched (non-empty) parts of a matching line, with each such
part on a separate output line.
--path-separator *SEPARATOR* --path-separator *SEPARATOR*
: The path separator to use when printing file paths. This defaults to your : The path separator to use when printing file paths. This defaults to your
platform's path separator, which is / on Unix and \\ on Windows. This flag is platform's path separator, which is / on Unix and \\ on Windows. This flag is

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "ignore" name = "ignore"
version = "0.1.8" #:version version = "0.1.9" #:version
authors = ["Andrew Gallant <jamslam@gmail.com>"] authors = ["Andrew Gallant <jamslam@gmail.com>"]
description = """ description = """
A fast library for efficiently matching ignore files such as `.gitignore` A fast library for efficiently matching ignore files such as `.gitignore`

View File

@@ -191,6 +191,7 @@ const DEFAULT_TYPES: &'static [(&'static str, &'static [&'static str])] = &[
("twig", &["*.twig"]), ("twig", &["*.twig"]),
("vala", &["*.vala"]), ("vala", &["*.vala"]),
("vb", &["*.vb"]), ("vb", &["*.vb"]),
("vim", &["*.vim"]),
("vimscript", &["*.vim"]), ("vimscript", &["*.vim"]),
("wiki", &["*.mediawiki", "*.wiki"]), ("wiki", &["*.mediawiki", "*.wiki"]),
("xml", &["*.xml"]), ("xml", &["*.xml"]),

View File

@@ -3,7 +3,7 @@ class RipgrepBin < Formula
desc "Search tool like grep and The Silver Searcher." desc "Search tool like grep and The Silver Searcher."
homepage "https://github.com/BurntSushi/ripgrep" homepage "https://github.com/BurntSushi/ripgrep"
url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-apple-darwin.tar.gz" url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-apple-darwin.tar.gz"
sha256 "efdc64456fc64910c2998b25c402aac2ff17caf1507e8bcca4584b429ef7f7ae" sha256 "5bfa8872c4f2a5d010ddec1c213d518056e62d4dd3b3f23a0ef099b85343dbdd"
conflicts_with "ripgrep" conflicts_with "ripgrep"

View File

@@ -32,16 +32,6 @@ ARGS:
OPTIONS: OPTIONS:
{unified}"; {unified}";
/// Build a clap application with short help strings.
pub fn app_short() -> App<'static, 'static> {
app(false, |k| USAGES[k].short)
}
/// Build a clap application with long help strings.
pub fn app_long() -> App<'static, 'static> {
app(true, |k| USAGES[k].long)
}
/// Build a clap application parameterized by usage strings. /// Build a clap application parameterized by usage strings.
/// ///
/// The function given should take a clap argument name and return a help /// The function given should take a clap argument name and return a help
@@ -49,10 +39,9 @@ pub fn app_long() -> App<'static, 'static> {
/// ///
/// This is an intentionally stand-alone module so that it can be used easily /// This is an intentionally stand-alone module so that it can be used easily
/// in a `build.rs` script to build shell completion files. /// in a `build.rs` script to build shell completion files.
fn app<F>(next_line_help: bool, doc: F) -> App<'static, 'static> pub fn app() -> App<'static, 'static> {
where F: Fn(&'static str) -> &'static str {
let arg = |name| { let arg = |name| {
Arg::with_name(name).help(doc(name)).next_line_help(next_line_help) Arg::with_name(name).help(USAGES[name].short).long_help(USAGES[name].long)
}; };
let flag = |name| arg(name).long(name); let flag = |name| arg(name).long(name);
@@ -64,11 +53,7 @@ fn app<F>(next_line_help: bool, doc: F) -> App<'static, 'static>
.setting(AppSettings::UnifiedHelpMessage) .setting(AppSettings::UnifiedHelpMessage)
.usage(USAGE) .usage(USAGE)
.template(TEMPLATE) .template(TEMPLATE)
// Handle help/version manually to make their output formatting .help_message("Prints help information. Use --help for more details.")
// consistent with short/long views.
.arg(arg("help-short").short("h"))
.arg(flag("help"))
.arg(arg("ripgrep-version").long("version").short("V"))
// First, set up primary positional/flag arguments. // First, set up primary positional/flag arguments.
.arg(arg("pattern") .arg(arg("pattern")
.required_unless_one(&[ .required_unless_one(&[
@@ -158,7 +143,8 @@ fn app<F>(next_line_help: bool, doc: F) -> App<'static, 'static>
.arg(flag("no-ignore")) .arg(flag("no-ignore"))
.arg(flag("no-ignore-parent")) .arg(flag("no-ignore-parent"))
.arg(flag("no-ignore-vcs")) .arg(flag("no-ignore-vcs"))
.arg(flag("null")) .arg(flag("null").short("0"))
.arg(flag("only-matching").short("o").conflicts_with("replace"))
.arg(flag("path-separator").value_name("SEPARATOR").takes_value(true)) .arg(flag("path-separator").value_name("SEPARATOR").takes_value(true))
.arg(flag("pretty").short("p")) .arg(flag("pretty").short("p"))
.arg(flag("replace").short("r").value_name("ARG").takes_value(true)) .arg(flag("replace").short("r").value_name("ARG").takes_value(true))
@@ -249,12 +235,12 @@ lazy_static! {
red, blue, green, cyan, magenta, yellow, white and black. \ red, blue, green, cyan, magenta, yellow, white and black. \
Styles are limited to nobold, bold, nointense or intense.\n\n\ Styles are limited to nobold, bold, nointense or intense.\n\n\
The format of the flag is {type}:{attribute}:{value}. {type} \ The format of the flag is {type}:{attribute}:{value}. {type} \
should be one of path, line or match. {attribute} can be fg, bg \ should be one of path, line, column or match. {attribute} can \
or style. {value} is either a color (for fg and bg) or a text \ be fg, bg or style. {value} is either a color (for fg and bg) \
style. A special format, {type}:none, will clear all color \ or a text style. A special format, {type}:none, will clear all \
settings for {type}.\n\nFor example, the following command will \ color settings for {type}.\n\nFor example, the following \
change the match color to magenta and the background color for \ command will change the match color to magenta and the \
line numbers to yellow:\n\n\ background color for line numbers to yellow:\n\n\
rg --colors 'match:fg:magenta' --colors 'line:bg:yellow' foo."); rg --colors 'match:fg:magenta' --colors 'line:bg:yellow' foo.");
doc!(h, "encoding", doc!(h, "encoding",
"Specify the text encoding of files to search.", "Specify the text encoding of files to search.",
@@ -388,10 +374,11 @@ lazy_static! {
"Limit the number of matching lines per file searched to NUM."); "Limit the number of matching lines per file searched to NUM.");
doc!(h, "max-filesize", doc!(h, "max-filesize",
"Ignore files larger than NUM in size.", "Ignore files larger than NUM in size.",
"Ignore files larger than NUM in size. Does not ignore directories. \ "Ignore files larger than NUM in size. Does not ignore \
directories. \
\n\nThe input format accepts suffixes of K, M or G which \ \n\nThe input format accepts suffixes of K, M or G which \
correspond to kilobytes, megabytes and gigabytes. If no suffix is \ correspond to kilobytes, megabytes and gigabytes. If no suffix \
provided the input is treated as bytes. \ is provided the input is treated as bytes. \
\n\nExample: --max-filesize 50K or --max-filesize 80M"); \n\nExample: --max-filesize 50K or --max-filesize 80M");
doc!(h, "maxdepth", doc!(h, "maxdepth",
"Descend at most NUM directories.", "Descend at most NUM directories.",
@@ -435,6 +422,10 @@ lazy_static! {
printing a list of matching files such as with --count, \ printing a list of matching files such as with --count, \
--files-with-matches and --files. This option is useful for use \ --files-with-matches and --files. This option is useful for use \
with xargs."); with xargs.");
doc!(h, "only-matching",
"Print only matched parts of a line.",
"Print only the matched (non-empty) parts of a matching line, \
with each such part on a separate output line.");
doc!(h, "path-separator", doc!(h, "path-separator",
"Path separator to use when printing file paths.", "Path separator to use when printing file paths.",
"The path separator to use when printing file paths. This \ "The path separator to use when printing file paths. This \
@@ -496,8 +487,8 @@ lazy_static! {
permits specifying one or more other type names (separated by a \ permits specifying one or more other type names (separated by a \
comma) that have been defined and its rules will automatically \ comma) that have been defined and its rules will automatically \
be imported into the type specified. For example, to create a \ be imported into the type specified. For example, to create a \
type called src that matches C++, Python and Markdown files, one \ type called src that matches C++, Python and Markdown files, \
can use:\n\n\ one can use:\n\n\
--type-add 'src:include:cpp,py,md'\n\n\ --type-add 'src:include:cpp,py,md'\n\n\
Additional glob rules can still be added to the src type by \ Additional glob rules can still be added to the src type by \
using the --type-add flag again:\n\n\ using the --type-add flag again:\n\n\

View File

@@ -5,7 +5,6 @@ use std::fs;
use std::io::{self, BufRead}; use std::io::{self, BufRead};
use std::ops; use std::ops;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process;
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
@@ -66,6 +65,7 @@ pub struct Args {
no_ignore_vcs: bool, no_ignore_vcs: bool,
no_messages: bool, no_messages: bool,
null: bool, null: bool,
only_matching: bool,
path_separator: Option<u8>, path_separator: Option<u8>,
quiet: bool, quiet: bool,
quiet_matched: QuietMatched, quiet_matched: QuietMatched,
@@ -88,26 +88,7 @@ impl Args {
/// ///
/// Also, initialize a global logger. /// Also, initialize a global logger.
pub fn parse() -> Result<Args> { pub fn parse() -> Result<Args> {
use clap::ErrorKind::*; let matches = app::app().get_matches();
let matches = match app::app_short().get_matches_safe() {
Ok(matches) => matches,
Err(clap::Error { kind: HelpDisplayed, .. }) => {
let _ = ::app::app_long().print_help();
println!("");
process::exit(0);
}
Err(err) => err.exit(),
};
if matches.is_present("help-short") {
let _ = ::app::app_short().print_help();
println!("");
process::exit(0);
}
if matches.is_present("ripgrep-version") {
println!("ripgrep {}", crate_version!());
process::exit(0);
}
let mut logb = env_logger::LogBuilder::new(); let mut logb = env_logger::LogBuilder::new();
if matches.is_present("debug") { if matches.is_present("debug") {
@@ -161,6 +142,7 @@ impl Args {
.heading(self.heading) .heading(self.heading)
.line_per_match(self.line_per_match) .line_per_match(self.line_per_match)
.null(self.null) .null(self.null)
.only_matching(self.only_matching)
.path_separator(self.path_separator) .path_separator(self.path_separator)
.with_filename(self.with_filename) .with_filename(self.with_filename)
.max_columns(self.max_columns); .max_columns(self.max_columns);
@@ -365,6 +347,7 @@ impl<'a> ArgMatches<'a> {
no_ignore_vcs: self.no_ignore_vcs(), no_ignore_vcs: self.no_ignore_vcs(),
no_messages: self.is_present("no-messages"), no_messages: self.is_present("no-messages"),
null: self.is_present("null"), null: self.is_present("null"),
only_matching: self.is_present("only-matching"),
path_separator: try!(self.path_separator()), path_separator: try!(self.path_separator()),
quiet: quiet, quiet: quiet,
quiet_matched: QuietMatched::new(quiet), quiet_matched: QuietMatched::new(quiet),
@@ -837,7 +820,7 @@ impl<'a> ArgMatches<'a> {
let caps = try!(re.captures(&max_filesize) let caps = try!(re.captures(&max_filesize)
.ok_or("invalid format for max-filesize argument")); .ok_or("invalid format for max-filesize argument"));
let value = try!(caps[1].parse::<u64>().map_err(|err| err.to_string())); let value = try!(caps[1].parse::<u64>().map_err(|err|err.to_string()));
let suffix = caps.get(2).map(|x| x.as_str()); let suffix = caps.get(2).map(|x| x.as_str());
match suffix { match suffix {

View File

@@ -1,5 +1,3 @@
#![allow(dead_code)]
use std::cmp; use std::cmp;
use std::io::{self, Read}; use std::io::{self, Read};
@@ -290,10 +288,6 @@ mod tests {
use super::{Bom, BomPeeker, DecodeReader}; use super::{Bom, BomPeeker, DecodeReader};
fn utf8(bytes: &[u8]) -> &str {
::std::str::from_utf8(bytes).unwrap()
}
fn read_to_string<R: Read>(mut rdr: R) -> String { fn read_to_string<R: Read>(mut rdr: R) -> String {
let mut s = String::new(); let mut s = String::new();
rdr.read_to_string(&mut s).unwrap(); rdr.read_to_string(&mut s).unwrap();
@@ -453,7 +447,8 @@ mod tests {
test_trans_simple!(trans_simple_utf16be, "utf-16be", b"\x04\x16", "Ж"); test_trans_simple!(trans_simple_utf16be, "utf-16be", b"\x04\x16", "Ж");
test_trans_simple!(trans_simple_chinese, "chinese", b"\xA7\xA8", "Ж"); test_trans_simple!(trans_simple_chinese, "chinese", b"\xA7\xA8", "Ж");
test_trans_simple!(trans_simple_korean, "korean", b"\xAC\xA8", "Ж"); test_trans_simple!(trans_simple_korean, "korean", b"\xAC\xA8", "Ж");
test_trans_simple!(trans_simple_big5_hkscs, "big5-hkscs", b"\xC7\xFA", "Ж"); test_trans_simple!(
trans_simple_big5_hkscs, "big5-hkscs", b"\xC7\xFA", "Ж");
test_trans_simple!(trans_simple_gbk, "gbk", b"\xA7\xA8", "Ж"); test_trans_simple!(trans_simple_gbk, "gbk", b"\xA7\xA8", "Ж");
test_trans_simple!(trans_simple_sjis, "sjis", b"\x84\x47", "Ж"); test_trans_simple!(trans_simple_sjis, "sjis", b"\x84\x47", "Ж");
test_trans_simple!(trans_simple_eucjp, "euc-jp", b"\xA7\xA8", "Ж"); test_trans_simple!(trans_simple_eucjp, "euc-jp", b"\xA7\xA8", "Ж");

View File

@@ -58,6 +58,8 @@ pub struct Printer<W> {
/// Whether to print NUL bytes after a file path instead of new lines /// Whether to print NUL bytes after a file path instead of new lines
/// or `:`. /// or `:`.
null: bool, null: bool,
/// Print only the matched (non-empty) parts of a matching line
only_matching: bool,
/// A string to use as a replacement of each match in a matching line. /// A string to use as a replacement of each match in a matching line.
replace: Option<Vec<u8>>, replace: Option<Vec<u8>>,
/// Whether to prefix each match with the corresponding file name. /// Whether to prefix each match with the corresponding file name.
@@ -83,6 +85,7 @@ impl<W: WriteColor> Printer<W> {
heading: false, heading: false,
line_per_match: false, line_per_match: false,
null: false, null: false,
only_matching: false,
replace: None, replace: None,
with_filename: false, with_filename: false,
colors: ColorSpecs::default(), colors: ColorSpecs::default(),
@@ -144,6 +147,12 @@ impl<W: WriteColor> Printer<W> {
self self
} }
/// Print only the matched (non-empty) parts of a matching line
pub fn only_matching(mut self, yes: bool) -> Printer<W> {
self.only_matching = yes;
self
}
/// A separator to use when printing file paths. When empty, use the /// A separator to use when printing file paths. When empty, use the
/// default separator for the current platform. (/ on Unix, \ on Windows.) /// default separator for the current platform. (/ on Unix, \ on Windows.)
pub fn path_separator(mut self, sep: Option<u8>) -> Printer<W> { pub fn path_separator(mut self, sep: Option<u8>) -> Printer<W> {
@@ -153,9 +162,6 @@ impl<W: WriteColor> Printer<W> {
/// Replace every match in each matching line with the replacement string /// Replace every match in each matching line with the replacement string
/// given. /// given.
///
/// The replacement string syntax is documented here:
/// https://doc.rust-lang.org/regex/regex/bytes/struct.Captures.html#method.expand
pub fn replace(mut self, replacement: Vec<u8>) -> Printer<W> { pub fn replace(mut self, replacement: Vec<u8>) -> Printer<W> {
self.replace = Some(replacement); self.replace = Some(replacement);
self self
@@ -204,22 +210,14 @@ impl<W: WriteColor> Printer<W> {
pub fn path<P: AsRef<Path>>(&mut self, path: P) { pub fn path<P: AsRef<Path>>(&mut self, path: P) {
let path = strip_prefix("./", path.as_ref()).unwrap_or(path.as_ref()); let path = strip_prefix("./", path.as_ref()).unwrap_or(path.as_ref());
self.write_path(path); self.write_path(path);
if self.null { self.write_path_eol();
self.write(b"\x00");
} else {
self.write_eol();
}
} }
/// Prints the given path and a count of the number of matches found. /// Prints the given path and a count of the number of matches found.
pub fn path_count<P: AsRef<Path>>(&mut self, path: P, count: u64) { pub fn path_count<P: AsRef<Path>>(&mut self, path: P, count: u64) {
if self.with_filename { if self.with_filename {
self.write_path(path); self.write_path(path);
if self.null { self.write_path_sep(b':');
self.write(b"\x00");
} else {
self.write(b":");
}
} }
self.write(count.to_string().as_bytes()); self.write(count.to_string().as_bytes());
self.write_eol(); self.write_eol();
@@ -227,13 +225,11 @@ impl<W: WriteColor> Printer<W> {
/// Prints the context separator. /// Prints the context separator.
pub fn context_separate(&mut self) { pub fn context_separate(&mut self) {
// N.B. We can't use `write` here because of borrowing restrictions.
if self.context_separator.is_empty() { if self.context_separator.is_empty() {
return; return;
} }
self.has_printed = true;
let _ = self.wtr.write_all(&self.context_separator); let _ = self.wtr.write_all(&self.context_separator);
let _ = self.wtr.write_all(&[self.eol]); self.write_eol();
} }
pub fn matched<P: AsRef<Path>>( pub fn matched<P: AsRef<Path>>(
@@ -245,7 +241,7 @@ impl<W: WriteColor> Printer<W> {
end: usize, end: usize,
line_number: Option<u64>, line_number: Option<u64>,
) { ) {
if !self.line_per_match { if !self.line_per_match && !self.only_matching {
let column = let column =
if self.column { if self.column {
Some(re.find(&buf[start..end]) Some(re.find(&buf[start..end])
@@ -280,16 +276,17 @@ impl<W: WriteColor> Printer<W> {
) { ) {
if self.heading && self.with_filename && !self.has_printed { if self.heading && self.with_filename && !self.has_printed {
self.write_file_sep(); self.write_file_sep();
self.write_heading(path.as_ref()); self.write_path(path);
self.write_path_eol();
} else if !self.heading && self.with_filename { } else if !self.heading && self.with_filename {
self.write_non_heading_path(path.as_ref()); self.write_path(path);
self.write_path_sep(b':');
} }
if let Some(line_number) = line_number { if let Some(line_number) = line_number {
self.line_number(line_number, b':'); self.line_number(line_number, b':');
} }
if let Some(c) = column { if let Some(c) = column {
self.write((c + 1).to_string().as_bytes()); self.column_number(c + 1, b':');
self.write(b":");
} }
if self.replace.is_some() { if self.replace.is_some() {
let mut count = 0; let mut count = 0;
@@ -299,11 +296,9 @@ impl<W: WriteColor> Printer<W> {
re.replace_all(&buf[start..end], replacer) re.replace_all(&buf[start..end], replacer)
}; };
if self.max_columns.map_or(false, |m| line.len() > m) { if self.max_columns.map_or(false, |m| line.len() > m) {
let _ = self.wtr.set_color(self.colors.matched());
let msg = format!( let msg = format!(
"[Omitted long line with {} replacements]", count); "[Omitted long line with {} replacements]", count);
self.write(msg.as_bytes()); self.write_colored(msg.as_bytes(), |colors| colors.matched());
let _ = self.wtr.reset();
self.write_eol(); self.write_eol();
return; return;
} }
@@ -312,7 +307,13 @@ impl<W: WriteColor> Printer<W> {
self.write_eol(); self.write_eol();
} }
} else { } else {
self.write_matched_line(re, &buf[start..end]); let line_buf = if self.only_matching {
let m = re.find(&buf[start..end]).unwrap();
&buf[start + m.start()..start + m.end()]
} else {
&buf[start..end]
};
self.write_matched_line(re, line_buf);
// write_matched_line guarantees to write a newline. // write_matched_line guarantees to write a newline.
} }
} }
@@ -320,10 +321,8 @@ impl<W: WriteColor> Printer<W> {
fn write_matched_line(&mut self, re: &Regex, buf: &[u8]) { fn write_matched_line(&mut self, re: &Regex, buf: &[u8]) {
if self.max_columns.map_or(false, |m| buf.len() > m) { if self.max_columns.map_or(false, |m| buf.len() > m) {
let count = re.find_iter(buf).count(); let count = re.find_iter(buf).count();
let _ = self.wtr.set_color(self.colors.matched());
let msg = format!("[Omitted long line with {} matches]", count); let msg = format!("[Omitted long line with {} matches]", count);
self.write(msg.as_bytes()); self.write_colored(msg.as_bytes(), |colors| colors.matched());
let _ = self.wtr.reset();
self.write_eol(); self.write_eol();
return; return;
} }
@@ -333,9 +332,8 @@ impl<W: WriteColor> Printer<W> {
let mut last_written = 0; let mut last_written = 0;
for m in re.find_iter(buf) { for m in re.find_iter(buf) {
self.write(&buf[last_written..m.start()]); self.write(&buf[last_written..m.start()]);
let _ = self.wtr.set_color(self.colors.matched()); self.write_colored(
self.write(&buf[m.start()..m.end()]); &buf[m.start()..m.end()], |colors| colors.matched());
let _ = self.wtr.reset();
last_written = m.end(); last_written = m.end();
} }
self.write(&buf[last_written..]); self.write(&buf[last_written..]);
@@ -355,14 +353,11 @@ impl<W: WriteColor> Printer<W> {
) { ) {
if self.heading && self.with_filename && !self.has_printed { if self.heading && self.with_filename && !self.has_printed {
self.write_file_sep(); self.write_file_sep();
self.write_heading(path.as_ref()); self.write_path(path);
self.write_path_eol();
} else if !self.heading && self.with_filename { } else if !self.heading && self.with_filename {
self.write_path(path.as_ref()); self.write_path(path);
if self.null { self.write_path_sep(b'-');
self.write(b"\x00");
} else {
self.write(b"-");
}
} }
if let Some(line_number) = line_number { if let Some(line_number) = line_number {
self.line_number(line_number, b'-'); self.line_number(line_number, b'-');
@@ -378,10 +373,19 @@ impl<W: WriteColor> Printer<W> {
} }
} }
fn write_heading<P: AsRef<Path>>(&mut self, path: P) { fn separator(&mut self, sep: &[u8]) {
let _ = self.wtr.set_color(self.colors.path()); self.write(&sep);
self.write_path(path.as_ref()); }
let _ = self.wtr.reset();
fn write_path_sep(&mut self, sep: u8) {
if self.null {
self.write(b"\x00");
} else {
self.separator(&[sep]);
}
}
fn write_path_eol(&mut self) {
if self.null { if self.null {
self.write(b"\x00"); self.write(b"\x00");
} else { } else {
@@ -389,52 +393,43 @@ impl<W: WriteColor> Printer<W> {
} }
} }
fn write_non_heading_path<P: AsRef<Path>>(&mut self, path: P) {
let _ = self.wtr.set_color(self.colors.path());
self.write_path(path.as_ref());
let _ = self.wtr.reset();
if self.null {
self.write(b"\x00");
} else {
self.write(b":");
}
}
fn line_number(&mut self, n: u64, sep: u8) {
let _ = self.wtr.set_color(self.colors.line());
self.write(n.to_string().as_bytes());
let _ = self.wtr.reset();
self.write(&[sep]);
}
#[cfg(unix)] #[cfg(unix)]
fn write_path<P: AsRef<Path>>(&mut self, path: P) { fn write_path<P: AsRef<Path>>(&mut self, path: P) {
use std::os::unix::ffi::OsStrExt; use std::os::unix::ffi::OsStrExt;
let path = path.as_ref().as_os_str().as_bytes(); let path = path.as_ref().as_os_str().as_bytes();
match self.path_separator { self.write_path_replace_separator(path);
None => self.write(path),
Some(sep) => self.write_path_with_sep(path, sep),
}
} }
#[cfg(not(unix))] #[cfg(not(unix))]
fn write_path<P: AsRef<Path>>(&mut self, path: P) { fn write_path<P: AsRef<Path>>(&mut self, path: P) {
let path = path.as_ref().to_string_lossy(); let path = path.as_ref().to_string_lossy();
self.write_path_replace_separator(path.as_bytes());
}
fn write_path_replace_separator(&mut self, path: &[u8]) {
match self.path_separator { match self.path_separator {
None => self.write(path.as_bytes()), None => self.write_colored(path, |colors| colors.path()),
Some(sep) => self.write_path_with_sep(path.as_bytes(), sep), Some(sep) => {
let transformed_path: Vec<_> = path.iter().map(|&b| {
if b == b'/' || (cfg!(windows) && b == b'\\') {
sep
} else {
b
}
}).collect();
self.write_colored(&transformed_path, |colors| colors.path());
}
} }
} }
fn write_path_with_sep(&mut self, path: &[u8], sep: u8) { fn line_number(&mut self, n: u64, sep: u8) {
let mut path = path.to_vec(); self.write_colored(n.to_string().as_bytes(), |colors| colors.line());
for b in &mut path { self.separator(&[sep]);
if *b == b'/' || (cfg!(windows) && *b == b'\\') { }
*b = sep;
} fn column_number(&mut self, n: u64, sep: u8) {
} self.write_colored(n.to_string().as_bytes(), |colors| colors.column());
self.write(&path); self.separator(&[sep]);
} }
fn write(&mut self, buf: &[u8]) { fn write(&mut self, buf: &[u8]) {
@@ -447,6 +442,14 @@ impl<W: WriteColor> Printer<W> {
self.write(&[eol]); self.write(&[eol]);
} }
fn write_colored<F>(&mut self, buf: &[u8], get_color: F)
where F: Fn(&ColorSpecs) -> &ColorSpec
{
let _ = self.wtr.set_color( get_color(&self.colors) );
self.write(buf);
let _ = self.wtr.reset();
}
fn write_file_sep(&mut self) { fn write_file_sep(&mut self) {
if let Some(ref sep) = self.file_separator { if let Some(ref sep) = self.file_separator {
self.has_printed = true; self.has_printed = true;
@@ -492,7 +495,7 @@ impl fmt::Display for Error {
match *self { match *self {
Error::UnrecognizedOutType(ref name) => { Error::UnrecognizedOutType(ref name) => {
write!(f, "Unrecognized output type '{}'. Choose from: \ write!(f, "Unrecognized output type '{}'. Choose from: \
path, line, match.", name) path, line, column, match.", name)
} }
Error::UnrecognizedSpecType(ref name) => { Error::UnrecognizedSpecType(ref name) => {
write!(f, "Unrecognized spec type '{}'. Choose from: \ write!(f, "Unrecognized spec type '{}'. Choose from: \
@@ -503,12 +506,14 @@ impl fmt::Display for Error {
} }
Error::UnrecognizedStyle(ref name) => { Error::UnrecognizedStyle(ref name) => {
write!(f, "Unrecognized style attribute '{}'. Choose from: \ write!(f, "Unrecognized style attribute '{}'. Choose from: \
nobold, bold.", name) nobold, bold, nointense, intense.", name)
} }
Error::InvalidFormat(ref original) => { Error::InvalidFormat(ref original) => {
write!(f, "Invalid color speci format: '{}'. Valid format \ write!(
is '(path|line|match):(fg|bg|style):(value)'.", f,
original) "Invalid color speci format: '{}'. Valid format \
is '(path|line|column|match):(fg|bg|style):(value)'.",
original)
} }
} }
} }
@@ -525,6 +530,7 @@ impl From<ParseColorError> for Error {
pub struct ColorSpecs { pub struct ColorSpecs {
path: ColorSpec, path: ColorSpec,
line: ColorSpec, line: ColorSpec,
column: ColorSpec,
matched: ColorSpec, matched: ColorSpec,
} }
@@ -554,7 +560,7 @@ pub struct ColorSpecs {
/// The format of a `Spec` is a triple: `{type}:{attribute}:{value}`. Each /// The format of a `Spec` is a triple: `{type}:{attribute}:{value}`. Each
/// component is defined as follows: /// component is defined as follows:
/// ///
/// * `{type}` can be one of `path`, `line` or `match`. /// * `{type}` can be one of `path`, `line`, `column` or `match`.
/// * `{attribute}` can be one of `fg`, `bg` or `style`. `{attribute}` may also /// * `{attribute}` can be one of `fg`, `bg` or `style`. `{attribute}` may also
/// be the special value `none`, in which case, `{value}` can be omitted. /// be the special value `none`, in which case, `{value}` can be omitted.
/// * `{value}` is either a color name (for `fg`/`bg`) or a style instruction. /// * `{value}` is either a color name (for `fg`/`bg`) or a style instruction.
@@ -593,6 +599,7 @@ enum SpecValue {
enum OutType { enum OutType {
Path, Path,
Line, Line,
Column,
Match, Match,
} }
@@ -623,6 +630,7 @@ impl ColorSpecs {
match user_spec.ty { match user_spec.ty {
OutType::Path => user_spec.merge_into(&mut specs.path), OutType::Path => user_spec.merge_into(&mut specs.path),
OutType::Line => user_spec.merge_into(&mut specs.line), OutType::Line => user_spec.merge_into(&mut specs.line),
OutType::Column => user_spec.merge_into(&mut specs.column),
OutType::Match => user_spec.merge_into(&mut specs.matched), OutType::Match => user_spec.merge_into(&mut specs.matched),
} }
} }
@@ -639,6 +647,11 @@ impl ColorSpecs {
&self.line &self.line
} }
/// Return the color specification for coloring column numbers.
fn column(&self) -> &ColorSpec {
&self.column
}
/// Return the color specification for coloring matched text. /// Return the color specification for coloring matched text.
fn matched(&self) -> &ColorSpec { fn matched(&self) -> &ColorSpec {
&self.matched &self.matched
@@ -714,6 +727,7 @@ impl FromStr for OutType {
match &*s.to_lowercase() { match &*s.to_lowercase() {
"path" => Ok(OutType::Path), "path" => Ok(OutType::Path),
"line" => Ok(OutType::Line), "line" => Ok(OutType::Line),
"column" => Ok(OutType::Column),
"match" => Ok(OutType::Match), "match" => Ok(OutType::Match),
_ => Err(Error::UnrecognizedOutType(s.to_string())), _ => Err(Error::UnrecognizedOutType(s.to_string())),
} }
@@ -765,6 +779,7 @@ mod tests {
assert_eq!(ColorSpecs::new(user_specs), ColorSpecs { assert_eq!(ColorSpecs::new(user_specs), ColorSpecs {
path: ColorSpec::default(), path: ColorSpec::default(),
line: ColorSpec::default(), line: ColorSpec::default(),
column: ColorSpec::default(),
matched: expect_matched, matched: expect_matched,
}); });
} }
@@ -800,6 +815,12 @@ mod tests {
ty: OutType::Line, ty: OutType::Line,
value: SpecValue::None, value: SpecValue::None,
}); });
let spec: Spec = "column:bg:green".parse().unwrap();
assert_eq!(spec, Spec {
ty: OutType::Column,
value: SpecValue::Bg(Color::Green),
});
} }
#[test] #[test]

View File

@@ -3,8 +3,8 @@ The `search_buffer` module is responsible for searching a single file all in a
single buffer. Typically, the source of the buffer is a memory map. This can single buffer. Typically, the source of the buffer is a memory map. This can
be useful for when memory maps are faster than streaming search. be useful for when memory maps are faster than streaming search.
Note that this module doesn't quite support everything that `search_stream` does. Note that this module doesn't quite support everything that `search_stream`
Notably, showing contexts. does. Notably, showing contexts.
*/ */
use std::cmp; use std::cmp;
use std::path::Path; use std::path::Path;

3
termcolor/COPYING Normal file
View File

@@ -0,0 +1,3 @@
This project is dual-licensed under the Unlicense and MIT licenses.
You may use this code under the terms of either license.

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "termcolor" name = "termcolor"
version = "0.3.1" #:version version = "0.3.2" #:version
authors = ["Andrew Gallant <jamslam@gmail.com>"] authors = ["Andrew Gallant <jamslam@gmail.com>"]
description = """ description = """
A simple cross platform library for writing colored text to a terminal. A simple cross platform library for writing colored text to a terminal.

21
termcolor/LICENSE-MIT Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Andrew Gallant
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

24
termcolor/UNLICENSE Normal file
View File

@@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>

View File

@@ -1057,6 +1057,33 @@ clean!(regression_405, "test", ".", |wd: WorkDir, mut cmd: Command| {
assert_eq!(lines, format!("{}:test\n", path("bar/foo/file2.txt"))); assert_eq!(lines, format!("{}:test\n", path("bar/foo/file2.txt")));
}); });
// See: https://github.com/BurntSushi/ripgrep/issues/428
clean!(regression_428_color_context_path, "foo", ".", |wd: WorkDir, mut cmd: Command| {
wd.create("sherlock", "foo\nbar");
cmd.arg("-A1").arg("-H").arg("--no-heading").arg("-N")
.arg("--colors=match:none").arg("--color=always");
let lines: String = wd.stdout(&mut cmd);
let expected = format!("\
{colored_path}:foo
{colored_path}-bar
", colored_path=format!("\x1b\x5b\x6d\x1b\x5b\x33\x35\x6d{path}\x1b\x5b\x6d", path=path("sherlock")));
assert_eq!(lines, expected);
});
// See: https://github.com/BurntSushi/ripgrep/issues/428
clean!(regression_428_unrecognized_style, "Sherlok", ".", |wd: WorkDir, mut cmd: Command| {
cmd.arg("--colors=match:style:");
wd.assert_err(&mut cmd);
let output = cmd.output().unwrap();
let err = String::from_utf8_lossy(&output.stderr);
let expected = "\
Unrecognized style attribute ''. Choose from: nobold, bold, nointense, intense.
";
assert_eq!(err, expected);
});
// See: https://github.com/BurntSushi/ripgrep/issues/1 // See: https://github.com/BurntSushi/ripgrep/issues/1
clean!(feature_1_sjis, "Шерлок Холмс", ".", |wd: WorkDir, mut cmd: Command| { clean!(feature_1_sjis, "Шерлок Холмс", ".", |wd: WorkDir, mut cmd: Command| {
let sherlock = let sherlock =
@@ -1139,6 +1166,32 @@ be, to a very large extent, the result of luck. Sherlock Holmes
assert_eq!(lines, expected); assert_eq!(lines, expected);
}); });
// See: https://github.com/BurntSushi/ripgrep/issues/34
sherlock!(feature_34_only_matching, "Sherlock", ".",
|wd: WorkDir, mut cmd: Command| {
cmd.arg("--only-matching");
let lines: String = wd.stdout(&mut cmd);
let expected = "\
sherlock:Sherlock
sherlock:Sherlock
";
assert_eq!(lines, expected);
});
// See: https://github.com/BurntSushi/ripgrep/issues/34
sherlock!(feature_34_only_matching_line_column, "Sherlock", ".",
|wd: WorkDir, mut cmd: Command| {
cmd.arg("--only-matching").arg("--column").arg("--line-number");
let lines: String = wd.stdout(&mut cmd);
let expected = "\
sherlock:1:57:Sherlock
sherlock:3:49:Sherlock
";
assert_eq!(lines, expected);
});
// See: https://github.com/BurntSushi/ripgrep/issues/45 // See: https://github.com/BurntSushi/ripgrep/issues/45
sherlock!(feature_45_relative_cwd, "test", ".", sherlock!(feature_45_relative_cwd, "test", ".",
|wd: WorkDir, mut cmd: Command| { |wd: WorkDir, mut cmd: Command| {
@@ -1390,6 +1443,15 @@ clean!(feature_275_pathsep, "test", ".", |wd: WorkDir, mut cmd: Command| {
assert_eq!(lines, "fooZbar:test\n"); assert_eq!(lines, "fooZbar:test\n");
}); });
// See: https://github.com/BurntSushi/ripgrep/issues/419
sherlock!(feature_419_zero_as_shortcut_for_null, "Sherlock", ".",
|wd: WorkDir, mut cmd: Command| {
cmd.arg("-0").arg("--count");
let lines: String = wd.stdout(&mut cmd);
assert_eq!(lines, "sherlock\x002\n");
});
#[test] #[test]
fn binary_nosearch() { fn binary_nosearch() {
let wd = WorkDir::new("binary_nosearch"); let wd = WorkDir::new("binary_nosearch");