summaryrefslogtreecommitdiffstats
path: root/crates
diff options
context:
space:
mode:
authorAndrew Gallant <jamslam@gmail.com>2023-10-16 18:05:39 -0400
committerAndrew Gallant <jamslam@gmail.com>2023-11-20 23:51:53 -0500
commit082245dadb3854238e62b91aa95a46018cf16ef1 (patch)
tree8170196f77908196547cc8e3a7e99129aa586a08 /crates
parentc33f6237199cd3ae6f884f5fe0f6ccf57f805a28 (diff)
cli: replace clap with lexopt and supporting code
ripgrep began it's life with docopt for argument parsing. Then it moved to Clap and stayed there for a number of years. Clap has served ripgrep well, and it probably could continue to serve ripgrep well, but I ended up deciding to move off of it. Why? The first time I had the thought of moving off of Clap was during the 2->3->4 transition. I thought the 3.x and 4.x releases were great, but for me, it ended up moving a little too quickly. Since the release of 4.x was telegraphed around when 3.x came out, I decided to just hold off and wait to migrate to 4.x instead of doing a 3.x migration followed shortly by another 4.x migration. Of course, I just never ended up doing the migration at all. I never got around to it and there just wasn't a compelling reason for me to upgrade. While I never investigated it, I saw an upgrade as a non-trivial amount of work in part because I didn't encapsulate the usage of Clap enough. The above is just what got me started thinking about it. It wasn't enough to get me to move off of it on its own. What ended up pushing me over the edge was a combination of factors: * As mentioned above, I didn't want to run on the migration treadmill. This has proven to not be much of an issue, but at the time of the 2->3->4 releases, I didn't know how long Clap 4.x would be out before a 5.x would come out. * The release of lexopt[1] caught my eye. IMO, that crate demonstrates exactly how something new can arrive on the scene and just thoroughly solve a problem minimalistically. It has the docs, the reasoning, the simple API, the tests and good judgment. It gets all the weird corner cases right that Clap also gets right (and is part of why I was originally attracted to Clap). * I have an overall desire to reduce the size of my dependency tree. In part because a smaller dependency tree tends to correlate with better compile times, but also in part because it reduces my reliance and trust on others. It lets me be the "master" of ripgrep's destiny by reducing the amount of behavior that is the result of someone else's decision (whether good or bad). * I perceived that Clap solves a more general problem than what I actually need solved. Despite the vast number of flags that ripgrep has, its requirements are actually pretty simple. We just need simple switches and flags that support one value. No multi-value flags. No sub-commands. And probably a lot of other functionality that Clap has that makes it so flexible for so many different use cases. (I'm being hand wavy on the last point.) With all that said, perhaps most importantly, the future of ripgrep possibly demands a more flexible CLI argument parser. In today's world, I would really like, for example, flags like `--type` and `--type-not` to be able to accumulate their repeated values into a single sequence while respecting the order they appear on the CLI. For example, prior to this migration, `rg regex-automata -Tlock -ttoml` would not return results in `Cargo.lock` in this repository because the `-Tlock` always took priority even though `-ttoml` appeared after it. But with this migration, `-ttoml` now correctly overrides `-Tlock`. We would like to do similar things for `-g/--glob` and `--iglob` and potentially even now introduce a `-G/--glob-not` flag instead of requiring users to use `!` to negate a glob. (Which I had done originally to work-around this problem.) And some day, I'd like to add some kind of boolean matching to ripgrep perhaps similar to how `git grep` does it. (Although I haven't thought too carefully on a design yet.) In order to do that, I perceive it would be difficult to implement correctly in Clap. I believe that this last point is possible to implement correctly in Clap 2.x, although it is awkward to do so. I have not looked closely enough at the Clap 4.x API to know whether it's still possible there. In any case, these were enough reasons to move off of Clap and own more of the argument parsing process myself. This did require a few things: * I had to write my own logic for how arguments are combined into one single state object. Of course, I wanted this. This was part of the upside. But it's still code I didn't have to write for Clap. * I had to write my own shell completion generator. * I had to write my own `-h/--help` output generator. * I also had to write my own man page generator. Well, I had to do this with Clap 2.x too, although my understanding is that Clap 4.x supports this. With that said, without having tried it, my guess is that I probably wouldn't have liked the output it generated because I ultimately had to write most of the roff by hand myself to get the man page I wanted. (This also had the benefit of dropping the build dependency on asciidoc/asciidoctor.) While this is definitely a fair bit of extra work, it overall only cost me a couple days. IMO, that's a good trade off given that this code is unlikely to change again in any substantial way. And it should also allow for more flexible semantics going forward. Fixes #884, Fixes #1648, Fixes #1701, Fixes #1814, Fixes #1966 [1]: https://docs.rs/lexopt/0.3.0/lexopt/index.html
Diffstat (limited to 'crates')
-rw-r--r--crates/cli/src/wtr.rs2
-rw-r--r--crates/core/app.rs3251
-rw-r--r--crates/core/args.rs1975
-rw-r--r--crates/core/flags/complete/bash.rs107
-rw-r--r--crates/core/flags/complete/fish.rs47
-rw-r--r--crates/core/flags/complete/mod.rs8
-rw-r--r--crates/core/flags/complete/powershell.rs86
-rw-r--r--crates/core/flags/complete/rg.zsh661
-rw-r--r--crates/core/flags/complete/zsh.rs23
-rw-r--r--crates/core/flags/config.rs (renamed from crates/core/config.rs)9
-rw-r--r--crates/core/flags/defs.rs7625
-rw-r--r--crates/core/flags/doc/help.rs259
-rw-r--r--crates/core/flags/doc/man.rs110
-rw-r--r--crates/core/flags/doc/mod.rs38
-rw-r--r--crates/core/flags/doc/template.long.help61
-rw-r--r--crates/core/flags/doc/template.rg.1415
-rw-r--r--crates/core/flags/doc/template.short.help38
-rw-r--r--crates/core/flags/doc/version.rs148
-rw-r--r--crates/core/flags/hiargs.rs1409
-rw-r--r--crates/core/flags/lowargs.rs758
-rw-r--r--crates/core/flags/mod.rs282
-rw-r--r--crates/core/flags/parse.rs392
-rw-r--r--crates/core/haystack.rs (renamed from crates/core/subject.rs)117
-rw-r--r--crates/core/logger.rs16
-rw-r--r--crates/core/main.rs547
-rw-r--r--crates/core/messages.rs61
-rw-r--r--crates/core/search.rs272
-rw-r--r--crates/printer/src/json.rs2
-rw-r--r--crates/printer/src/standard.rs2
-rw-r--r--crates/printer/src/summary.rs2
-rw-r--r--crates/printer/src/util.rs16
-rw-r--r--crates/searcher/src/searcher/mod.rs2
32 files changed, 13027 insertions, 5714 deletions
diff --git a/crates/cli/src/wtr.rs b/crates/cli/src/wtr.rs
index f6c7306b..44eb54d5 100644
--- a/crates/cli/src/wtr.rs
+++ b/crates/cli/src/wtr.rs
@@ -3,6 +3,7 @@ use std::io::{self, IsTerminal};
use termcolor::{self, HyperlinkSpec};
/// A writer that supports coloring with either line or block buffering.
+#[derive(Debug)]
pub struct StandardStream(StandardStreamKind);
/// Returns a possibly buffered writer to stdout for the given color choice.
@@ -57,6 +58,7 @@ pub fn stdout_buffered_block(
StandardStream(StandardStreamKind::BlockBuffered(out))
}
+#[derive(Debug)]
enum StandardStreamKind {
LineBuffered(termcolor::StandardStream),
BlockBuffered(termcolor::BufferedStandardStream),
diff --git a/crates/core/app.rs b/crates/core/app.rs
deleted file mode 100644
index 3e0247f4..00000000
--- a/crates/core/app.rs
+++ /dev/null
@@ -1,3251 +0,0 @@
-// 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};
-
-const ABOUT: &str = "
-ripgrep (rg) recursively searches the current directory for a regex pattern.
-By default, ripgrep will respect gitignore rules 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 ... [PATH ...]
- rg [OPTIONS] -f PATTERNFILE ... [PATH ...]
- rg [OPTIONS] --files [PATH ...]
- rg [OPTIONS] --type-list
- command | rg [OPTIONS] PATTERN
- rg [OPTIONS] --help
- rg [OPTIONS] --version";
-
-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> {
- use std::sync::OnceLock;
-
- // 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.
- static LONG_VERSION: OnceLock<String> = OnceLock::new();
- let long_version = LONG_VERSION.get_or_init(|| 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 hyphen.
- ///
- /// 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_field_context_separator(&mut args);
- flag_field_match_separator(&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_hostname_bin(&mut args);
- flag_hyperlink_format(&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_stop_on_nonmatch(&