mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-04-19 09:02:15 +02:00
parent
8eeb0c0b60
commit
1595f0faf5
6
doc/rg.1
6
doc/rg.1
@ -238,6 +238,12 @@ Alias for \-\-color=always \-\-heading \-n.
|
|||||||
.RS
|
.RS
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.TP
|
||||||
|
.B \-S, \-\-smart\-case
|
||||||
|
Search case insensitively if the pattern is all lowercase.
|
||||||
|
Search case sensitively otherwise.
|
||||||
|
.RS
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
.B \-j, \-\-threads \f[I]ARG\f[]
|
.B \-j, \-\-threads \f[I]ARG\f[]
|
||||||
The number of threads to use.
|
The number of threads to use.
|
||||||
Defaults to the number of logical CPUs (capped at 6).
|
Defaults to the number of logical CPUs (capped at 6).
|
||||||
|
@ -154,6 +154,10 @@ the raw speed of grep.
|
|||||||
-p, --pretty
|
-p, --pretty
|
||||||
: Alias for --color=always --heading -n.
|
: Alias for --color=always --heading -n.
|
||||||
|
|
||||||
|
-S, --smart-case
|
||||||
|
: Search case insensitively if the pattern is all lowercase.
|
||||||
|
Search case sensitively otherwise.
|
||||||
|
|
||||||
-j, --threads *ARG*
|
-j, --threads *ARG*
|
||||||
: The number of threads to use. Defaults to the number of logical CPUs
|
: The number of threads to use. Defaults to the number of logical CPUs
|
||||||
(capped at 6). [default: 0]
|
(capped at 6). [default: 0]
|
||||||
|
@ -52,6 +52,7 @@ pub struct GrepBuilder {
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct Options {
|
struct Options {
|
||||||
case_insensitive: bool,
|
case_insensitive: bool,
|
||||||
|
case_smart: bool,
|
||||||
line_terminator: u8,
|
line_terminator: u8,
|
||||||
size_limit: usize,
|
size_limit: usize,
|
||||||
dfa_size_limit: usize,
|
dfa_size_limit: usize,
|
||||||
@ -61,6 +62,7 @@ impl Default for Options {
|
|||||||
fn default() -> Options {
|
fn default() -> Options {
|
||||||
Options {
|
Options {
|
||||||
case_insensitive: false,
|
case_insensitive: false,
|
||||||
|
case_smart: false,
|
||||||
line_terminator: b'\n',
|
line_terminator: b'\n',
|
||||||
size_limit: 10 * (1 << 20),
|
size_limit: 10 * (1 << 20),
|
||||||
dfa_size_limit: 10 * (1 << 20),
|
dfa_size_limit: 10 * (1 << 20),
|
||||||
@ -98,6 +100,18 @@ impl GrepBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether to enable smart case search or not (disabled by default).
|
||||||
|
///
|
||||||
|
/// Smart case uses case insensitive search if the regex is contains all
|
||||||
|
/// lowercase literal characters. Otherwise, a case sensitive search is
|
||||||
|
/// used instead.
|
||||||
|
///
|
||||||
|
/// Enabling the case_insensitive flag overrides this.
|
||||||
|
pub fn case_smart(mut self, yes: bool) -> GrepBuilder {
|
||||||
|
self.opts.case_smart = yes;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the approximate size limit of the compiled regular expression.
|
/// Set the approximate size limit of the compiled regular expression.
|
||||||
///
|
///
|
||||||
/// This roughly corresponds to the number of bytes occupied by a
|
/// This roughly corresponds to the number of bytes occupied by a
|
||||||
@ -148,8 +162,11 @@ impl GrepBuilder {
|
|||||||
/// Creates a new regex from the given expression with the current
|
/// Creates a new regex from the given expression with the current
|
||||||
/// configuration.
|
/// configuration.
|
||||||
fn regex(&self, expr: &Expr) -> Result<Regex> {
|
fn regex(&self, expr: &Expr) -> Result<Regex> {
|
||||||
|
let casei =
|
||||||
|
self.opts.case_insensitive
|
||||||
|
|| (self.opts.case_smart && !has_uppercase_literal(expr));
|
||||||
RegexBuilder::new(&expr.to_string())
|
RegexBuilder::new(&expr.to_string())
|
||||||
.case_insensitive(self.opts.case_insensitive)
|
.case_insensitive(casei)
|
||||||
.multi_line(true)
|
.multi_line(true)
|
||||||
.unicode(true)
|
.unicode(true)
|
||||||
.size_limit(self.opts.size_limit)
|
.size_limit(self.opts.size_limit)
|
||||||
@ -274,6 +291,23 @@ impl<'b, 's> Iterator for Iter<'b, 's> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn has_uppercase_literal(expr: &Expr) -> bool {
|
||||||
|
use syntax::Expr::*;
|
||||||
|
match *expr {
|
||||||
|
Literal { ref chars, casei } => {
|
||||||
|
casei || chars.iter().any(|c| c.is_uppercase())
|
||||||
|
}
|
||||||
|
LiteralBytes { ref bytes, casei } => {
|
||||||
|
casei || bytes.iter().any(|&b| b'A' <= b && b <= b'Z')
|
||||||
|
}
|
||||||
|
Group { ref e, .. } => has_uppercase_literal(e),
|
||||||
|
Repeat { ref e, .. } => has_uppercase_literal(e),
|
||||||
|
Concat(ref es) => es.iter().any(has_uppercase_literal),
|
||||||
|
Alternate(ref es) => es.iter().any(has_uppercase_literal),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#![allow(unused_imports)]
|
#![allow(unused_imports)]
|
||||||
|
@ -154,6 +154,10 @@ Less common options:
|
|||||||
-p, --pretty
|
-p, --pretty
|
||||||
Alias for --color=always --heading -n.
|
Alias for --color=always --heading -n.
|
||||||
|
|
||||||
|
-S, --smart-case
|
||||||
|
Search case insensitively if the pattern is all lowercase.
|
||||||
|
Search case sensitively otherwise.
|
||||||
|
|
||||||
-j, --threads ARG
|
-j, --threads ARG
|
||||||
The number of threads to use. Defaults to the number of logical CPUs
|
The number of threads to use. Defaults to the number of logical CPUs
|
||||||
(capped at 6). [default: 0]
|
(capped at 6). [default: 0]
|
||||||
@ -217,6 +221,7 @@ pub struct RawArgs {
|
|||||||
flag_quiet: bool,
|
flag_quiet: bool,
|
||||||
flag_regexp: Vec<String>,
|
flag_regexp: Vec<String>,
|
||||||
flag_replace: Option<String>,
|
flag_replace: Option<String>,
|
||||||
|
flag_smart_case: bool,
|
||||||
flag_text: bool,
|
flag_text: bool,
|
||||||
flag_threads: usize,
|
flag_threads: usize,
|
||||||
flag_type: Vec<String>,
|
flag_type: Vec<String>,
|
||||||
@ -348,6 +353,7 @@ impl RawArgs {
|
|||||||
let types = try!(btypes.build());
|
let types = try!(btypes.build());
|
||||||
let grep = try!(
|
let grep = try!(
|
||||||
GrepBuilder::new(&pattern)
|
GrepBuilder::new(&pattern)
|
||||||
|
.case_smart(self.flag_smart_case)
|
||||||
.case_insensitive(self.flag_ignore_case)
|
.case_insensitive(self.flag_ignore_case)
|
||||||
.line_terminator(eol)
|
.line_terminator(eol)
|
||||||
.build()
|
.build()
|
||||||
|
@ -699,6 +699,18 @@ clean!(feature_68, "test", ".", |wd: WorkDir, mut cmd: Command| {
|
|||||||
assert_eq!(lines, "foo:test\n");
|
assert_eq!(lines, "foo:test\n");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/issues/70
|
||||||
|
sherlock!(feature_70, "sherlock", ".", |wd: WorkDir, mut cmd: Command| {
|
||||||
|
cmd.arg("--smart-case");
|
||||||
|
|
||||||
|
let lines: String = wd.stdout(&mut cmd);
|
||||||
|
let expected = "\
|
||||||
|
sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||||
|
sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
|
||||||
|
";
|
||||||
|
assert_eq!(lines, expected);
|
||||||
|
});
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn binary_nosearch() {
|
fn binary_nosearch() {
|
||||||
let wd = WorkDir::new("binary_nosearch");
|
let wd = WorkDir::new("binary_nosearch");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user