1
0
mirror of https://github.com/BurntSushi/ripgrep.git synced 2025-03-23 04:34:39 +02:00
Jan Verbeek 8575d26179 complete/fish: Fix syntax for negated options
And also, negated options don't take arguments.

Specifically, the fish completion generator currently forgets to add
`-l` to negation options, leading to a list of these errors:

    complete: too many arguments

    ~/.config/fish/completions/rg.fish (line 146):
    complete -c rg -n '__fish_use_subcommand'  no-sort-files -d '(DEPRECATED) Sort results by file path.'
    ^
    from sourcing file ~/.config/fish/completions/rg.fish

    (Type 'help complete' for related documentation)

To reproduce, run `fish -c 'rg --generate=complete-fish | source'`.

It also potentially suggests a list of choices for negation options,
even though those never take arguments. That case doesn't occur with
any of the current options but it's an easy fix.

Fixes #2659, Closes #2655
2023-11-27 21:17:12 -05:00

49 lines
1.6 KiB
Rust

/*!
Provides completions for ripgrep's CLI for the fish shell.
*/
use crate::flags::defs::FLAGS;
const TEMPLATE: &'static str =
"complete -c rg -n '__fish_use_subcommand' !SHORT! !LONG! !DOC!\n";
const TEMPLATE_CHOICES: &'static str =
"complete -c rg -n '__fish_use_subcommand' !SHORT! !LONG! !DOC! -r -f -a '!CHOICES!'\n";
/// Generate completions for Fish.
///
/// Note that these completions are based on what was produced for ripgrep <=13
/// using Clap 2.x. Improvements on this are welcome.
pub(crate) fn generate() -> String {
let mut out = String::new();
for flag in FLAGS.iter() {
let short = match flag.name_short() {
None => "".to_string(),
Some(byte) => format!("-s {}", char::from(byte)),
};
let long = format!("-l '{}'", flag.name_long().replace("'", "\\'"));
let doc = format!("-d '{}'", flag.doc_short().replace("'", "\\'"));
let template = if flag.doc_choices().is_empty() {
TEMPLATE.to_string()
} else {
TEMPLATE_CHOICES
.replace("!CHOICES!", &flag.doc_choices().join(" "))
};
out.push_str(
&template
.replace("!SHORT!", &short)
.replace("!LONG!", &long)
.replace("!DOC!", &doc),
);
if let Some(negated) = flag.name_negated() {
let long = format!("-l '{}'", negated.replace("'", "\\'"));
out.push_str(
&TEMPLATE
.replace("!SHORT!", "")
.replace("!LONG!", &long)
.replace("!DOC!", &doc),
);
}
}
out
}