Skip to main content

rgx/config/
cli.rs

1use clap::{CommandFactory, Parser};
2use clap_complete::{generate, Shell};
3
4#[derive(Parser, Debug)]
5#[command(
6    name = "rgx",
7    version,
8    about = "Terminal regex tester with real-time matching and multi-engine support",
9    long_about = "Test and debug regular expressions without leaving your terminal. Supports 3 engines (Rust regex, fancy-regex, PCRE2), capture group highlighting, plain-English explanations, and replace mode. Useful for remote work, shell pipelines, and engine-specific testing."
10)]
11pub struct Cli {
12    /// Initial regex pattern
13    #[arg(value_name = "PATTERN")]
14    pub pattern: Option<String>,
15
16    /// Engine to use: rust, fancy, or pcre2
17    #[arg(short, long)]
18    pub engine: Option<String>,
19
20    /// Case-insensitive matching
21    #[arg(short = 'i', long)]
22    pub case_insensitive: bool,
23
24    /// Multi-line mode
25    #[arg(short = 'm', long)]
26    pub multiline: bool,
27
28    /// Dot matches newline
29    #[arg(short = 's', long)]
30    pub dotall: bool,
31
32    /// Unicode mode
33    #[arg(short = 'u', long)]
34    pub unicode: Option<bool>,
35
36    /// Extended mode (ignore whitespace)
37    #[arg(short = 'x', long)]
38    pub extended: bool,
39
40    /// Initial replacement string
41    #[arg(short = 'r', long)]
42    pub replacement: Option<String>,
43
44    /// Read test string from file
45    #[arg(short = 'f', long)]
46    pub file: Option<String>,
47
48    /// Test string (alternative to stdin or file)
49    #[arg(short = 't', long)]
50    pub text: Option<String>,
51
52    /// Load workspace from file
53    #[arg(short = 'l', long, conflicts_with = "workspace")]
54    pub load: Option<String>,
55
56    /// Use a workspace file for save/load (creates if missing)
57    #[arg(short = 'w', long, conflicts_with = "load")]
58    pub workspace: Option<String>,
59
60    /// Print matches to stdout and exit (non-interactive batch mode).
61    /// Requires a pattern and input (stdin, --file, or --text).
62    #[arg(short = 'p', long)]
63    pub print: bool,
64
65    /// After interactive session, print the final pattern to stdout instead of matches.
66    /// Useful for: eval $(rgx -P)
67    #[arg(short = 'P', long, conflicts_with = "print")]
68    pub output_pattern: bool,
69
70    /// Print a specific capture group instead of the full match (use with --print).
71    /// Accepts a group number (1, 2, ...) or a named group.
72    #[arg(short = 'g', long, requires = "print", conflicts_with = "count")]
73    pub group: Option<String>,
74
75    /// Print only the count of matches (use with --print).
76    #[arg(short = 'c', long, requires = "print", conflicts_with = "group")]
77    pub count: bool,
78
79    /// Output matches as JSON (use with --print).
80    #[arg(long, requires = "print")]
81    pub json: bool,
82
83    /// Colorize match output: auto (default), always, or never (use with --print).
84    #[arg(long, default_value = "auto", requires = "print")]
85    pub color: ColorMode,
86
87    /// Run test assertions from workspace file(s) and exit.
88    /// Expects TOML files with \[\[tests\]\] sections.
89    #[arg(long, num_args = 1.., value_name = "FILE")]
90    pub test: Option<Vec<String>>,
91
92    /// Use rounded border characters for panels.
93    #[arg(long)]
94    pub rounded: bool,
95
96    /// Enable vim-style modal keybindings (Normal/Insert mode).
97    #[arg(long)]
98    pub vim: bool,
99
100    /// Generate shell completions and exit.
101    #[arg(long, value_name = "SHELL")]
102    pub completions: Option<Shell>,
103}
104
105#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
106pub enum ColorMode {
107    Auto,
108    Always,
109    Never,
110}
111
112impl Cli {
113    pub fn print_completions(shell: Shell) {
114        let mut cmd = Self::command();
115        generate(shell, &mut cmd, "rgx", &mut std::io::stdout());
116    }
117}