From d9b8f46beeae17779ee7533e10c8541495279986 Mon Sep 17 00:00:00 2001 From: wuyangfan Date: Tue, 26 May 2026 21:36:27 +0800 Subject: [PATCH] fix: complete executables in fish for benchmark commands Add fish completion for positional benchmark commands using __fish_complete_command, and mark --reference with CommandString so its value completes executables as well. Fixes #872 Co-authored-by: Cursor --- build.rs | 28 ++++++++++++++++++++++++++++ src/cli.rs | 1 + 2 files changed, 29 insertions(+) diff --git a/build.rs b/build.rs index 0c3fe354d..c3dade366 100644 --- a/build.rs +++ b/build.rs @@ -1,9 +1,23 @@ use std::fs; +use std::path::{Path, PathBuf}; use clap_complete::{generate_to, Shell}; include!("src/cli.rs"); +const FISH_COMMAND_COMPLETION: &str = "\ +# Complete executables from $PATH for benchmark command arguments (see #872) +complete -c hyperfine -n \"__fish_use_subcommand\" -x -a \"(__fish_complete_command)\" +"; + +fn patch_fish_completions(path: &Path) { + let mut content = fs::read_to_string(path).expect("read fish completions"); + if !content.contains("__fish_use_subcommand") { + content.push_str(FISH_COMMAND_COMPLETION); + fs::write(path, content).expect("write fish completions"); + } +} + fn main() { let var = std::env::var_os("SHELL_COMPLETIONS_DIR").or_else(|| std::env::var_os("OUT_DIR")); let outdir = match var { @@ -21,5 +35,19 @@ fn main() { Shell::Elvish, ] { generate_to(shell, &mut command, "hyperfine", &outdir).unwrap(); + if shell == Shell::Fish { + patch_fish_completions(&PathBuf::from(&outdir).join("hyperfine.fish")); + } + } +} + +#[cfg(test)] +mod tests { + use super::FISH_COMMAND_COMPLETION; + + #[test] + fn fish_command_completion_snippet_uses_path_executable_helper() { + assert!(FISH_COMMAND_COMPLETION.contains("__fish_use_subcommand")); + assert!(FISH_COMMAND_COMPLETION.contains("__fish_complete_command")); } } diff --git a/src/cli.rs b/src/cli.rs index b12f6d34c..d2069d837 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -91,6 +91,7 @@ fn build_command() -> Command { .long("reference") .action(ArgAction::Set) .value_name("CMD") + .value_hint(ValueHint::CommandString) .help( "The reference command for the relative comparison of results. \ If this is unset, results are compared with the fastest command as reference."