1
0
mirror of https://github.com/BurntSushi/ripgrep.git synced 2025-04-14 00:58:43 +02:00

Add -x/--line-regexp (#520)

add -x/--line-regexp flag
This commit is contained in:
dana 2017-08-09 05:53:35 -05:00 committed by Andrew Gallant
parent b3a9c34515
commit 40bacbcd7c
7 changed files with 48 additions and 8 deletions

View File

@ -45,6 +45,7 @@ _rg() {
'--ignore-file=[specify additional ignore file]:file:_files' '--ignore-file=[specify additional ignore file]:file:_files'
'(-v --invert-match)'{-v,--invert-match}'[invert matching]' '(-v --invert-match)'{-v,--invert-match}'[invert matching]'
'(-n -N --line-number --no-line-number)'{-n,--line-number}'[show line numbers]' '(-n -N --line-number --no-line-number)'{-n,--line-number}'[show line numbers]'
'(-w -x --line-regexp --word-regexp)'{-x,--line-regexp}'[only show matches surrounded by line boundaries]'
'(-M --max-columns)'{-M+,--max-columns=}'[specify max length of lines to print]:number of bytes' '(-M --max-columns)'{-M+,--max-columns=}'[specify max length of lines to print]:number of bytes'
'(-m --max-count)'{-m+,--max-count=}'[specify max number of matches per file]:number of matches' '(-m --max-count)'{-m+,--max-count=}'[specify max number of matches per file]:number of matches'
'--max-filesize=[specify size above which files should be ignored]:file size' '--max-filesize=[specify size above which files should be ignored]:file size'
@ -80,7 +81,7 @@ _rg() {
'(: -)'{-V,--version}'[display version information]' '(: -)'{-V,--version}'[display version information]'
'(-p --heading --no-heading --pretty)--vimgrep[show results in vim-compatible format]' '(-p --heading --no-heading --pretty)--vimgrep[show results in vim-compatible format]'
'(-H --no-filename --with-filename)'{-H,--with-filename}'[prefix each match with name of file that contains it]' '(-H --no-filename --with-filename)'{-H,--with-filename}'[prefix each match with name of file that contains it]'
'(-w --word-regexp)'{-w,--word-regexp}'[only show matches surrounded by word boundaries]' '(-w -x --line-regexp --word-regexp)'{-w,--word-regexp}'[only show matches surrounded by word boundaries]'
'(-e -f --file --files --regexp --type-list)1: :_rg_pattern' '(-e -f --file --files --regexp --type-list)1: :_rg_pattern'
'(--type-list)*:file:_files' '(--type-list)*:file:_files'
) )

View File

@ -1,4 +1,5 @@
#!/bin/sh #!/bin/sh -e
pandoc -s -t man rg.1.md -o rg.1 pandoc -s -t man rg.1.md -o rg.1
sed -i 's/\.TH.*/.TH "rg" "1"/g' rg.1 sed -i.bak 's/\.TH.*/.TH "rg" "1"/g' rg.1
rm -f rg.1.bak # BSD `sed` requires the creation of a back-up file

View File

@ -156,6 +156,12 @@ Only show matches surrounded by word boundaries.
This is equivalent to putting \\b before and after the search pattern. This is equivalent to putting \\b before and after the search pattern.
.RS .RS
.RE .RE
.TP
.B \-x, \-\-line\-regexp
Only show matches surrounded by line boundaries.
This is equivalent to putting ^...$ around the search pattern.
.RS
.RE
.SH LESS COMMON OPTIONS .SH LESS COMMON OPTIONS
.TP .TP
.B \-A, \-\-after\-context \f[I]NUM\f[] .B \-A, \-\-after\-context \f[I]NUM\f[]

View File

@ -105,6 +105,10 @@ Project home page: https://github.com/BurntSushi/ripgrep
: Only show matches surrounded by word boundaries. This is equivalent to : Only show matches surrounded by word boundaries. This is equivalent to
putting \\b before and after the search pattern. putting \\b before and after the search pattern.
-x, --line-regexp
: Only show matches surrounded by line boundaries. This is equivalent to
putting ^...$ around the search pattern.
# LESS COMMON OPTIONS # LESS COMMON OPTIONS
-A, --after-context *NUM* -A, --after-context *NUM*

View File

@ -109,7 +109,8 @@ pub fn app() -> App<'static, 'static> {
.arg(flag("unrestricted").short("u") .arg(flag("unrestricted").short("u")
.multiple(true)) .multiple(true))
.arg(flag("invert-match").short("v")) .arg(flag("invert-match").short("v"))
.arg(flag("word-regexp").short("w")) .arg(flag("word-regexp").short("w").overrides_with("line-regexp"))
.arg(flag("line-regexp").short("x"))
// Third, set up less common flags. // Third, set up less common flags.
.arg(flag("after-context").short("A") .arg(flag("after-context").short("A")
.value_name("NUM").takes_value(true) .value_name("NUM").takes_value(true)
@ -348,6 +349,10 @@ lazy_static! {
"Only show matches surrounded by word boundaries. This is \ "Only show matches surrounded by word boundaries. This is \
equivalent to putting \\b before and after all of the search \ equivalent to putting \\b before and after all of the search \
patterns."); patterns.");
doc!(h, "line-regexp",
"Only show matches surrounded by line boundaries.",
"Only show matches surrounded by line boundaries. This is \
equivalent to putting ^...$ around all of the search patterns.");
doc!(h, "after-context", doc!(h, "after-context",
"Show NUM lines after each match."); "Show NUM lines after each match.");

View File

@ -427,7 +427,8 @@ impl<'a> ArgMatches<'a> {
/// ///
/// Note that if -F/--fixed-strings is set, then all patterns will be /// Note that if -F/--fixed-strings is set, then all patterns will be
/// escaped. Similarly, if -w/--word-regexp is set, then all patterns /// escaped. Similarly, if -w/--word-regexp is set, then all patterns
/// are surrounded by `\b`. /// are surrounded by `\b`, and if -x/--line-regexp is set, then all
/// patterns are surrounded by `^...$`.
/// ///
/// If any pattern is invalid UTF-8, then an error is returned. /// If any pattern is invalid UTF-8, then an error is returned.
fn patterns(&self) -> Result<Vec<String>> { fn patterns(&self) -> Result<Vec<String>> {
@ -470,7 +471,7 @@ impl<'a> ArgMatches<'a> {
Ok(pats) Ok(pats)
} }
/// Converts an OsStr pattern to a String pattern, including word /// Converts an OsStr pattern to a String pattern, including line/word
/// boundaries or escapes if applicable. /// boundaries or escapes if applicable.
/// ///
/// If the pattern is not valid UTF-8, then an error is returned. /// If the pattern is not valid UTF-8, then an error is returned.
@ -479,10 +480,12 @@ impl<'a> ArgMatches<'a> {
Ok(self.str_pattern(s)) Ok(self.str_pattern(s))
} }
/// Converts a &str pattern to a String pattern, including word /// Converts a &str pattern to a String pattern, including line/word
/// boundaries or escapes if applicable. /// boundaries or escapes if applicable.
fn str_pattern(&self, pat: &str) -> String { fn str_pattern(&self, pat: &str) -> String {
let s = self.word_pattern(self.literal_pattern(pat.to_string())); let litpat = self.literal_pattern(pat.to_string());
let s = self.line_pattern(self.word_pattern(litpat));
if s.is_empty() { if s.is_empty() {
self.empty_pattern() self.empty_pattern()
} else { } else {
@ -511,6 +514,16 @@ impl<'a> ArgMatches<'a> {
} }
} }
/// Returns the given pattern as a line pattern if the -x/--line-regexp
/// flag is set. Otherwise, the pattern is returned unchanged.
fn line_pattern(&self, pat: String) -> String {
if self.is_present("line-regexp") {
format!(r"^(?:{})$", pat)
} else {
pat
}
}
/// Empty pattern returns a pattern that is guaranteed to produce an empty /// Empty pattern returns a pattern that is guaranteed to produce an empty
/// regular expression that is valid in any position. /// regular expression that is valid in any position.
fn empty_pattern(&self) -> String { fn empty_pattern(&self) -> String {

View File

@ -209,6 +209,16 @@ For the Doctor Watsons of this world, as opposed to the Sherlock
assert_eq!(lines, expected); assert_eq!(lines, expected);
}); });
sherlock!(line, "Watson|and exhibited clearly, with a label attached.",
|wd: WorkDir, mut cmd: Command| {
cmd.arg("-x");
let lines: String = wd.stdout(&mut cmd);
let expected = "\
and exhibited clearly, with a label attached.
";
assert_eq!(lines, expected);
});
sherlock!(literal, "()", "file", |wd: WorkDir, mut cmd: Command| { sherlock!(literal, "()", "file", |wd: WorkDir, mut cmd: Command| {
wd.create("file", "blib\n()\nblab\n"); wd.create("file", "blib\n()\nblab\n");
cmd.arg("-F"); cmd.arg("-F");