mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-07-31 04:02:00 -07:00
The fish completions now also pay attention to the configuration file to determine whether to suggest negation options and not just to the current command line. This doesn't cover all edge cases. For example the config file is cached, and so changes may not take effect until the next shell session. But the cases it doesn't cover are hopefully very rare. Closes #2708
77 lines
2.6 KiB
Rust
77 lines
2.6 KiB
Rust
/*!
|
|
Provides completions for ripgrep's CLI for the fish shell.
|
|
*/
|
|
|
|
use crate::flags::{defs::FLAGS, CompletionType};
|
|
|
|
const TEMPLATE: &'static str = "complete -c rg !SHORT! -l !LONG! -d '!DOC!'";
|
|
const TEMPLATE_NEGATED: &'static str =
|
|
"complete -c rg -l !NEGATED! -n '__rg_contains_opt !LONG! !SHORT!' -d '!DOC!'\n";
|
|
|
|
/// Generate completions for Fish.
|
|
///
|
|
/// Reference: <https://fishshell.com/docs/current/completions.html>
|
|
pub(crate) fn generate() -> String {
|
|
let mut out = String::new();
|
|
out.push_str(include_str!("prelude.fish"));
|
|
out.push('\n');
|
|
for flag in FLAGS.iter() {
|
|
let short = match flag.name_short() {
|
|
None => "".to_string(),
|
|
Some(byte) => format!("-s {}", char::from(byte)),
|
|
};
|
|
let long = flag.name_long();
|
|
let doc = flag.doc_short().replace("'", "\\'");
|
|
let mut completion = TEMPLATE
|
|
.replace("!SHORT!", &short)
|
|
.replace("!LONG!", &long)
|
|
.replace("!DOC!", &doc);
|
|
|
|
match flag.completion_type() {
|
|
CompletionType::Filename => {
|
|
completion.push_str(" -r -F");
|
|
}
|
|
CompletionType::Executable => {
|
|
completion.push_str(" -r -f -a '(__fish_complete_command)'");
|
|
}
|
|
CompletionType::Filetype => {
|
|
completion.push_str(
|
|
" -r -f -a '(rg --type-list | string replace : \\t)'",
|
|
);
|
|
}
|
|
CompletionType::Encoding => {
|
|
completion.push_str(" -r -f -a '");
|
|
completion.push_str(super::ENCODINGS);
|
|
completion.push_str("'");
|
|
}
|
|
CompletionType::Other if !flag.doc_choices().is_empty() => {
|
|
completion.push_str(" -r -f -a '");
|
|
completion.push_str(&flag.doc_choices().join(" "));
|
|
completion.push_str("'");
|
|
}
|
|
CompletionType::Other if !flag.is_switch() => {
|
|
completion.push_str(" -r -f");
|
|
}
|
|
CompletionType::Other => (),
|
|
}
|
|
|
|
completion.push('\n');
|
|
out.push_str(&completion);
|
|
|
|
if let Some(negated) = flag.name_negated() {
|
|
let short = match flag.name_short() {
|
|
None => "".to_string(),
|
|
Some(byte) => char::from(byte).to_string(),
|
|
};
|
|
out.push_str(
|
|
&TEMPLATE_NEGATED
|
|
.replace("!NEGATED!", &negated)
|
|
.replace("!SHORT!", &short)
|
|
.replace("!LONG!", &long)
|
|
.replace("!DOC!", &doc),
|
|
);
|
|
}
|
|
}
|
|
out
|
|
}
|