-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat(complete): group options by tag (in zsh)
#6334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -431,25 +431,61 @@ function _clap_dynamic_completer_NAME() { | |
| )}") | ||
|
|
||
| if [[ -n $completions ]]; then | ||
| local -a dirs=() | ||
| local -a other=() | ||
| local -A tag_map tag_map_dirs | ||
| local completion | ||
| local tag | ||
| local value | ||
| local to_add | ||
|
|
||
| for completion in $completions; do | ||
| local value="${completion%%:*}" | ||
| IFS=: read -r tag value <<< "$completion" | ||
|
|
||
| if [[ "$value" == */ ]]; then | ||
| local dir_no_slash="${value%/}" | ||
| if [[ "$completion" == *:* ]]; then | ||
| local desc="${completion#*:}" | ||
| dirs+=("$dir_no_slash:$desc") | ||
|
|
||
| if [[ "$value" == *:* ]]; then | ||
| local desc="${value#*:}" | ||
| to_add="$dir_no_slash:$desc" | ||
| else | ||
| dirs+=("$dir_no_slash") | ||
| to_add="$dir_no_slash" | ||
| fi | ||
|
|
||
| tag_map_dirs[$tag]+=${tag_map_dirs[$tag]:+$'\n'}"$to_add" | ||
| else | ||
| other+=("$completion") | ||
| tag_map[$tag]+=${tag_map[$tag]:+$'\n'}"$value" | ||
| fi | ||
|
Comment on lines
443
to
+456
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this mean we aren't getting the
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The opposite in fact - if a
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Items with
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you, I see what it's for now - fix in place |
||
| done | ||
| [[ -n $dirs ]] && _describe -V 'values' dirs -S '/' -r '/' | ||
| [[ -n $other ]] && _describe -V 'values' other | ||
|
|
||
| local -A tags | ||
| for k in ${(k)tag_map} ${(k)tag_map_dirs}; do | ||
| tags[$k]=1 | ||
| done | ||
|
|
||
| local extglob=${options[extendedglob]} | ||
| setopt extendedglob | ||
| for tag in ${(Ok)tags}; do | ||
| # _describe -t tag cannot begin with a `-` | ||
| local desc_tag=${tag##-##} | ||
| local values=("${(@f)tag_map[$tag]}") # split on newline | ||
|
|
||
| if (( $#values )); then | ||
| if [[ -n "$desc_tag" ]]; then | ||
| _describe -V -t "$desc_tag" "$desc_tag" values | ||
| else | ||
| _describe -V 'options' values | ||
| fi | ||
| fi | ||
|
|
||
| values=("${(@f)tag_map_dirs[$tag]}") | ||
| if (( $#values )); then | ||
| if [[ -n "$desc_tag" ]]; then | ||
| _describe -V -t "${desc_tag}-dirs" "$desc_tag" values -S '/' -r '/' | ||
| else | ||
| _describe -V 'options' values -S '/' -r '/' | ||
| fi | ||
| fi | ||
| done | ||
| [[ $extglob == on ]] || unsetopt extendedglob | ||
| fi | ||
| } | ||
|
|
||
|
|
@@ -486,6 +522,14 @@ compdef _clap_dynamic_completer_NAME BIN"# | |
| if i != 0 { | ||
| write!(buf, "{}", ifs.as_deref().unwrap_or("\n"))?; | ||
| } | ||
|
|
||
| let tag = candidate | ||
| .get_tag() | ||
| .map(|t| t.to_string()) | ||
| .unwrap_or_default(); | ||
|
|
||
| write!(buf, "{}:", Self::escape_value(&tag))?; | ||
|
|
||
| write!( | ||
| buf, | ||
| "{}", | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -251,11 +251,11 @@ fn complete_dynamic_env_toplevel() { | |||||||||||||||||||||||||
| let input = "exhaustive \t\t"; | ||||||||||||||||||||||||||
| let expected = snapbox::str![[r#" | ||||||||||||||||||||||||||
| % exhaustive | ||||||||||||||||||||||||||
| help -- Print this message or the help of the given subcommand(s) | ||||||||||||||||||||||||||
| --generate -- generate | ||||||||||||||||||||||||||
| --help -- Print help | ||||||||||||||||||||||||||
| empty action value last hint | ||||||||||||||||||||||||||
| global quote pacman alias --empty-choice | ||||||||||||||||||||||||||
| help -- Print this message or the help of the given subcommand(s) | ||||||||||||||||||||||||||
| --empty-choice empty action value last hint | ||||||||||||||||||||||||||
| global quote pacman alias | ||||||||||||||||||||||||||
| "#]]; | ||||||||||||||||||||||||||
| let actual = runtime.complete(input, &term).unwrap(); | ||||||||||||||||||||||||||
| assert_data_eq!(actual, expected); | ||||||||||||||||||||||||||
|
|
@@ -275,16 +275,22 @@ fn complete_dynamic_env_quoted_help() { | |||||||||||||||||||||||||
| let input = "exhaustive quote \t\t"; | ||||||||||||||||||||||||||
| let expected = snapbox::str![[r#" | ||||||||||||||||||||||||||
| % exhaustive quote | ||||||||||||||||||||||||||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this test, the Perhaps we ensure their tags are the same to continue to group them? (if I'm right about the tagging - out of time but I can check later)
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes - it's the tags. Options get tagged as clap/clap_complete/src/engine/complete.rs Lines 548 to 553 in c8c9355
and commands similarly: clap/clap_complete/src/engine/complete.rs Lines 597 to 602 in c8c9355
To keep the ordering in the tests the same, we could tag commands as options (for the test only): .help("enum"),
]),
clap::Command::new("quote")
+ .subcommand_help_heading("Options") // group subcommands with options
.args([
clap::Arg::new("single-quotes")
.long("single-quotes")(in or we could remove the default tag entirely, which is a larger change which would affect not just the tests |
||||||||||||||||||||||||||
| --help -- Print help (see more with '--help') | ||||||||||||||||||||||||||
| 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 | ||||||||||||||||||||||||||
| --single-quotes -- Can be 'always', 'auto', or 'never' | ||||||||||||||||||||||||||
| --double-quotes -- Can be "always", "auto", or "never" | ||||||||||||||||||||||||||
| --backticks -- For more information see `echo test` | ||||||||||||||||||||||||||
| --backslash -- Avoid '/n' | ||||||||||||||||||||||||||
| --brackets -- List packages [filter] | ||||||||||||||||||||||||||
| --expansions -- Execute the shell command with $SHELL | ||||||||||||||||||||||||||
| --help -- Print help (see more with '--help') | ||||||||||||||||||||||||||
| cmd-single-quotes -- Can be 'always', 'auto', or 'never' | ||||||||||||||||||||||||||
| cmd-double-quotes -- Can be "always", "auto", or "never" | ||||||||||||||||||||||||||
| cmd-backticks -- For more information see `echo test` | ||||||||||||||||||||||||||
| cmd-backslash -- Avoid '/n' | ||||||||||||||||||||||||||
| cmd-brackets -- List packages [filter] | ||||||||||||||||||||||||||
| cmd-expansions -- Execute the shell command with $SHELL | ||||||||||||||||||||||||||
| escape-help -- /tab "' | ||||||||||||||||||||||||||
| 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); | ||||||||||||||||||||||||||
|
|
@@ -392,16 +398,22 @@ fn complete_dynamic_empty_space() { | |||||||||||||||||||||||||
| let input = "exhaustive quote -\x1b[D\x1b[D\t\t"; | ||||||||||||||||||||||||||
| let expected = snapbox::str![[r#" | ||||||||||||||||||||||||||
| % exhaustive quote - | ||||||||||||||||||||||||||
| --help -- Print help (see more with '--help') | ||||||||||||||||||||||||||
| 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 | ||||||||||||||||||||||||||
| --single-quotes -- Can be 'always', 'auto', or 'never' | ||||||||||||||||||||||||||
| --double-quotes -- Can be "always", "auto", or "never" | ||||||||||||||||||||||||||
| --backticks -- For more information see `echo test` | ||||||||||||||||||||||||||
| --backslash -- Avoid '/n' | ||||||||||||||||||||||||||
| --brackets -- List packages [filter] | ||||||||||||||||||||||||||
| --expansions -- Execute the shell command with $SHELL | ||||||||||||||||||||||||||
| --help -- Print help (see more with '--help') | ||||||||||||||||||||||||||
| cmd-single-quotes -- Can be 'always', 'auto', or 'never' | ||||||||||||||||||||||||||
| cmd-double-quotes -- Can be "always", "auto", or "never" | ||||||||||||||||||||||||||
| cmd-backticks -- For more information see `echo test` | ||||||||||||||||||||||||||
| cmd-backslash -- Avoid '/n' | ||||||||||||||||||||||||||
| cmd-brackets -- List packages [filter] | ||||||||||||||||||||||||||
| cmd-expansions -- Execute the shell command with $SHELL | ||||||||||||||||||||||||||
| escape-help -- /tab "' | ||||||||||||||||||||||||||
| 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); | ||||||||||||||||||||||||||
|
|
@@ -430,8 +442,37 @@ fn complete_dynamic_dir_no_trailing_space() { | |||||||||||||||||||||||||
| let input = "exhaustive hint --file tests/\t\t"; | ||||||||||||||||||||||||||
| let expected = snapbox::str![[r#" | ||||||||||||||||||||||||||
| % exhaustive hint --file tests/ | ||||||||||||||||||||||||||
| tests/snapshots tests/testsuite tests/examples.rs | ||||||||||||||||||||||||||
| tests/examples.rs tests/snapshots tests/testsuite | ||||||||||||||||||||||||||
| "#]]; | ||||||||||||||||||||||||||
| let actual = runtime.complete(input, &term).unwrap(); | ||||||||||||||||||||||||||
| assert_data_eq!(actual, expected); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||
| #[cfg(all(unix, feature = "unstable-dynamic"))] | ||||||||||||||||||||||||||
| #[cfg(feature = "unstable-shell-tests")] | ||||||||||||||||||||||||||
| fn complete_dynamic_tagged_options() { | ||||||||||||||||||||||||||
| if !common::has_command(CMD) { | ||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| let term = completest::Term::new(); | ||||||||||||||||||||||||||
| let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive"); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| let input = [ | ||||||||||||||||||||||||||
| "zstyle ':completion:*:descriptions' format '%d'", | ||||||||||||||||||||||||||
| "exhaustive -\t\t", | ||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||
| .join("\n"); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| let expected = snapbox::str![[r#" | ||||||||||||||||||||||||||
| % zstyle ':completion:*:descriptions' format '%d' | ||||||||||||||||||||||||||
| % exhaustive - | ||||||||||||||||||||||||||
| Options | ||||||||||||||||||||||||||
| --generate -- generate | ||||||||||||||||||||||||||
| -h -- Print help | ||||||||||||||||||||||||||
| --empty-choice | ||||||||||||||||||||||||||
| "#]]; | ||||||||||||||||||||||||||
| let actual = runtime.complete(&input, &term).unwrap(); | ||||||||||||||||||||||||||
| assert_data_eq!(actual, expected); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.