Skip to content
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

added keep order to bash, zsh, pwsh & fish #1903

Merged
merged 10 commits into from Feb 25, 2023
13 changes: 10 additions & 3 deletions bash_completions.go
Expand Up @@ -81,14 +81,15 @@ __%[1]s_handle_go_custom_completion()
local shellCompDirectiveNoFileComp=%[5]d
local shellCompDirectiveFilterFileExt=%[6]d
local shellCompDirectiveFilterDirs=%[7]d
local shellCompDirectiveKeepOrder=%[8]d

local out requestComp lastParam lastChar comp directive args

# Prepare the command to request completions for the program.
# Calling ${words[0]} instead of directly %[1]s allows to handle aliases
args=("${words[@]:1}")
# Disable ActiveHelp which is not supported for bash completion v1
requestComp="%[8]s=0 ${words[0]} %[2]s ${args[*]}"
requestComp="%[9]s=0 ${words[0]} %[2]s ${args[*]}"

lastParam=${words[$((${#words[@]}-1))]}
lastChar=${lastParam:$((${#lastParam}-1)):1}
Expand Down Expand Up @@ -127,6 +128,12 @@ __%[1]s_handle_go_custom_completion()
compopt -o nospace
fi
fi
if [ $((directive & shellCompDirectiveKeepOrder)) -ne 0 ]; then
if [[ $(type -t compopt) = "builtin" ]]; then
__%[1]s_debug "${FUNCNAME[0]}: activating keep order"
compopt -o nosort
fi
fi
if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then
if [[ $(type -t compopt) = "builtin" ]]; then
__%[1]s_debug "${FUNCNAME[0]}: activating no file completion"
Expand Down Expand Up @@ -398,7 +405,7 @@ __%[1]s_handle_word()

`, name, ShellCompNoDescRequestCmd,
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, activeHelpEnvVar(name)))
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder, activeHelpEnvVar(name)))
}

func writePostscript(buf io.StringWriter, name string) {
Expand Down Expand Up @@ -437,7 +444,7 @@ func writePostscript(buf io.StringWriter, name string) {
WriteStringAndCheck(buf, fmt.Sprintf(`if [[ $(type -t compopt) = "builtin" ]]; then
complete -o default -F __start_%s %s
else
complete -o default -o nospace -F __start_%s %s
complete -F __start_%s %s
h4ck3rk3y marked this conversation as resolved.
Show resolved Hide resolved
fi

`, name, name, name, name))
Expand Down
15 changes: 12 additions & 3 deletions bash_completionsV2.go
Expand Up @@ -101,6 +101,7 @@ __%[1]s_process_completion_results() {
local shellCompDirectiveNoFileComp=%[5]d
local shellCompDirectiveFilterFileExt=%[6]d
local shellCompDirectiveFilterDirs=%[7]d
local shellCompDirectiveKeepOrder=%[8]d

if (((directive & shellCompDirectiveError) != 0)); then
# Error code. No completion.
Expand All @@ -115,6 +116,14 @@ __%[1]s_process_completion_results() {
__%[1]s_debug "No space directive not supported in this version of bash"
fi
fi
if (((directive & shellCompDirectiveKeepOrder) != 0)); then
if [[ $(type -t compopt) == builtin ]]; then
__%[1]s_debug "Activating keep order"
compopt -o nosort
h4ck3rk3y marked this conversation as resolved.
Show resolved Hide resolved
else
__%[1]s_debug "No sort directive not supported in this version of bash"
fi
fi
if (((directive & shellCompDirectiveNoFileComp) != 0)); then
if [[ $(type -t compopt) == builtin ]]; then
__%[1]s_debug "Activating no file completion"
Expand Down Expand Up @@ -183,7 +192,7 @@ __%[1]s_process_completion_results() {
# Separate activeHelp lines from real completions.
# Fills the $activeHelp and $completions arrays.
__%[1]s_extract_activeHelp() {
local activeHelpMarker="%[8]s"
local activeHelpMarker="%[9]s"
local endIndex=${#activeHelpMarker}

while IFS='' read -r comp; do
Expand Down Expand Up @@ -354,13 +363,13 @@ __start_%[1]s()
if [[ $(type -t compopt) = "builtin" ]]; then
complete -o default -F __start_%[1]s %[1]s
else
complete -o default -o nospace -F __start_%[1]s %[1]s
complete -F __start_%[1]s %[1]s
h4ck3rk3y marked this conversation as resolved.
Show resolved Hide resolved
fi

# ex: ts=4 sw=4 et filetype=sh
`, name, compCmd,
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs,
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder,
activeHelpMarker))
}

Expand Down
7 changes: 7 additions & 0 deletions completions.go
Expand Up @@ -77,6 +77,10 @@ const (
// obtain the same behavior but only for flags.
ShellCompDirectiveFilterDirs

// ShellCompDirectiveKeepOrder indicates that the shell should preserve the order
// in which the completions are provided
ShellCompDirectiveKeepOrder

// ===========================================================================

// All directives using iota should be above this one.
Expand Down Expand Up @@ -159,6 +163,9 @@ func (d ShellCompDirective) string() string {
if d&ShellCompDirectiveFilterDirs != 0 {
directives = append(directives, "ShellCompDirectiveFilterDirs")
}
if d&ShellCompDirectiveKeepOrder != 0 {
directives = append(directives, "ShellCompDirectiveKeepOrder")
}
if len(directives) == 0 {
directives = append(directives, "ShellCompDirectiveDefault")
}
Expand Down
30 changes: 26 additions & 4 deletions fish_completions.go
Expand Up @@ -53,7 +53,7 @@ function __%[1]s_perform_completion
__%[1]s_debug "last arg: $lastArg"

# Disable ActiveHelp which is not supported for fish shell
set -l requestComp "%[9]s=0 $args[1] %[3]s $args[2..-1] $lastArg"
set -l requestComp "%[10]s=0 $args[1] %[3]s $args[2..-1] $lastArg"

__%[1]s_debug "Calling $requestComp"
set -l results (eval $requestComp 2> /dev/null)
Expand Down Expand Up @@ -89,6 +89,25 @@ function __%[1]s_perform_completion
printf "%%s\n" "$directiveLine"
end

function __%[1]s_doesnt_requires_order_preservation
h4ck3rk3y marked this conversation as resolved.
Show resolved Hide resolved
__%[1]s_debug ""
__%[1]s_debug "========= checking if order preservation is required =========="

set -l results (__%[1]s_perform_completion)
h4ck3rk3y marked this conversation as resolved.
Show resolved Hide resolved
if test -z "$results"
__%[1]s_debug "Error determining if order preservation is required"
return 1
end

set -l keeporder (math (math --scale 0 $directive / $shellCompDirectiveKeepOrder) %% 2)

if test "$keeporder" -ne 0
__%[1]s_debug "This does require order preservation"
return 1
end
end


# This function does two things:
# - Obtain the completions and store them in the global __%[1]s_comp_results
# - Return false if file completion should be performed
Expand Down Expand Up @@ -119,6 +138,7 @@ function __%[1]s_prepare_completions
set -l shellCompDirectiveNoFileComp %[6]d
set -l shellCompDirectiveFilterFileExt %[7]d
set -l shellCompDirectiveFilterDirs %[8]d
set -l shellCompDirectiveKeepOrder %[9]d

if test -z "$directive"
set directive 0
Expand Down Expand Up @@ -207,11 +227,13 @@ complete -c %[2]s -e

# The call to __%[1]s_prepare_completions will setup __%[1]s_comp_results
# which provides the program's completion choices.
complete -c %[2]s -n '__%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results'

# if this doesn't require order preservation, we dont use the -k flag
h4ck3rk3y marked this conversation as resolved.
Show resolved Hide resolved
complete -c %[2]s -n '__%[1]s_doesnt_requires_order_preservation' -n '__%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results'
h4ck3rk3y marked this conversation as resolved.
Show resolved Hide resolved
# otherwise we use the -k flag
complete -k -c %[2]s -n '__%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results'
`, nameForVar, name, compCmd,
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, activeHelpEnvVar(name)))
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder, activeHelpEnvVar(name)))
}

// GenFishCompletion generates fish completion file and writes to the passed writer.
Expand Down
10 changes: 8 additions & 2 deletions powershell_completions.go
Expand Up @@ -77,6 +77,7 @@ filter __%[1]s_escapeStringWithSpecialChars {
$ShellCompDirectiveNoFileComp=%[6]d
$ShellCompDirectiveFilterFileExt=%[7]d
$ShellCompDirectiveFilterDirs=%[8]d
$ShellCompDirectiveKeepOrder=%[9]d

# Prepare the command to request completions for the program.
# Split the command at the first space to separate the program and arguments.
Expand Down Expand Up @@ -112,7 +113,7 @@ filter __%[1]s_escapeStringWithSpecialChars {

__%[1]s_debug "Calling $RequestComp"
# First disable ActiveHelp which is not supported for Powershell
$env:%[9]s=0
$env:%[10]s=0

#call the command store the output in $out and redirect stderr and stdout to null
# $Out is an array contains each line per element
Expand Down Expand Up @@ -182,6 +183,11 @@ filter __%[1]s_escapeStringWithSpecialChars {
}
}

# we sort the values in ascending order by name if keep order isn't passed
if (($Directive -band $ShellCompDirectiveKeepOrder) -eq 0 ) {
$Values = $Values | Sort-Object -Property Name
}
marckhouzam marked this conversation as resolved.
Show resolved Hide resolved

if (($Directive -band $ShellCompDirectiveNoFileComp) -ne 0 ) {
__%[1]s_debug "ShellCompDirectiveNoFileComp is called"

Expand Down Expand Up @@ -267,7 +273,7 @@ filter __%[1]s_escapeStringWithSpecialChars {
Register-ArgumentCompleter -CommandName '%[1]s' -ScriptBlock $__%[2]sCompleterBlock
`, name, nameForVar, compCmd,
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, activeHelpEnvVar(name)))
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder, activeHelpEnvVar(name)))
}

func (c *Command) genPowerShellCompletion(w io.Writer, includeDesc bool) error {
Expand Down
4 changes: 4 additions & 0 deletions shell_completions.md
Expand Up @@ -237,6 +237,10 @@ ShellCompDirectiveFilterFileExt
// return []string{"themes"}, ShellCompDirectiveFilterDirs
//
ShellCompDirectiveFilterDirs

// ShellCompDirectiveKeepOrder indicates that the shell should preserve the order
// in which the completions are provided
ShellCompDirectiveKeepOrder
```

***Note***: When using the `ValidArgsFunction`, Cobra will call your registered function after having parsed all flags and arguments provided in the command-line. You therefore don't need to do this parsing yourself. For example, when a user calls `helm status --namespace my-rook-ns [tab][tab]`, Cobra will call your registered `ValidArgsFunction` after having parsed the `--namespace` flag, as it would have done when calling the `RunE` function.
Expand Down
14 changes: 10 additions & 4 deletions zsh_completions.go
Expand Up @@ -108,8 +108,9 @@ _%[1]s()
local shellCompDirectiveNoFileComp=%[5]d
local shellCompDirectiveFilterFileExt=%[6]d
local shellCompDirectiveFilterDirs=%[7]d
local shellCompDirectiveKeepOrder=%[8]d

local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace
local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace keepOrder
local -a completions

__%[1]s_debug "\n========= starting completion logic =========="
Expand Down Expand Up @@ -177,7 +178,7 @@ _%[1]s()
return
fi

local activeHelpMarker="%[8]s"
local activeHelpMarker="%[9]s"
local endIndex=${#activeHelpMarker}
local startIndex=$((${#activeHelpMarker}+1))
local hasActiveHelp=0
Expand Down Expand Up @@ -227,6 +228,11 @@ _%[1]s()
noSpace="-S ''"
fi

if [ $((directive & shellCompDirectiveKeepOrder)) -ne 0 ]; then
__%[1]s_debug "Activating keep order."
keepOrder="-V"
fi

if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then
# File extension filtering
local filteringCmd
Expand Down Expand Up @@ -262,7 +268,7 @@ _%[1]s()
return $result
else
__%[1]s_debug "Calling _describe"
if eval _describe "completions" completions $flagPrefix $noSpace; then
if eval _describe $keepOrder "completions" completions $flagPrefix $noSpace; then
__%[1]s_debug "_describe found some completions"

# Return the success of having called _describe
Expand Down Expand Up @@ -296,6 +302,6 @@ if [ "$funcstack[1]" = "_%[1]s" ]; then
fi
`, name, compCmd,
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs,
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder,
activeHelpMarker))
}