From 78803979c5e750d7e552ba52d7c6dff498df4ae5 Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Tue, 9 Jan 2024 22:16:02 +0100 Subject: [PATCH] complete/fish: Take RIPGREP_CONFIG_PATH into account 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 --- CHANGELOG.md | 5 ++++ crates/core/flags/complete/fish.rs | 10 +++++++- crates/core/flags/complete/prelude.fish | 31 +++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 crates/core/flags/complete/prelude.fish diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cc576ec..b0c9223e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ TBD === Unreleased changes. Release notes have not yet been written. +Feature enhancements: + +* [FEATURE #2708](https://github.com/BurntSushi/ripgrep/pull/2708): + Completions for the fish shell take ripgrep's config file into account. + 14.1.1 (2024-09-08) =================== diff --git a/crates/core/flags/complete/fish.rs b/crates/core/flags/complete/fish.rs index f8f7133b..8952cdd3 100644 --- a/crates/core/flags/complete/fish.rs +++ b/crates/core/flags/complete/fish.rs @@ -6,11 +6,15 @@ 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 '__fish_contains_opt !SHORT! !LONG!' -d '!DOC!'\n"; + "complete -c rg -l !NEGATED! -n '__rg_contains_opt !LONG! !SHORT!' -d '!DOC!'\n"; /// Generate completions for Fish. +/// +/// Reference: 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(), @@ -55,6 +59,10 @@ pub(crate) fn generate() -> String { 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) diff --git a/crates/core/flags/complete/prelude.fish b/crates/core/flags/complete/prelude.fish new file mode 100644 index 00000000..6932f3e8 --- /dev/null +++ b/crates/core/flags/complete/prelude.fish @@ -0,0 +1,31 @@ +# Usage: __rg_contains_opt LONG [SHORT] +function __rg_contains_opt --description 'Specialized __fish_contains_opt' + # Cache the config file because this function is called many times per + # completion attempt. + # The cache will persist for the entire shell session (even if the + # variable or the file contents change). + if not set -q __rg_config + set -g __rg_config + if set -qx RIPGREP_CONFIG_PATH + set __rg_config ( + cat -- $RIPGREP_CONFIG_PATH 2>/dev/null \ + | string trim \ + | string match -rv '^$|^#' + ) + end + end + + set -l commandline (commandline -cpo) (commandline -ct) $__rg_config + + if contains -- "--$argv[1]" $commandline + return 0 + end + + if set -q argv[2] + if string match -qr -- "^-[^-]*$argv[2]" $commandline + return 0 + end + end + + return 1 +end