Исправления в ветке main

This commit is contained in:
2026-10-22 12:42:32 +06:00
parent 933e5ccb58
commit 9b05edc263
31 changed files with 2433 additions and 114 deletions

View File

@@ -0,0 +1,426 @@
# bash completion V2 for goreleaser -*- shell-script -*-
__goreleaser_debug()
{
if [[ -n ${BASH_COMP_DEBUG_FILE-} ]]; then
echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
fi
}
# Macs have bash3 for which the bash-completion package doesn't include
# _init_completion. This is a minimal version of that function.
__goreleaser_init_completion()
{
COMPREPLY=()
_get_comp_words_by_ref "$@" cur prev words cword
}
# This function calls the goreleaser program to obtain the completion
# results and the directive. It fills the 'out' and 'directive' vars.
__goreleaser_get_completion_results() {
local requestComp lastParam lastChar args
# Prepare the command to request completions for the program.
# Calling ${words[0]} instead of directly goreleaser allows handling aliases
args=("${words[@]:1}")
requestComp="${words[0]} __complete ${args[*]}"
lastParam=${words[$((${#words[@]}-1))]}
lastChar=${lastParam:$((${#lastParam}-1)):1}
__goreleaser_debug "lastParam ${lastParam}, lastChar ${lastChar}"
if [[ -z ${cur} && ${lastChar} != = ]]; then
# If the last parameter is complete (there is a space following it)
# We add an extra empty parameter so we can indicate this to the go method.
__goreleaser_debug "Adding extra empty parameter"
requestComp="${requestComp} ''"
fi
# When completing a flag with an = (e.g., goreleaser -n=<TAB>)
# bash focuses on the part after the =, so we need to remove
# the flag part from $cur
if [[ ${cur} == -*=* ]]; then
cur="${cur#*=}"
fi
__goreleaser_debug "Calling ${requestComp}"
# Use eval to handle any environment variables and such
out=$(eval "${requestComp}" 2>/dev/null)
# Extract the directive integer at the very end of the output following a colon (:)
directive=${out##*:}
# Remove the directive
out=${out%:*}
if [[ ${directive} == "${out}" ]]; then
# There is not directive specified
directive=0
fi
__goreleaser_debug "The completion directive is: ${directive}"
__goreleaser_debug "The completions are: ${out}"
}
__goreleaser_process_completion_results() {
local shellCompDirectiveError=1
local shellCompDirectiveNoSpace=2
local shellCompDirectiveNoFileComp=4
local shellCompDirectiveFilterFileExt=8
local shellCompDirectiveFilterDirs=16
local shellCompDirectiveKeepOrder=32
if (((directive & shellCompDirectiveError) != 0)); then
# Error code. No completion.
__goreleaser_debug "Received error from custom completion go code"
return
else
if (((directive & shellCompDirectiveNoSpace) != 0)); then
if [[ $(type -t compopt) == builtin ]]; then
__goreleaser_debug "Activating no space"
compopt -o nospace
else
__goreleaser_debug "No space directive not supported in this version of bash"
fi
fi
if (((directive & shellCompDirectiveKeepOrder) != 0)); then
if [[ $(type -t compopt) == builtin ]]; then
# no sort isn't supported for bash less than < 4.4
if [[ ${BASH_VERSINFO[0]} -lt 4 || ( ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 4 ) ]]; then
__goreleaser_debug "No sort directive not supported in this version of bash"
else
__goreleaser_debug "Activating keep order"
compopt -o nosort
fi
else
__goreleaser_debug "No sort directive not supported in this version of bash"
fi
fi
if (((directive & shellCompDirectiveNoFileComp) != 0)); then
if [[ $(type -t compopt) == builtin ]]; then
__goreleaser_debug "Activating no file completion"
compopt +o default
else
__goreleaser_debug "No file completion directive not supported in this version of bash"
fi
fi
fi
# Separate activeHelp from normal completions
local completions=()
local activeHelp=()
__goreleaser_extract_activeHelp
if (((directive & shellCompDirectiveFilterFileExt) != 0)); then
# File extension filtering
local fullFilter="" filter filteringCmd
# Do not use quotes around the $completions variable or else newline
# characters will be kept.
for filter in ${completions[*]}; do
fullFilter+="$filter|"
done
filteringCmd="_filedir $fullFilter"
__goreleaser_debug "File filtering command: $filteringCmd"
$filteringCmd
elif (((directive & shellCompDirectiveFilterDirs) != 0)); then
# File completion for directories only
local subdir
subdir=${completions[0]}
if [[ -n $subdir ]]; then
__goreleaser_debug "Listing directories in $subdir"
pushd "$subdir" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 || return
else
__goreleaser_debug "Listing directories in ."
_filedir -d
fi
else
__goreleaser_handle_completion_types
fi
__goreleaser_handle_special_char "$cur" :
__goreleaser_handle_special_char "$cur" =
# Print the activeHelp statements before we finish
__goreleaser_handle_activeHelp
}
__goreleaser_handle_activeHelp() {
# Print the activeHelp statements
if ((${#activeHelp[*]} != 0)); then
if [ -z $COMP_TYPE ]; then
# Bash v3 does not set the COMP_TYPE variable.
printf "\n";
printf "%s\n" "${activeHelp[@]}"
printf "\n"
__goreleaser_reprint_commandLine
return
fi
# Only print ActiveHelp on the second TAB press
if [ $COMP_TYPE -eq 63 ]; then
printf "\n"
printf "%s\n" "${activeHelp[@]}"
if ((${#COMPREPLY[*]} == 0)); then
# When there are no completion choices from the program, file completion
# may kick in if the program has not disabled it; in such a case, we want
# to know if any files will match what the user typed, so that we know if
# there will be completions presented, so that we know how to handle ActiveHelp.
# To find out, we actually trigger the file completion ourselves;
# the call to _filedir will fill COMPREPLY if files match.
if (((directive & shellCompDirectiveNoFileComp) == 0)); then
__goreleaser_debug "Listing files"
_filedir
fi
fi
if ((${#COMPREPLY[*]} != 0)); then
# If there are completion choices to be shown, print a delimiter.
# Re-printing the command-line will automatically be done
# by the shell when it prints the completion choices.
printf -- "--"
else
# When there are no completion choices at all, we need
# to re-print the command-line since the shell will
# not be doing it itself.
__goreleaser_reprint_commandLine
fi
elif [ $COMP_TYPE -eq 37 ] || [ $COMP_TYPE -eq 42 ]; then
# For completion type: menu-complete/menu-complete-backward and insert-completions
# the completions are immediately inserted into the command-line, so we first
# print the activeHelp message and reprint the command-line since the shell won't.
printf "\n"
printf "%s\n" "${activeHelp[@]}"
__goreleaser_reprint_commandLine
fi
fi
}
__goreleaser_reprint_commandLine() {
# The prompt format is only available from bash 4.4.
# We test if it is available before using it.
if (x=${PS1@P}) 2> /dev/null; then
printf "%s" "${PS1@P}${COMP_LINE[@]}"
else
# Can't print the prompt. Just print the
# text the user had typed, it is workable enough.
printf "%s" "${COMP_LINE[@]}"
fi
}
# Separate activeHelp lines from real completions.
# Fills the $activeHelp and $completions arrays.
__goreleaser_extract_activeHelp() {
local activeHelpMarker="_activeHelp_ "
local endIndex=${#activeHelpMarker}
while IFS='' read -r comp; do
[[ -z $comp ]] && continue
if [[ ${comp:0:endIndex} == $activeHelpMarker ]]; then
comp=${comp:endIndex}
__goreleaser_debug "ActiveHelp found: $comp"
if [[ -n $comp ]]; then
activeHelp+=("$comp")
fi
else
# Not an activeHelp line but a normal completion
completions+=("$comp")
fi
done <<<"${out}"
}
__goreleaser_handle_completion_types() {
__goreleaser_debug "__goreleaser_handle_completion_types: COMP_TYPE is $COMP_TYPE"
case $COMP_TYPE in
37|42)
# Type: menu-complete/menu-complete-backward and insert-completions
# If the user requested inserting one completion at a time, or all
# completions at once on the command-line we must remove the descriptions.
# https://github.com/spf13/cobra/issues/1508
# If there are no completions, we don't need to do anything
(( ${#completions[@]} == 0 )) && return 0
local tab=$'\t'
# Strip any description and escape the completion to handled special characters
IFS=$'\n' read -ra completions -d '' < <(printf "%q\n" "${completions[@]%%$tab*}")
# Only consider the completions that match
IFS=$'\n' read -ra COMPREPLY -d '' < <(IFS=$'\n'; compgen -W "${completions[*]}" -- "${cur}")
# compgen looses the escaping so we need to escape all completions again since they will
# all be inserted on the command-line.
IFS=$'\n' read -ra COMPREPLY -d '' < <(printf "%q\n" "${COMPREPLY[@]}")
;;
*)
# Type: complete (normal completion)
__goreleaser_handle_standard_completion_case
;;
esac
}
__goreleaser_handle_standard_completion_case() {
local tab=$'\t'
# If there are no completions, we don't need to do anything
(( ${#completions[@]} == 0 )) && return 0
# Short circuit to optimize if we don't have descriptions
if [[ "${completions[*]}" != *$tab* ]]; then
# First, escape the completions to handle special characters
IFS=$'\n' read -ra completions -d '' < <(printf "%q\n" "${completions[@]}")
# Only consider the completions that match what the user typed
IFS=$'\n' read -ra COMPREPLY -d '' < <(IFS=$'\n'; compgen -W "${completions[*]}" -- "${cur}")
# compgen looses the escaping so, if there is only a single completion, we need to
# escape it again because it will be inserted on the command-line. If there are multiple
# completions, we don't want to escape them because they will be printed in a list
# and we don't want to show escape characters in that list.
if (( ${#COMPREPLY[@]} == 1 )); then
COMPREPLY[0]=$(printf "%q" "${COMPREPLY[0]}")
fi
return 0
fi
local longest=0
local compline
# Look for the longest completion so that we can format things nicely
while IFS='' read -r compline; do
[[ -z $compline ]] && continue
# Before checking if the completion matches what the user typed,
# we need to strip any description and escape the completion to handle special
# characters because those escape characters are part of what the user typed.
# Don't call "printf" in a sub-shell because it will be much slower
# since we are in a loop.
printf -v comp "%q" "${compline%%$tab*}" &>/dev/null || comp=$(printf "%q" "${compline%%$tab*}")
# Only consider the completions that match
[[ $comp == "$cur"* ]] || continue
# The completions matches. Add it to the list of full completions including
# its description. We don't escape the completion because it may get printed
# in a list if there are more than one and we don't want show escape characters
# in that list.
COMPREPLY+=("$compline")
# Strip any description before checking the length, and again, don't escape
# the completion because this length is only used when printing the completions
# in a list and we don't want show escape characters in that list.
comp=${compline%%$tab*}
if ((${#comp}>longest)); then
longest=${#comp}
fi
done < <(printf "%s\n" "${completions[@]}")
# If there is a single completion left, remove the description text and escape any special characters
if ((${#COMPREPLY[*]} == 1)); then
__goreleaser_debug "COMPREPLY[0]: ${COMPREPLY[0]}"
COMPREPLY[0]=$(printf "%q" "${COMPREPLY[0]%%$tab*}")
__goreleaser_debug "Removed description from single completion, which is now: ${COMPREPLY[0]}"
else
# Format the descriptions
__goreleaser_format_comp_descriptions $longest
fi
}
__goreleaser_handle_special_char()
{
local comp="$1"
local char=$2
if [[ "$comp" == *${char}* && "$COMP_WORDBREAKS" == *${char}* ]]; then
local word=${comp%"${comp##*${char}}"}
local idx=${#COMPREPLY[*]}
while ((--idx >= 0)); do
COMPREPLY[idx]=${COMPREPLY[idx]#"$word"}
done
fi
}
__goreleaser_format_comp_descriptions()
{
local tab=$'\t'
local comp desc maxdesclength
local longest=$1
local i ci
for ci in ${!COMPREPLY[*]}; do
comp=${COMPREPLY[ci]}
# Properly format the description string which follows a tab character if there is one
if [[ "$comp" == *$tab* ]]; then
__goreleaser_debug "Original comp: $comp"
desc=${comp#*$tab}
comp=${comp%%$tab*}
# $COLUMNS stores the current shell width.
# Remove an extra 4 because we add 2 spaces and 2 parentheses.
maxdesclength=$(( COLUMNS - longest - 4 ))
# Make sure we can fit a description of at least 8 characters
# if we are to align the descriptions.
if ((maxdesclength > 8)); then
# Add the proper number of spaces to align the descriptions
for ((i = ${#comp} ; i < longest ; i++)); do
comp+=" "
done
else
# Don't pad the descriptions so we can fit more text after the completion
maxdesclength=$(( COLUMNS - ${#comp} - 4 ))
fi
# If there is enough space for any description text,
# truncate the descriptions that are too long for the shell width
if ((maxdesclength > 0)); then
if ((${#desc} > maxdesclength)); then
desc=${desc:0:$(( maxdesclength - 1 ))}
desc+="…"
fi
comp+=" ($desc)"
fi
COMPREPLY[ci]=$comp
__goreleaser_debug "Final comp: $comp"
fi
done
}
__start_goreleaser()
{
local cur prev words cword split
COMPREPLY=()
# Call _init_completion from the bash-completion package
# to prepare the arguments properly
if declare -F _init_completion >/dev/null 2>&1; then
_init_completion -n =: || return
else
__goreleaser_init_completion -n =: || return
fi
__goreleaser_debug
__goreleaser_debug "========= starting completion logic =========="
__goreleaser_debug "cur is ${cur}, words[*] is ${words[*]}, #words[@] is ${#words[@]}, cword is $cword"
# The user could have moved the cursor backwards on the command-line.
# We need to trigger completion from the $cword location, so we need
# to truncate the command-line ($words) up to the $cword location.
words=("${words[@]:0:$cword+1}")
__goreleaser_debug "Truncated words[*]: ${words[*]},"
local out directive
__goreleaser_get_completion_results
__goreleaser_process_completion_results
}
if [[ $(type -t compopt) = "builtin" ]]; then
complete -o default -F __start_goreleaser goreleaser
else
complete -o default -o nospace -F __start_goreleaser goreleaser
fi
# ex: ts=4 sw=4 et filetype=sh

View File

@@ -0,0 +1,235 @@
# fish completion for goreleaser -*- shell-script -*-
function __goreleaser_debug
set -l file "$BASH_COMP_DEBUG_FILE"
if test -n "$file"
echo "$argv" >> $file
end
end
function __goreleaser_perform_completion
__goreleaser_debug "Starting __goreleaser_perform_completion"
# Extract all args except the last one
set -l args (commandline -opc)
# Extract the last arg and escape it in case it is a space
set -l lastArg (string escape -- (commandline -ct))
__goreleaser_debug "args: $args"
__goreleaser_debug "last arg: $lastArg"
# Disable ActiveHelp which is not supported for fish shell
set -l requestComp "GORELEASER_ACTIVE_HELP=0 $args[1] __complete $args[2..-1] $lastArg"
__goreleaser_debug "Calling $requestComp"
set -l results (eval $requestComp 2> /dev/null)
# Some programs may output extra empty lines after the directive.
# Let's ignore them or else it will break completion.
# Ref: https://github.com/spf13/cobra/issues/1279
for line in $results[-1..1]
if test (string trim -- $line) = ""
# Found an empty line, remove it
set results $results[1..-2]
else
# Found non-empty line, we have our proper output
break
end
end
set -l comps $results[1..-2]
set -l directiveLine $results[-1]
# For Fish, when completing a flag with an = (e.g., <program> -n=<TAB>)
# completions must be prefixed with the flag
set -l flagPrefix (string match -r -- '-.*=' "$lastArg")
__goreleaser_debug "Comps: $comps"
__goreleaser_debug "DirectiveLine: $directiveLine"
__goreleaser_debug "flagPrefix: $flagPrefix"
for comp in $comps
printf "%s%s\n" "$flagPrefix" "$comp"
end
printf "%s\n" "$directiveLine"
end
# this function limits calls to __goreleaser_perform_completion, by caching the result behind $__goreleaser_perform_completion_once_result
function __goreleaser_perform_completion_once
__goreleaser_debug "Starting __goreleaser_perform_completion_once"
if test -n "$__goreleaser_perform_completion_once_result"
__goreleaser_debug "Seems like a valid result already exists, skipping __goreleaser_perform_completion"
return 0
end
set --global __goreleaser_perform_completion_once_result (__goreleaser_perform_completion)
if test -z "$__goreleaser_perform_completion_once_result"
__goreleaser_debug "No completions, probably due to a failure"
return 1
end
__goreleaser_debug "Performed completions and set __goreleaser_perform_completion_once_result"
return 0
end
# this function is used to clear the $__goreleaser_perform_completion_once_result variable after completions are run
function __goreleaser_clear_perform_completion_once_result
__goreleaser_debug ""
__goreleaser_debug "========= clearing previously set __goreleaser_perform_completion_once_result variable =========="
set --erase __goreleaser_perform_completion_once_result
__goreleaser_debug "Successfully erased the variable __goreleaser_perform_completion_once_result"
end
function __goreleaser_requires_order_preservation
__goreleaser_debug ""
__goreleaser_debug "========= checking if order preservation is required =========="
__goreleaser_perform_completion_once
if test -z "$__goreleaser_perform_completion_once_result"
__goreleaser_debug "Error determining if order preservation is required"
return 1
end
set -l directive (string sub --start 2 $__goreleaser_perform_completion_once_result[-1])
__goreleaser_debug "Directive is: $directive"
set -l shellCompDirectiveKeepOrder 32
set -l keeporder (math (math --scale 0 $directive / $shellCompDirectiveKeepOrder) % 2)
__goreleaser_debug "Keeporder is: $keeporder"
if test $keeporder -ne 0
__goreleaser_debug "This does require order preservation"
return 0
end
__goreleaser_debug "This doesn't require order preservation"
return 1
end
# This function does two things:
# - Obtain the completions and store them in the global __goreleaser_comp_results
# - Return false if file completion should be performed
function __goreleaser_prepare_completions
__goreleaser_debug ""
__goreleaser_debug "========= starting completion logic =========="
# Start fresh
set --erase __goreleaser_comp_results
__goreleaser_perform_completion_once
__goreleaser_debug "Completion results: $__goreleaser_perform_completion_once_result"
if test -z "$__goreleaser_perform_completion_once_result"
__goreleaser_debug "No completion, probably due to a failure"
# Might as well do file completion, in case it helps
return 1
end
set -l directive (string sub --start 2 $__goreleaser_perform_completion_once_result[-1])
set --global __goreleaser_comp_results $__goreleaser_perform_completion_once_result[1..-2]
__goreleaser_debug "Completions are: $__goreleaser_comp_results"
__goreleaser_debug "Directive is: $directive"
set -l shellCompDirectiveError 1
set -l shellCompDirectiveNoSpace 2
set -l shellCompDirectiveNoFileComp 4
set -l shellCompDirectiveFilterFileExt 8
set -l shellCompDirectiveFilterDirs 16
if test -z "$directive"
set directive 0
end
set -l compErr (math (math --scale 0 $directive / $shellCompDirectiveError) % 2)
if test $compErr -eq 1
__goreleaser_debug "Received error directive: aborting."
# Might as well do file completion, in case it helps
return 1
end
set -l filefilter (math (math --scale 0 $directive / $shellCompDirectiveFilterFileExt) % 2)
set -l dirfilter (math (math --scale 0 $directive / $shellCompDirectiveFilterDirs) % 2)
if test $filefilter -eq 1; or test $dirfilter -eq 1
__goreleaser_debug "File extension filtering or directory filtering not supported"
# Do full file completion instead
return 1
end
set -l nospace (math (math --scale 0 $directive / $shellCompDirectiveNoSpace) % 2)
set -l nofiles (math (math --scale 0 $directive / $shellCompDirectiveNoFileComp) % 2)
__goreleaser_debug "nospace: $nospace, nofiles: $nofiles"
# If we want to prevent a space, or if file completion is NOT disabled,
# we need to count the number of valid completions.
# To do so, we will filter on prefix as the completions we have received
# may not already be filtered so as to allow fish to match on different
# criteria than the prefix.
if test $nospace -ne 0; or test $nofiles -eq 0
set -l prefix (commandline -t | string escape --style=regex)
__goreleaser_debug "prefix: $prefix"
set -l completions (string match -r -- "^$prefix.*" $__goreleaser_comp_results)
set --global __goreleaser_comp_results $completions
__goreleaser_debug "Filtered completions are: $__goreleaser_comp_results"
# Important not to quote the variable for count to work
set -l numComps (count $__goreleaser_comp_results)
__goreleaser_debug "numComps: $numComps"
if test $numComps -eq 1; and test $nospace -ne 0
# We must first split on \t to get rid of the descriptions to be
# able to check what the actual completion will be.
# We don't need descriptions anyway since there is only a single
# real completion which the shell will expand immediately.
set -l split (string split --max 1 \t $__goreleaser_comp_results[1])
# Fish won't add a space if the completion ends with any
# of the following characters: @=/:.,
set -l lastChar (string sub -s -1 -- $split)
if not string match -r -q "[@=/:.,]" -- "$lastChar"
# In other cases, to support the "nospace" directive we trick the shell
# by outputting an extra, longer completion.
__goreleaser_debug "Adding second completion to perform nospace directive"
set --global __goreleaser_comp_results $split[1] $split[1].
__goreleaser_debug "Completions are now: $__goreleaser_comp_results"
end
end
if test $numComps -eq 0; and test $nofiles -eq 0
# To be consistent with bash and zsh, we only trigger file
# completion when there are no other completions
__goreleaser_debug "Requesting file completion"
return 1
end
end
return 0
end
# Since Fish completions are only loaded once the user triggers them, we trigger them ourselves
# so we can properly delete any completions provided by another script.
# Only do this if the program can be found, or else fish may print some errors; besides,
# the existing completions will only be loaded if the program can be found.
if type -q "goreleaser"
# The space after the program name is essential to trigger completion for the program
# and not completion of the program name itself.
# Also, we use '> /dev/null 2>&1' since '&>' is not supported in older versions of fish.
complete --do-complete "goreleaser " > /dev/null 2>&1
end
# Remove any pre-existing completions for the program since we will be handling all of them.
complete -c goreleaser -e
# this will get called after the two calls below and clear the $__goreleaser_perform_completion_once_result global
complete -c goreleaser -n '__goreleaser_clear_perform_completion_once_result'
# The call to __goreleaser_prepare_completions will setup __goreleaser_comp_results
# which provides the program's completion choices.
# If this doesn't require order preservation, we don't use the -k flag
complete -c goreleaser -n 'not __goreleaser_requires_order_preservation && __goreleaser_prepare_completions' -f -a '$__goreleaser_comp_results'
# otherwise we use the -k flag
complete -k -c goreleaser -n '__goreleaser_requires_order_preservation && __goreleaser_prepare_completions' -f -a '$__goreleaser_comp_results'

View File

@@ -0,0 +1,212 @@
#compdef goreleaser
compdef _goreleaser goreleaser
# zsh completion for goreleaser -*- shell-script -*-
__goreleaser_debug()
{
local file="$BASH_COMP_DEBUG_FILE"
if [[ -n ${file} ]]; then
echo "$*" >> "${file}"
fi
}
_goreleaser()
{
local shellCompDirectiveError=1
local shellCompDirectiveNoSpace=2
local shellCompDirectiveNoFileComp=4
local shellCompDirectiveFilterFileExt=8
local shellCompDirectiveFilterDirs=16
local shellCompDirectiveKeepOrder=32
local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace keepOrder
local -a completions
__goreleaser_debug "\n========= starting completion logic =========="
__goreleaser_debug "CURRENT: ${CURRENT}, words[*]: ${words[*]}"
# The user could have moved the cursor backwards on the command-line.
# We need to trigger completion from the $CURRENT location, so we need
# to truncate the command-line ($words) up to the $CURRENT location.
# (We cannot use $CURSOR as its value does not work when a command is an alias.)
words=("${=words[1,CURRENT]}")
__goreleaser_debug "Truncated words[*]: ${words[*]},"
lastParam=${words[-1]}
lastChar=${lastParam[-1]}
__goreleaser_debug "lastParam: ${lastParam}, lastChar: ${lastChar}"
# For zsh, when completing a flag with an = (e.g., goreleaser -n=<TAB>)
# completions must be prefixed with the flag
setopt local_options BASH_REMATCH
if [[ "${lastParam}" =~ '-.*=' ]]; then
# We are dealing with a flag with an =
flagPrefix="-P ${BASH_REMATCH}"
fi
# Prepare the command to obtain completions
requestComp="${words[1]} __complete ${words[2,-1]}"
if [ "${lastChar}" = "" ]; then
# If the last parameter is complete (there is a space following it)
# We add an extra empty parameter so we can indicate this to the go completion code.
__goreleaser_debug "Adding extra empty parameter"
requestComp="${requestComp} \"\""
fi
__goreleaser_debug "About to call: eval ${requestComp}"
# Use eval to handle any environment variables and such
out=$(eval ${requestComp} 2>/dev/null)
__goreleaser_debug "completion output: ${out}"
# Extract the directive integer following a : from the last line
local lastLine
while IFS='\n' read -r line; do
lastLine=${line}
done < <(printf "%s\n" "${out[@]}")
__goreleaser_debug "last line: ${lastLine}"
if [ "${lastLine[1]}" = : ]; then
directive=${lastLine[2,-1]}
# Remove the directive including the : and the newline
local suffix
(( suffix=${#lastLine}+2))
out=${out[1,-$suffix]}
else
# There is no directive specified. Leave $out as is.
__goreleaser_debug "No directive found. Setting do default"
directive=0
fi
__goreleaser_debug "directive: ${directive}"
__goreleaser_debug "completions: ${out}"
__goreleaser_debug "flagPrefix: ${flagPrefix}"
if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then
__goreleaser_debug "Completion received error. Ignoring completions."
return
fi
local activeHelpMarker="_activeHelp_ "
local endIndex=${#activeHelpMarker}
local startIndex=$((${#activeHelpMarker}+1))
local hasActiveHelp=0
while IFS='\n' read -r comp; do
# Check if this is an activeHelp statement (i.e., prefixed with $activeHelpMarker)
if [ "${comp[1,$endIndex]}" = "$activeHelpMarker" ];then
__goreleaser_debug "ActiveHelp found: $comp"
comp="${comp[$startIndex,-1]}"
if [ -n "$comp" ]; then
compadd -x "${comp}"
__goreleaser_debug "ActiveHelp will need delimiter"
hasActiveHelp=1
fi
continue
fi
if [ -n "$comp" ]; then
# If requested, completions are returned with a description.
# The description is preceded by a TAB character.
# For zsh's _describe, we need to use a : instead of a TAB.
# We first need to escape any : as part of the completion itself.
comp=${comp//:/\\:}
local tab="$(printf '\t')"
comp=${comp//$tab/:}
__goreleaser_debug "Adding completion: ${comp}"
completions+=${comp}
lastComp=$comp
fi
done < <(printf "%s\n" "${out[@]}")
# Add a delimiter after the activeHelp statements, but only if:
# - there are completions following the activeHelp statements, or
# - file completion will be performed (so there will be choices after the activeHelp)
if [ $hasActiveHelp -eq 1 ]; then
if [ ${#completions} -ne 0 ] || [ $((directive & shellCompDirectiveNoFileComp)) -eq 0 ]; then
__goreleaser_debug "Adding activeHelp delimiter"
compadd -x "--"
hasActiveHelp=0
fi
fi
if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then
__goreleaser_debug "Activating nospace."
noSpace="-S ''"
fi
if [ $((directive & shellCompDirectiveKeepOrder)) -ne 0 ]; then
__goreleaser_debug "Activating keep order."
keepOrder="-V"
fi
if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then
# File extension filtering
local filteringCmd
filteringCmd='_files'
for filter in ${completions[@]}; do
if [ ${filter[1]} != '*' ]; then
# zsh requires a glob pattern to do file filtering
filter="\*.$filter"
fi
filteringCmd+=" -g $filter"
done
filteringCmd+=" ${flagPrefix}"
__goreleaser_debug "File filtering command: $filteringCmd"
_arguments '*:filename:'"$filteringCmd"
elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then
# File completion for directories only
local subdir
subdir="${completions[1]}"
if [ -n "$subdir" ]; then
__goreleaser_debug "Listing directories in $subdir"
pushd "${subdir}" >/dev/null 2>&1
else
__goreleaser_debug "Listing directories in ."
fi
local result
_arguments '*:dirname:_files -/'" ${flagPrefix}"
result=$?
if [ -n "$subdir" ]; then
popd >/dev/null 2>&1
fi
return $result
else
__goreleaser_debug "Calling _describe"
if eval _describe $keepOrder "completions" completions $flagPrefix $noSpace; then
__goreleaser_debug "_describe found some completions"
# Return the success of having called _describe
return 0
else
__goreleaser_debug "_describe did not find completions."
__goreleaser_debug "Checking if we should do file completion."
if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then
__goreleaser_debug "deactivating file completion"
# We must return an error code here to let zsh know that there were no
# completions found by _describe; this is what will trigger other
# matching algorithms to attempt to find completions.
# For example zsh can match letters in the middle of words.
return 1
else
# Perform file completion
__goreleaser_debug "Activating file completion"
# We must return the result of this command, so it must be the
# last command, or else we must store its result to return it.
_arguments '*:filename:_files'" ${flagPrefix}"
fi
fi
fi
}
# don't run the completion function when being source-ed or eval-ed
if [ "$funcstack[1]" = "_goreleaser" ]; then
_goreleaser
fi