/crates/core/app.rs
Rust | 3029 lines | 2636 code | 171 blank | 222 comment | 13 complexity | 8e00978dbda7f431c397449444e4035a MD5 | raw file
Possible License(s): MIT, Unlicense
Large files files are truncated, but you can click here to view the full file
- // This module defines the set of command line arguments that ripgrep supports,
- // including some light validation.
- //
- // This module is purposely written in a bare-bones way, since it is included
- // in ripgrep's build.rs file as a way to generate a man page and completion
- // files for common shells.
- //
- // The only other place that ripgrep deals with clap is in src/args.rs, which
- // is where we read clap's configuration from the end user's arguments and turn
- // it into a ripgrep-specific configuration type that is not coupled with clap.
- use clap::{self, crate_authors, crate_version, App, AppSettings};
- use lazy_static::lazy_static;
- const ABOUT: &str = "
- ripgrep (rg) recursively searches your current directory for a regex pattern.
- By default, ripgrep will respect your .gitignore and automatically skip hidden
- files/directories and binary files.
- Use -h for short descriptions and --help for more details.
- Project home page: https://github.com/BurntSushi/ripgrep
- ";
- const USAGE: &str = "
- rg [OPTIONS] PATTERN [PATH ...]
- rg [OPTIONS] [-e PATTERN ...] [-f PATTERNFILE ...] [PATH ...]
- rg [OPTIONS] --files [PATH ...]
- rg [OPTIONS] --type-list
- command | rg [OPTIONS] PATTERN";
- const TEMPLATE: &str = "\
- {bin} {version}
- {author}
- {about}
- USAGE:{usage}
- ARGS:
- {positionals}
- OPTIONS:
- {unified}";
- /// Build a clap application parameterized by usage strings.
- pub fn app() -> App<'static, 'static> {
- // We need to specify our version in a static because we've painted clap
- // into a corner. We've told it that every string we give it will be
- // 'static, but we need to build the version string dynamically. We can
- // fake the 'static lifetime with lazy_static.
- lazy_static! {
- static ref LONG_VERSION: String = long_version(None, true);
- }
- let mut app = App::new("ripgrep")
- .author(crate_authors!())
- .version(crate_version!())
- .long_version(LONG_VERSION.as_str())
- .about(ABOUT)
- .max_term_width(100)
- .setting(AppSettings::UnifiedHelpMessage)
- .setting(AppSettings::AllArgsOverrideSelf)
- .usage(USAGE)
- .template(TEMPLATE)
- .help_message("Prints help information. Use --help for more details.");
- for arg in all_args_and_flags() {
- app = app.arg(arg.claparg);
- }
- app
- }
- /// Return the "long" format of ripgrep's version string.
- ///
- /// If a revision hash is given, then it is used. If one isn't given, then
- /// the RIPGREP_BUILD_GIT_HASH env var is inspected for it. If that isn't set,
- /// then a revision hash is not included in the version string returned.
- ///
- /// If `cpu` is true, then the version string will include the compiled and
- /// runtime CPU features.
- pub fn long_version(revision_hash: Option<&str>, cpu: bool) -> String {
- // Do we have a git hash?
- // (Yes, if ripgrep was built on a machine with `git` installed.)
- let hash = match revision_hash.or(option_env!("RIPGREP_BUILD_GIT_HASH")) {
- None => String::new(),
- Some(githash) => format!(" (rev {})", githash),
- };
- if !cpu {
- format!("{}{}", crate_version!(), hash,)
- } else {
- let runtime = runtime_cpu_features();
- if runtime.is_empty() {
- format!(
- "{}{}\n{} (compiled)",
- crate_version!(),
- hash,
- compile_cpu_features().join(" ")
- )
- } else {
- format!(
- "{}{}\n{} (compiled)\n{} (runtime)",
- crate_version!(),
- hash,
- compile_cpu_features().join(" "),
- runtime.join(" ")
- )
- }
- }
- }
- /// Returns the relevant CPU features enabled at compile time.
- fn compile_cpu_features() -> Vec<&'static str> {
- let mut features = vec![];
- if cfg!(feature = "simd-accel") {
- features.push("+SIMD");
- } else {
- features.push("-SIMD");
- }
- if cfg!(feature = "avx-accel") {
- features.push("+AVX");
- } else {
- features.push("-AVX");
- }
- features
- }
- /// Returns the relevant CPU features enabled at runtime.
- #[cfg(target_arch = "x86_64")]
- fn runtime_cpu_features() -> Vec<&'static str> {
- // This is kind of a dirty violation of abstraction, since it assumes
- // knowledge about what specific SIMD features are being used.
- let mut features = vec![];
- if is_x86_feature_detected!("ssse3") {
- features.push("+SIMD");
- } else {
- features.push("-SIMD");
- }
- if is_x86_feature_detected!("avx2") {
- features.push("+AVX");
- } else {
- features.push("-AVX");
- }
- features
- }
- /// Returns the relevant CPU features enabled at runtime.
- #[cfg(not(target_arch = "x86_64"))]
- fn runtime_cpu_features() -> Vec<&'static str> {
- vec![]
- }
- /// Arg is a light alias for a clap::Arg that is specialized to compile time
- /// string literals.
- type Arg = clap::Arg<'static, 'static>;
- /// RGArg is a light wrapper around a clap::Arg and also contains some metadata
- /// about the underlying Arg so that it can be inspected for other purposes
- /// (e.g., hopefully generating a man page).
- ///
- /// Note that this type is purposely overly constrained to ripgrep's particular
- /// use of clap.
- #[allow(dead_code)]
- #[derive(Clone)]
- pub struct RGArg {
- /// The underlying clap argument.
- claparg: Arg,
- /// The name of this argument. This is always present and is the name
- /// used in the code to find the value of an argument at runtime.
- pub name: &'static str,
- /// A short documentation string describing this argument. This string
- /// should fit on a single line and be a complete sentence.
- ///
- /// This is shown in the `-h` output.
- pub doc_short: &'static str,
- /// A longer documentation string describing this argument. This usually
- /// starts with the contents of `doc_short`. This is also usually many
- /// lines, potentially paragraphs, and may contain examples and additional
- /// prose.
- ///
- /// This is shown in the `--help` output.
- pub doc_long: &'static str,
- /// Whether this flag is hidden or not.
- ///
- /// This is typically used for uncommon flags that only serve to override
- /// other flags. For example, --no-ignore is a prominent flag that disables
- /// ripgrep's gitignore functionality, but --ignore re-enables it. Since
- /// gitignore support is enabled by default, use of the --ignore flag is
- /// somewhat niche and relegated to special cases when users make use of
- /// configuration files to set defaults.
- ///
- /// Generally, these flags should be documented in the documentation for
- /// the flag they override.
- pub hidden: bool,
- /// The type of this argument.
- pub kind: RGArgKind,
- }
- /// The kind of a ripgrep argument.
- ///
- /// This can be one of three possibilities: a positional argument, a boolean
- /// switch flag or a flag that accepts exactly one argument. Each variant
- /// stores argument type specific data.
- ///
- /// Note that clap supports more types of arguments than this, but we don't
- /// (and probably shouldn't) use them in ripgrep.
- ///
- /// Finally, note that we don't capture *all* state about an argument in this
- /// type. Some state is only known to clap. There isn't any particular reason
- /// why; the state we do capture is motivated by use cases (like generating
- /// documentation).
- #[derive(Clone)]
- pub enum RGArgKind {
- /// A positional argument.
- Positional {
- /// The name of the value used in the `-h/--help` output. By
- /// convention, this is an all-uppercase string. e.g., `PATH` or
- /// `PATTERN`.
- value_name: &'static str,
- /// Whether an argument can be repeated multiple times or not.
- ///
- /// The only argument this applies to is PATH, where an end user can
- /// specify multiple paths for ripgrep to search.
- ///
- /// If this is disabled, then an argument can only be provided once.
- /// For example, PATTERN is one such argument. (Note that the
- /// -e/--regexp flag is distinct from the positional PATTERN argument,
- /// and it can be provided multiple times.)
- multiple: bool,
- },
- /// A boolean switch.
- Switch {
- /// The long name of a flag. This is always non-empty.
- long: &'static str,
- /// The short name of a flag. This is empty if a flag only has a long
- /// name.
- short: Option<&'static str>,
- /// Whether this switch can be provided multiple times where meaning
- /// is attached to the number of times this flag is given.
- ///
- /// Note that every switch can be provided multiple times. This
- /// particular state indicates whether all instances of a switch are
- /// relevant or not.
- ///
- /// For example, the -u/--unrestricted flag can be provided multiple
- /// times where each repeated use of it indicates more relaxing of
- /// ripgrep's filtering. Conversely, the -i/--ignore-case flag can
- /// also be provided multiple times, but it is simply considered either
- /// present or not. In these cases, -u/--unrestricted has `multiple`
- /// set to `true` while -i/--ignore-case has `multiple` set to `false`.
- multiple: bool,
- },
- /// A flag the accepts a single value.
- Flag {
- /// The long name of a flag. This is always non-empty.
- long: &'static str,
- /// The short name of a flag. This is empty if a flag only has a long
- /// name.
- short: Option<&'static str>,
- /// The name of the value used in the `-h/--help` output. By
- /// convention, this is an all-uppercase string. e.g., `PATH` or
- /// `PATTERN`.
- value_name: &'static str,
- /// Whether this flag can be provided multiple times with multiple
- /// distinct values.
- ///
- /// Note that every flag can be provided multiple times. This
- /// particular state indicates whether all instances of a flag are
- /// relevant or not.
- ///
- /// For example, the -g/--glob flag can be provided multiple times and
- /// all of its values should be interpreted by ripgrep. Conversely,
- /// while the -C/--context flag can also be provided multiple times,
- /// only its last instance is used while all previous instances are
- /// ignored. In these cases, -g/--glob has `multiple` set to `true`
- /// while -C/--context has `multiple` set to `false`.
- multiple: bool,
- /// A set of possible values for this flag. If an end user provides
- /// any value other than what's in this set, then clap will report an
- /// error.
- possible_values: Vec<&'static str>,
- },
- }
- impl RGArg {
- /// Create a positional argument.
- ///
- /// The `long_name` parameter is the name of the argument, e.g., `pattern`.
- /// The `value_name` parameter is a name that describes the type of
- /// argument this flag accepts. It should be in uppercase, e.g., PATH or
- /// PATTERN.
- fn positional(name: &'static str, value_name: &'static str) -> RGArg {
- RGArg {
- claparg: Arg::with_name(name).value_name(value_name),
- name,
- doc_short: "",
- doc_long: "",
- hidden: false,
- kind: RGArgKind::Positional { value_name, multiple: false },
- }
- }
- /// Create a boolean switch.
- ///
- /// The `long_name` parameter is the name of the flag, e.g., `--long-name`.
- ///
- /// All switches may be repeated an arbitrary number of times. If a switch
- /// is truly boolean, that consumers of clap's configuration should only
- /// check whether the flag is present or not. Otherwise, consumers may
- /// inspect the number of times the switch is used.
- fn switch(long_name: &'static str) -> RGArg {
- let claparg = Arg::with_name(long_name).long(long_name);
- RGArg {
- claparg,
- name: long_name,
- doc_short: "",
- doc_long: "",
- hidden: false,
- kind: RGArgKind::Switch {
- long: long_name,
- short: None,
- multiple: false,
- },
- }
- }
- /// Create a flag. A flag always accepts exactly one argument.
- ///
- /// The `long_name` parameter is the name of the flag, e.g., `--long-name`.
- /// The `value_name` parameter is a name that describes the type of
- /// argument this flag accepts. It should be in uppercase, e.g., PATH or
- /// PATTERN.
- ///
- /// All flags may be repeated an arbitrary number of times. If a flag has
- /// only one logical value, that consumers of clap's configuration should
- /// only use the last value.
- fn flag(long_name: &'static str, value_name: &'static str) -> RGArg {
- let claparg = Arg::with_name(long_name)
- .long(long_name)
- .value_name(value_name)
- .takes_value(true)
- .number_of_values(1);
- RGArg {
- claparg,
- name: long_name,
- doc_short: "",
- doc_long: "",
- hidden: false,
- kind: RGArgKind::Flag {
- long: long_name,
- short: None,
- value_name,
- multiple: false,
- possible_values: vec![],
- },
- }
- }
- /// Set the short flag name.
- ///
- /// This panics if this arg isn't a switch or a flag.
- fn short(mut self, name: &'static str) -> RGArg {
- match self.kind {
- RGArgKind::Positional { .. } => panic!("expected switch or flag"),
- RGArgKind::Switch { ref mut short, .. } => {
- *short = Some(name);
- }
- RGArgKind::Flag { ref mut short, .. } => {
- *short = Some(name);
- }
- }
- self.claparg = self.claparg.short(name);
- self
- }
- /// Set the "short" help text.
- ///
- /// This should be a single line. It is shown in the `-h` output.
- fn help(mut self, text: &'static str) -> RGArg {
- self.doc_short = text;
- self.claparg = self.claparg.help(text);
- self
- }
- /// Set the "long" help text.
- ///
- /// This should be at least a single line, usually longer. It is shown in
- /// the `--help` output.
- fn long_help(mut self, text: &'static str) -> RGArg {
- self.doc_long = text;
- self.claparg = self.claparg.long_help(text);
- self
- }
- /// Enable this argument to accept multiple values.
- ///
- /// Note that while switches and flags can always be repeated an arbitrary
- /// number of times, this particular method enables the flag to be
- /// logically repeated where each occurrence of the flag may have
- /// significance. That is, when this is disabled, then a switch is either
- /// present or not and a flag has exactly one value (the last one given).
- /// When this is enabled, then a switch has a count corresponding to the
- /// number of times it is used and a flag's value is a list of all values
- /// given.
- ///
- /// For the most part, this distinction is resolved by consumers of clap's
- /// configuration.
- fn multiple(mut self) -> RGArg {
- // Why not put `multiple` on RGArg proper? Because it's useful to
- // document it distinct for each different kind. See RGArgKind docs.
- match self.kind {
- RGArgKind::Positional { ref mut multiple, .. } => {
- *multiple = true;
- }
- RGArgKind::Switch { ref mut multiple, .. } => {
- *multiple = true;
- }
- RGArgKind::Flag { ref mut multiple, .. } => {
- *multiple = true;
- }
- }
- self.claparg = self.claparg.multiple(true);
- self
- }
- /// Hide this flag from all documentation.
- fn hidden(mut self) -> RGArg {
- self.hidden = true;
- self.claparg = self.claparg.hidden(true);
- self
- }
- /// Set the possible values for this argument. If this argument is not
- /// a flag, then this panics.
- ///
- /// If the end user provides any value other than what is given here, then
- /// clap will report an error to the user.
- ///
- /// Note that this will suppress clap's automatic output of possible values
- /// when using -h/--help, so users of this method should provide
- /// appropriate documentation for the choices in the "long" help text.
- fn possible_values(mut self, values: &[&'static str]) -> RGArg {
- match self.kind {
- RGArgKind::Positional { .. } => panic!("expected flag"),
- RGArgKind::Switch { .. } => panic!("expected flag"),
- RGArgKind::Flag { ref mut possible_values, .. } => {
- *possible_values = values.to_vec();
- self.claparg = self
- .claparg
- .possible_values(values)
- .hide_possible_values(true);
- }
- }
- self
- }
- /// Add an alias to this argument.
- ///
- /// Aliases are not show in the output of -h/--help.
- fn alias(mut self, name: &'static str) -> RGArg {
- self.claparg = self.claparg.alias(name);
- self
- }
- /// Permit this flag to have values that begin with a hypen.
- ///
- /// This panics if this arg is not a flag.
- fn allow_leading_hyphen(mut self) -> RGArg {
- match self.kind {
- RGArgKind::Positional { .. } => panic!("expected flag"),
- RGArgKind::Switch { .. } => panic!("expected flag"),
- RGArgKind::Flag { .. } => {
- self.claparg = self.claparg.allow_hyphen_values(true);
- }
- }
- self
- }
- /// Sets this argument to a required argument, unless one of the given
- /// arguments is provided.
- fn required_unless(mut self, names: &[&'static str]) -> RGArg {
- self.claparg = self.claparg.required_unless_one(names);
- self
- }
- /// Sets conflicting arguments. That is, if this argument is used whenever
- /// any of the other arguments given here are used, then clap will report
- /// an error.
- fn conflicts(mut self, names: &[&'static str]) -> RGArg {
- self.claparg = self.claparg.conflicts_with_all(names);
- self
- }
- /// Sets an overriding argument. That is, if this argument and the given
- /// argument are both provided by an end user, then the "last" one will
- /// win. ripgrep will behave as if any previous instantiations did not
- /// happen.
- fn overrides(mut self, name: &'static str) -> RGArg {
- self.claparg = self.claparg.overrides_with(name);
- self
- }
- /// Sets the default value of this argument when not specified at
- /// runtime.
- fn default_value(mut self, value: &'static str) -> RGArg {
- self.claparg = self.claparg.default_value(value);
- self
- }
- /// Sets the default value of this argument if and only if the argument
- /// given is present.
- fn default_value_if(
- mut self,
- value: &'static str,
- arg_name: &'static str,
- ) -> RGArg {
- self.claparg = self.claparg.default_value_if(arg_name, None, value);
- self
- }
- /// Indicate that any value given to this argument should be a number. If
- /// it's not a number, then clap will report an error to the end user.
- fn number(mut self) -> RGArg {
- self.claparg = self.claparg.validator(|val| {
- val.parse::<usize>().map(|_| ()).map_err(|err| err.to_string())
- });
- self
- }
- }
- // We add an extra space to long descriptions so that a blank line is inserted
- // between flag descriptions in --help output.
- macro_rules! long {
- ($lit:expr) => {
- concat!($lit, " ")
- };
- }
- /// Generate a sequence of all positional and flag arguments.
- pub fn all_args_and_flags() -> Vec<RGArg> {
- let mut args = vec![];
- // The positional arguments must be defined first and in order.
- arg_pattern(&mut args);
- arg_path(&mut args);
- // Flags can be defined in any order, but we do it alphabetically. Note
- // that each function may define multiple flags. For example,
- // `flag_encoding` defines `--encoding` and `--no-encoding`. Most `--no`
- // flags are hidden and merely mentioned in the docs of the corresponding
- // "positive" flag.
- flag_after_context(&mut args);
- flag_auto_hybrid_regex(&mut args);
- flag_before_context(&mut args);
- flag_binary(&mut args);
- flag_block_buffered(&mut args);
- flag_byte_offset(&mut args);
- flag_case_sensitive(&mut args);
- flag_color(&mut args);
- flag_colors(&mut args);
- flag_column(&mut args);
- flag_context(&mut args);
- flag_context_separator(&mut args);
- flag_count(&mut args);
- flag_count_matches(&mut args);
- flag_crlf(&mut args);
- flag_debug(&mut args);
- flag_dfa_size_limit(&mut args);
- flag_encoding(&mut args);
- flag_engine(&mut args);
- flag_file(&mut args);
- flag_files(&mut args);
- flag_files_with_matches(&mut args);
- flag_files_without_match(&mut args);
- flag_fixed_strings(&mut args);
- flag_follow(&mut args);
- flag_glob(&mut args);
- flag_glob_case_insensitive(&mut args);
- flag_heading(&mut args);
- flag_hidden(&mut args);
- flag_iglob(&mut args);
- flag_ignore_case(&mut args);
- flag_ignore_file(&mut args);
- flag_ignore_file_case_insensitive(&mut args);
- flag_include_zero(&mut args);
- flag_invert_match(&mut args);
- flag_json(&mut args);
- flag_line_buffered(&mut args);
- flag_line_number(&mut args);
- flag_line_regexp(&mut args);
- flag_max_columns(&mut args);
- flag_max_columns_preview(&mut args);
- flag_max_count(&mut args);
- flag_max_depth(&mut args);
- flag_max_filesize(&mut args);
- flag_mmap(&mut args);
- flag_multiline(&mut args);
- flag_multiline_dotall(&mut args);
- flag_no_config(&mut args);
- flag_no_ignore(&mut args);
- flag_no_ignore_dot(&mut args);
- flag_no_ignore_exclude(&mut args);
- flag_no_ignore_files(&mut args);
- flag_no_ignore_global(&mut args);
- flag_no_ignore_messages(&mut args);
- flag_no_ignore_parent(&mut args);
- flag_no_ignore_vcs(&mut args);
- flag_no_messages(&mut args);
- flag_no_pcre2_unicode(&mut args);
- flag_no_require_git(&mut args);
- flag_no_unicode(&mut args);
- flag_null(&mut args);
- flag_null_data(&mut args);
- flag_one_file_system(&mut args);
- flag_only_matching(&mut args);
- flag_path_separator(&mut args);
- flag_passthru(&mut args);
- flag_pcre2(&mut args);
- flag_pcre2_version(&mut args);
- flag_pre(&mut args);
- flag_pre_glob(&mut args);
- flag_pretty(&mut args);
- flag_quiet(&mut args);
- flag_regex_size_limit(&mut args);
- flag_regexp(&mut args);
- flag_replace(&mut args);
- flag_search_zip(&mut args);
- flag_smart_case(&mut args);
- flag_sort_files(&mut args);
- flag_sort(&mut args);
- flag_sortr(&mut args);
- flag_stats(&mut args);
- flag_text(&mut args);
- flag_threads(&mut args);
- flag_trim(&mut args);
- flag_type(&mut args);
- flag_type_add(&mut args);
- flag_type_clear(&mut args);
- flag_type_list(&mut args);
- flag_type_not(&mut args);
- flag_unrestricted(&mut args);
- flag_vimgrep(&mut args);
- flag_with_filename(&mut args);
- flag_word_regexp(&mut args);
- args
- }
- fn arg_pattern(args: &mut Vec<RGArg>) {
- const SHORT: &str = "A regular expression used for searching.";
- const LONG: &str = long!(
- "\
- A regular expression used for searching. To match a pattern beginning with a
- dash, use the -e/--regexp flag.
- For example, to search for the literal '-foo', you can use this flag:
- rg -e -foo
- You can also use the special '--' delimiter to indicate that no more flags
- will be provided. Namely, the following is equivalent to the above:
- rg -- -foo
- "
- );
- let arg = RGArg::positional("pattern", "PATTERN")
- .help(SHORT)
- .long_help(LONG)
- .required_unless(&[
- "file",
- "files",
- "regexp",
- "type-list",
- "pcre2-version",
- ]);
- args.push(arg);
- }
- fn arg_path(args: &mut Vec<RGArg>) {
- const SHORT: &str = "A file or directory to search.";
- const LONG: &str = long!(
- "\
- A file or directory to search. Directories are searched recursively. File \
- paths specified on the command line override glob and ignore rules. \
- "
- );
- let arg = RGArg::positional("path", "PATH")
- .help(SHORT)
- .long_help(LONG)
- .multiple();
- args.push(arg);
- }
- fn flag_after_context(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Show NUM lines after each match.";
- const LONG: &str = long!(
- "\
- Show NUM lines after each match.
- This overrides the --context flag.
- "
- );
- let arg = RGArg::flag("after-context", "NUM")
- .short("A")
- .help(SHORT)
- .long_help(LONG)
- .number()
- .overrides("context");
- args.push(arg);
- }
- fn flag_auto_hybrid_regex(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Dynamically use PCRE2 if necessary.";
- const LONG: &str = long!(
- "\
- DEPRECATED. Use --engine instead.
- When this flag is used, ripgrep will dynamically choose between supported regex
- engines depending on the features used in a pattern. When ripgrep chooses a
- regex engine, it applies that choice for every regex provided to ripgrep (e.g.,
- via multiple -e/--regexp or -f/--file flags).
- As an example of how this flag might behave, ripgrep will attempt to use
- its default finite automata based regex engine whenever the pattern can be
- successfully compiled with that regex engine. If PCRE2 is enabled and if the
- pattern given could not be compiled with the default regex engine, then PCRE2
- will be automatically used for searching. If PCRE2 isn't available, then this
- flag has no effect because there is only one regex engine to choose from.
- In the future, ripgrep may adjust its heuristics for how it decides which
- regex engine to use. In general, the heuristics will be limited to a static
- analysis of the patterns, and not to any specific runtime behavior observed
- while searching files.
- The primary downside of using this flag is that it may not always be obvious
- which regex engine ripgrep uses, and thus, the match semantics or performance
- profile of ripgrep may subtly and unexpectedly change. However, in many cases,
- all regex engines will agree on what constitutes a match and it can be nice
- to transparently support more advanced regex features like look-around and
- backreferences without explicitly needing to enable them.
- This flag can be disabled with --no-auto-hybrid-regex.
- "
- );
- let arg = RGArg::switch("auto-hybrid-regex")
- .help(SHORT)
- .long_help(LONG)
- .overrides("no-auto-hybrid-regex")
- .overrides("pcre2")
- .overrides("no-pcre2")
- .overrides("engine");
- args.push(arg);
- let arg = RGArg::switch("no-auto-hybrid-regex")
- .hidden()
- .overrides("auto-hybrid-regex")
- .overrides("pcre2")
- .overrides("no-pcre2")
- .overrides("engine");
- args.push(arg);
- }
- fn flag_before_context(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Show NUM lines before each match.";
- const LONG: &str = long!(
- "\
- Show NUM lines before each match.
- This overrides the --context flag.
- "
- );
- let arg = RGArg::flag("before-context", "NUM")
- .short("B")
- .help(SHORT)
- .long_help(LONG)
- .number()
- .overrides("context");
- args.push(arg);
- }
- fn flag_binary(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Search binary files.";
- const LONG: &str = long!(
- "\
- Enabling this flag will cause ripgrep to search binary files. By default,
- ripgrep attempts to automatically skip binary files in order to improve the
- relevance of results and make the search faster.
- Binary files are heuristically detected based on whether they contain a NUL
- byte or not. By default (without this flag set), once a NUL byte is seen,
- ripgrep will stop searching the file. Usually, NUL bytes occur in the beginning
- of most binary files. If a NUL byte occurs after a match, then ripgrep will
- still stop searching the rest of the file, but a warning will be printed.
- In contrast, when this flag is provided, ripgrep will continue searching a file
- even if a NUL byte is found. In particular, if a NUL byte is found then ripgrep
- will continue searching until either a match is found or the end of the file is
- reached, whichever comes sooner. If a match is found, then ripgrep will stop
- and print a warning saying that the search stopped prematurely.
- If you want ripgrep to search a file without any special NUL byte handling at
- all (and potentially print binary data to stdout), then you should use the
- '-a/--text' flag.
- The '--binary' flag is a flag for controlling ripgrep's automatic filtering
- mechanism. As such, it does not need to be used when searching a file
- explicitly or when searching stdin. That is, it is only applicable when
- recursively searching a directory.
- Note that when the '-u/--unrestricted' flag is provided for a third time, then
- this flag is automatically enabled.
- This flag can be disabled with '--no-binary'. It overrides the '-a/--text'
- flag.
- "
- );
- let arg = RGArg::switch("binary")
- .help(SHORT)
- .long_help(LONG)
- .overrides("no-binary")
- .overrides("text")
- .overrides("no-text");
- args.push(arg);
- let arg = RGArg::switch("no-binary")
- .hidden()
- .overrides("binary")
- .overrides("text")
- .overrides("no-text");
- args.push(arg);
- }
- fn flag_block_buffered(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Force block buffering.";
- const LONG: &str = long!(
- "\
- When enabled, ripgrep will use block buffering. That is, whenever a matching
- line is found, it will be written to an in-memory buffer and will not be
- written to stdout until the buffer reaches a certain size. This is the default
- when ripgrep's stdout is redirected to a pipeline or a file. When ripgrep's
- stdout is connected to a terminal, line buffering will be used. Forcing block
- buffering can be useful when dumping a large amount of contents to a terminal.
- Forceful block buffering can be disabled with --no-block-buffered. Note that
- using --no-block-buffered causes ripgrep to revert to its default behavior of
- automatically detecting the buffering strategy. To force line buffering, use
- the --line-buffered flag.
- "
- );
- let arg = RGArg::switch("block-buffered")
- .help(SHORT)
- .long_help(LONG)
- .overrides("no-block-buffered")
- .overrides("line-buffered")
- .overrides("no-line-buffered");
- args.push(arg);
- let arg = RGArg::switch("no-block-buffered")
- .hidden()
- .overrides("block-buffered")
- .overrides("line-buffered")
- .overrides("no-line-buffered");
- args.push(arg);
- }
- fn flag_byte_offset(args: &mut Vec<RGArg>) {
- const SHORT: &str =
- "Print the 0-based byte offset for each matching line.";
- const LONG: &str = long!(
- "\
- Print the 0-based byte offset within the input file before each line of output.
- If -o (--only-matching) is specified, print the offset of the matching part
- itself.
- If ripgrep does transcoding, then the byte offset is in terms of the the result
- of transcoding and not the original data. This applies similarly to another
- transformation on the source, such as decompression or a --pre filter. Note
- that when the PCRE2 regex engine is used, then UTF-8 transcoding is done by
- default.
- "
- );
- let arg =
- RGArg::switch("byte-offset").short("b").help(SHORT).long_help(LONG);
- args.push(arg);
- }
- fn flag_case_sensitive(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Search case sensitively (default).";
- const LONG: &str = long!(
- "\
- Search case sensitively.
- This overrides the -i/--ignore-case and -S/--smart-case flags.
- "
- );
- let arg = RGArg::switch("case-sensitive")
- .short("s")
- .help(SHORT)
- .long_help(LONG)
- .overrides("ignore-case")
- .overrides("smart-case");
- args.push(arg);
- }
- fn flag_color(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Controls when to use color.";
- const LONG: &str = long!(
- "\
- This flag controls when to use colors. The default setting is 'auto', which
- means ripgrep will try to guess when to use colors. For example, if ripgrep is
- printing to a terminal, then it will use colors, but if it is redirected to a
- file or a pipe, then it will suppress color output. ripgrep will suppress color
- output in some other circumstances as well. For example, if the TERM
- environment variable is not set or set to 'dumb', then ripgrep will not use
- colors.
- The possible values for this flag are:
- never Colors will never be used.
- auto The default. ripgrep tries to be smart.
- always Colors will always be used regardless of where output is sent.
- ansi Like 'always', but emits ANSI escapes (even in a Windows console).
- When the --vimgrep flag is given to ripgrep, then the default value for the
- --color flag changes to 'never'.
- "
- );
- let arg = RGArg::flag("color", "WHEN")
- .help(SHORT)
- .long_help(LONG)
- .possible_values(&["never", "auto", "always", "ansi"])
- .default_value_if("never", "vimgrep");
- args.push(arg);
- }
- fn flag_colors(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Configure color settings and styles.";
- const LONG: &str = long!(
- "\
- This flag specifies color settings for use in the output. This flag may be
- provided multiple times. Settings are applied iteratively. Colors are limited
- to one of eight choices: red, blue, green, cyan, magenta, yellow, white and
- black. Styles are limited to nobold, bold, nointense, intense, nounderline
- or underline.
- The format of the flag is '{type}:{attribute}:{value}'. '{type}' should be
- one of path, line, column or match. '{attribute}' can be fg, bg or style.
- '{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}'.
- For example, the following command will change the match color to magenta and
- the background color for line numbers to yellow:
- rg --colors 'match:fg:magenta' --colors 'line:bg:yellow' foo.
- Extended colors can be used for '{value}' when the terminal supports ANSI color
- sequences. These are specified as either 'x' (256-color) or 'x,x,x' (24-bit
- truecolor) where x is a number between 0 and 255 inclusive. x may be given as
- a normal decimal number or a hexadecimal number, which is prefixed by `0x`.
- For example, the following command will change the match background color to
- that represented by the rgb value (0,128,255):
- rg --colors 'match:bg:0,128,255'
- or, equivalently,
- rg --colors 'match:bg:0x0,0x80,0xFF'
- Note that the the intense and nointense style flags will have no effect when
- used alongside these extended color codes.
- "
- );
- let arg = RGArg::flag("colors", "COLOR_SPEC")
- .help(SHORT)
- .long_help(LONG)
- .multiple();
- args.push(arg);
- }
- fn flag_column(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Show column numbers.";
- const LONG: &str = long!(
- "\
- Show column numbers (1-based). This only shows the column numbers for the first
- match on each line. This does not try to account for Unicode. One byte is equal
- to one column. This implies --line-number.
- This flag can be disabled with --no-column.
- "
- );
- let arg = RGArg::switch("column")
- .help(SHORT)
- .long_help(LONG)
- .overrides("no-column");
- args.push(arg);
- let arg = RGArg::switch("no-column").hidden().overrides("column");
- args.push(arg);
- }
- fn flag_context(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Show NUM lines before and after each match.";
- const LONG: &str = long!(
- "\
- Show NUM lines before and after each match. This is equivalent to providing
- both the -B/--before-context and -A/--after-context flags with the same value.
- This overrides both the -B/--before-context and -A/--after-context flags.
- "
- );
- let arg = RGArg::flag("context", "NUM")
- .short("C")
- .help(SHORT)
- .long_help(LONG)
- .number()
- .overrides("before-context")
- .overrides("after-context");
- args.push(arg);
- }
- fn flag_context_separator(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Set the context separator string.";
- const LONG: &str = long!(
- "\
- The string used to separate non-contiguous context lines in the output. This
- is only used when one of the context flags is used (-A, -B or -C). Escape
- sequences like \\x7F or \\t may be used. The default value is --.
- When the context separator is set to an empty string, then a line break
- is still inserted. To completely disable context separators, use the
- --no-context-separator flag.
- "
- );
- let arg = RGArg::flag("context-separator", "SEPARATOR")
- .help(SHORT)
- .long_help(LONG)
- .overrides("no-context-separator");
- args.push(arg);
- let arg = RGArg::switch("no-context-separator")
- .hidden()
- .overrides("context-separator");
- args.push(arg);
- }
- fn flag_count(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Only show the count of matching lines for each file.";
- const LONG: &str = long!(
- "\
- This flag suppresses normal output and shows the number of lines that match
- the given patterns for each file searched. Each file containing a match has its
- path and count printed on each line. Note that this reports the number of lines
- that match and not the total number of matches.
- If only one file is given to ripgrep, then only the count is printed if there
- is a match. The --with-filename flag can be used to force printing the file
- path in this case.
- This overrides the --count-matches flag. Note that when --count is combined
- with --only-matching, then ripgrep behaves as if --count-matches was given.
- "
- );
- let arg = RGArg::switch("count")
- .short("c")
- .help(SHORT)
- .long_help(LONG)
- .overrides("count-matches");
- args.push(arg);
- }
- fn flag_count_matches(args: &mut Vec<RGArg>) {
- const SHORT: &str =
- "Only show the count of individual matches for each file.";
- const LONG: &str = long!(
- "\
- This flag suppresses normal output and shows the number of individual
- matches of the given patterns for each file searched. Each file
- containing matches has its path and match count printed on each line.
- Note that this reports the total number of individual matches and not
- the number of lines that match.
- If only one file is given to ripgrep, then only the count is printed if there
- is a match. The --with-filename flag can be used to force printing the file
- path in this case.
- This overrides the --count flag. Note that when --count is combined with
- --only-matching, then ripgrep behaves as if --count-matches was given.
- "
- );
- let arg = RGArg::switch("count-matches")
- .help(SHORT)
- .long_help(LONG)
- .overrides("count");
- args.push(arg);
- }
- fn flag_crlf(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Support CRLF line terminators (useful on Windows).";
- const LONG: &str = long!(
- "\
- When enabled, ripgrep will treat CRLF ('\\r\\n') as a line terminator instead
- of just '\\n'.
- Principally, this permits '$' in regex patterns to match just before CRLF
- instead of just before LF. The underlying regex engine may not support this
- natively, so ripgrep will translate all instances of '$' to '(?:\\r??$)'. This
- may produce slightly different than desired match offsets. It is intended as a
- work-around until the regex engine supports this natively.
- CRLF support can be disabled with --no-crlf.
- "
- );
- let arg = RGArg::switch("crlf")
- .help(SHORT)
- .long_help(LONG)
- .overrides("no-crlf")
- .overrides("null-data");
- args.push(arg);
- let arg = RGArg::switch("no-crlf").hidden().overrides("crlf");
- args.push(arg);
- }
- fn flag_debug(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Show debug messages.";
- const LONG: &str = long!(
- "\
- Show debug messages. Please use this when filing a bug report.
- The --debug flag is generally useful for figuring out why ripgrep skipped
- searching a particular file. The debug messages should mention all files
- skipped and why they were skipped.
- To get even more debug output, use the --trace flag, which implies --debug
- along with additional trace data. With --trace, the output could be quite
- large and is generally more useful for development.
- "
- );
- let arg = RGArg::switch("debug").help(SHORT).long_help(LONG);
- args.push(arg);
- let arg = RGArg::switch("trace").hidden().overrides("debug");
- args.push(arg);
- }
- fn flag_dfa_size_limit(args: &mut Vec<RGArg>) {
- const SHORT: &str = "The upper size limit of the regex DFA.";
- const LONG: &str = long!(
- "\
- The upper size limit of the regex DFA. The default limit is 10M. This should
- only be changed on very large regex inputs where the (slower) fallback regex
- engine may otherwise be used if the limit is reached.
- The argument accepts the same size suffixes as allowed in with the
- --max-filesize flag.
- "
- );
- let arg = RGArg::flag("dfa-size-limit", "NUM+SUFFIX?")
- .help(SHORT)
- .long_help(LONG);
- args.push(arg);
- }
- fn flag_encoding(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Specify the text encoding of files to search.";
- const LONG: &str = long!(
- "\
- Specify the text encoding that ripgrep will use on all files searched. The
- default value is 'auto', which will cause ripgrep to do a best effort automatic
- detection of encoding on a per-file basis. Automatic detection in this case
- only applies to files that begin with a UTF-8 or UTF-16 byte-order mark (BOM).
- No other automatic detection is performed. One can also specify 'none' which
- will then completely disable BOM sniffing and always result in searching the
- raw bytes, including a BOM if it's present, regardless of its encoding.
- Other supported values can be found in the list of labels here:
- https://encoding.spec.whatwg.org/#concept-encoding-get
- For more details on encoding and how ripgrep deals with it, see GUIDE.md.
- This flag can be disabled with --no-encoding.
- "
- );
- let arg = RGArg::flag("encoding", "ENCODING")
- .short("E")
- .help(SHORT)
- .long_help(LONG);
- args.push(arg);
- let arg = RGArg::switch("no-encoding").hidden().overrides("encoding");
- args.push(arg);
- }
- fn flag_engine(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Specify which regexp engine to use.";
- const LONG: &str = long!(
- "\
- Specify which regular expression engine to use. When you choose a regex engine,
- it applies that choice for every regex provided to ripgrep (e.g., via multiple
- -e/--regexp or -f/--file flags).
- Accepted values are 'default', 'pcre2', or 'auto'.
- The default value is 'default', which is the fastest and should be good for
- most use cases. The 'pcre2' engine is generally useful when you want to use
- features such as look-around or backreferences. 'auto' will dynamically choose
- between supported regex engines depending on the features used in a pattern on
- a best effort basis.
- Note that the 'pcre2' engine is an optional ripgrep feature. If PCRE2 wasn't
- including in your build of ripgrep, then using this flag will result in ripgrep
- printing an error message and exiting.
- This overrides previous uses of --pcre2 and --auto-hybrid-regex flags.
- "
- );
- let arg = RGArg::flag("engine", "ENGINE")
- .help(SHORT)
- .long_help(LONG)
- .possible_values(&["default", "pcre2", "auto"])
- .default_value("default")
- .overrides("pcre2")
- .overrides("no-pcre2")
- .overrides("auto-hybrid-regex")
- .overrides("no-auto-hybrid-regex");
- args.push(arg);
- }
- fn flag_file(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Search for patterns from the given file.";
- const LONG: &str = long!(
- "\
- Search for patterns from the given file, with one pattern per line. When this
- flag is used multiple times or in combination with the -e/--regexp flag,
- then all patterns provided are searched. Empty pattern lines will match all
- input lines, and the newline is not counted as part of the pattern.
- A line is printed if and only if it matches at least one of the patterns.
- "
- );
- let arg = RGArg::flag("file", "PATTERNFILE")
- .short("f")
- .help(SHORT)
- .long_help(LONG)
- .multiple()
- .allow_leading_hyphen();
- args.push(arg);
- }
- fn flag_files(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Print each file that would be searched.";
- const LONG: &str = long!(
- "\
- Print each file that would be searched without actually performing the search.
- This is useful to determine whether a particular file is being searched or not.
- "
- );
- let arg = RGArg::switch("files")
- .help(SHORT)
- .long_help(LONG)
- // This also technically conflicts with pattern, but the first file
- // path will actually be in pattern.
- .conflicts(&["file", "regexp", "type-list"]);
- args.push(arg);
- }
- fn flag_files_with_matches(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Only print the paths with at least one match.";
- const LONG: &str = long!(
- "\
- Only print the paths with at least one match.
- This overrides --files-without-match.
- "
- );
- let arg = RGArg::switch("files-with-matches")
- .short("l")
- .help(SHORT)
- .long_help(LONG)
- .overrides("files-without-match");
- args.push(arg);
- }
- fn flag_files_without_match(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Only print the paths that contain zero matches.";
- const LONG: &str = long!(
- "\
- Only print the paths that contain zero matches. This inverts/negates the
- --files-with-matches flag.
- This overrides --files-with-matches.
- "
- );
- let arg = RGArg::switch("files-without-match")
- .help(SHORT)
- .long_help(LONG)
- .overrides("files-with-matches");
- args.push(arg);
- }
- fn flag_fixed_strings(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Treat the pattern as a literal string.";
- const LONG: &str = long!(
- "\
- Treat the pattern as a literal string instead of a regular expression. When
- this flag is used, special regular expression meta characters such as .(){}*+
- do not need to be escaped.
- This flag can be disabled with --no-fixed-strings.
- "
- );
- let arg = RGArg::switch("fixed-strings")
- .short("F")
- .help(SHORT)
- .long_help(LONG)
- .overrides("no-fixed-strings");
- args.push(arg);
- let arg =
- RGArg::switch("no-fixed-strings").hidden().overrides("fixed-strings");
- args.push(arg);
- }
- fn flag_follow(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Follow symbolic links.";
- const LONG: &str = long!(
- "\
- When this flag is enabled, ripgrep will follow symbolic links while traversing
- directories. This is disabled by default. Note that ripgrep will check for
- symbolic link loops and report errors if it finds one.
- This flag can be disabled with --no-follow.
- "
- );
- let arg = RGArg::switch("follow")
- .short("L")
- .help(SHORT)
- .long_help(LONG)
- .overrides("no-follow");
- args.push(arg);
- let arg = RGArg::switch("no-follow").hidden().overrides("follow");
- args.push(arg);
- }
- fn flag_glob(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Include or exclude files.";
- const LONG: &str = long!(
- "\
- Include or exclude files and directories for searching that match the given
- glob. This always overrides any other ignore logic. Multiple glob flags may be
- used. Globbing rules match .gitignore globs. Precede a glob with a ! to exclude
- it. If multiple globs match a file or directory, the glob given later in the
- command line takes precedence.
- When this flag is set, every file and directory is applied to it to test for
- a match. So for example, if you only want to search in a particular directory
- 'foo', then *-g foo* is incorrect because 'foo/bar' does not match the glob
- 'foo'. Instead, you should use *-g 'foo/**'*.
- "
- );
- let arg = RGArg::flag("glob", "GLOB")
- .short("g")
- .help(SHORT)
- .long_help(LONG)
- .multiple()
- .allow_leading_hyphen();
- args.push(arg);
- }
- fn flag_glob_case_insensitive(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Process all glob patterns case insensitively.";
- const LONG: &str = long!(
- "\
- Process glob patterns given with the -g/--glob flag case insensitively. This
- effectively treats --glob as --iglob.
- This flag can be disabled with the --no-glob-case-insensitive flag.
- "
- );
- let arg = RGArg::switch("glob-case-insensitive")
- .help(SHORT)
- .long_help(LONG)
- .overrides("no-glob-case-insensitive");
- args.push(arg);
- let arg = RGArg::switch("no-glob-case-insensitive")
- .hidden()
- .overrides("glob-case-insensitive");
- args.push(arg);
- }
- fn flag_heading(args: &mut Vec<RGArg>) {
- const SHORT: &str = "Print matches grouped by each file.";
- const LONG: &str = long!(
- "\
- This flag prints the file path above clusters of matches from each file instead
- of printing the file path as a prefix for each matched line. This is the
- default mode when printing to a terminal.
- This overrides the --no-heading flag.
- "
- );
- let arg = RGArg::switch("heading")
- .help(SHORT)
- .long_help(LONG)
- .overrides("no-heading");
- args.push(arg);
- const NO_SHORT: &str = "Don't group matches by each file.";
- const NO_LONG: &str = long!(
- "\
- Don't group matches by each file. If --no-heading is provided in addition to
- the -H/--with-filename flag, then file paths will be pr…
Large files files are truncated, but you can click here to view the full file