From 81d92682ce02bbce059317bf6d143ca7dd00d5c5 Mon Sep 17 00:00:00 2001 From: Vivien Maisonneuve Date: Sun, 13 Oct 2024 21:04:52 +0200 Subject: [PATCH] chore(complete): Add descriptions to dynamic Zsh completions --- clap_complete/src/env/shells.rs | 27 ++++++++++++++++-- .../exhaustive/zsh/zsh/_exhaustive | 2 +- clap_complete/tests/testsuite/zsh.rs | 28 +++++++++++++++---- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/clap_complete/src/env/shells.rs b/clap_complete/src/env/shells.rs index 7296647567c..5600927d9c9 100644 --- a/clap_complete/src/env/shells.rs +++ b/clap_complete/src/env/shells.rs @@ -361,7 +361,7 @@ function _clap_dynamic_completer_NAME() { )}") if [[ -n $completions ]]; then - compadd -a completions + _describe 'values' completions fi } @@ -398,8 +398,31 @@ compdef _clap_dynamic_completer_NAME BIN"# if i != 0 { write!(buf, "{}", ifs.as_deref().unwrap_or("\n"))?; } - write!(buf, "{}", candidate.get_value().to_string_lossy())?; + write!( + buf, + "{}", + Self::escape_value(&candidate.get_value().to_string_lossy()) + )?; + if let Some(help) = candidate.get_help() { + write!( + buf, + ":{}", + Self::escape_help(help.to_string().lines().next().unwrap_or_default()) + )?; + } } Ok(()) } } + +impl Zsh { + /// Escape value string + fn escape_value(string: &str) -> String { + string.replace('\\', "\\\\").replace(':', "\\:") + } + + /// Escape help string + fn escape_help(string: &str) -> String { + string.replace('\\', "\\\\") + } +} diff --git a/clap_complete/tests/snapshots/home/dynamic-env/exhaustive/zsh/zsh/_exhaustive b/clap_complete/tests/snapshots/home/dynamic-env/exhaustive/zsh/zsh/_exhaustive index e59950fc841..34af9fbe1e2 100644 --- a/clap_complete/tests/snapshots/home/dynamic-env/exhaustive/zsh/zsh/_exhaustive +++ b/clap_complete/tests/snapshots/home/dynamic-env/exhaustive/zsh/zsh/_exhaustive @@ -11,7 +11,7 @@ function _clap_dynamic_completer_exhaustive() { )}") if [[ -n $completions ]]; then - compadd -a completions + _describe 'values' completions fi } diff --git a/clap_complete/tests/testsuite/zsh.rs b/clap_complete/tests/testsuite/zsh.rs index 575d4fbb061..757c33f171b 100644 --- a/clap_complete/tests/testsuite/zsh.rs +++ b/clap_complete/tests/testsuite/zsh.rs @@ -192,8 +192,12 @@ fn complete_dynamic_env_toplevel() { let input = "exhaustive \t\t"; let expected = snapbox::str![[r#" % exhaustive ---generate --help action help last quote ---global --version alias hint pacman value +--generate -- generate +--global -- everywhere +--help -- Print help +--version -- Print version +help -- Print this message or the help of the given subcommand(s) +action alias hint last pacman quote value "#]]; let actual = runtime.complete(input, &term).unwrap(); assert_data_eq!(actual, expected); @@ -213,9 +217,18 @@ fn complete_dynamic_env_quoted_help() { let input = "exhaustive quote \t\t"; let expected = snapbox::str![[r#" % exhaustive quote ---backslash --choice --global --version cmd-brackets cmd-single-quotes ---backticks --double-quotes --help cmd-backslash cmd-double-quotes escape-help ---brackets --expansions --single-quotes cmd-backticks cmd-expansions help +--global -- everywhere +--help -- Print help (see more with '--help') +--version -- Print version +cmd-backslash --backslash -- Avoid '/n' +cmd-backticks --backticks -- For more information see `echo test` +cmd-brackets --brackets -- List packages [filter] +cmd-double-quotes --double-quotes -- Can be "always", "auto", or "never" +cmd-expansions --expansions -- Execute the shell command with $SHELL +cmd-single-quotes --single-quotes -- Can be 'always', 'auto', or 'never' +escape-help -- /tab/t"' +help -- Print this message or the help of the given subcommand(s) +--choice "#]]; let actual = runtime.complete(input, &term).unwrap(); assert_data_eq!(actual, expected); @@ -260,7 +273,10 @@ fn complete_dynamic_env_quoted_value() { let input = "exhaustive quote --choice \t\t"; let expected = snapbox::str![[r#" % exhaustive quote --choice -another/ shell bash fish zsh +another shell -- something with a space +bash -- bash (shell) +fish -- fish shell +zsh -- zsh shell "#]]; let actual = runtime.complete(input, &term).unwrap(); assert_data_eq!(actual, expected);