You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					389 lines
				
				14 KiB
			
		
		
			
		
	
	
					389 lines
				
				14 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								#!/bin/bash
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# Bash completion generated for '{{name}}' at {{date}}.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# The original template lives here:
							 | 
						||
| 
								 | 
							
								# https://github.com/trentm/node-dashdash/blob/master/etc/dashdash.bash_completion.in
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# Copyright 2016 Trent Mick
							 | 
						||
| 
								 | 
							
								# Copyright 2016 Joyent, Inc.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# A generic Bash completion driver script.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# This is meant to provide a re-usable chunk of Bash to use for
							 | 
						||
| 
								 | 
							
								# "etc/bash_completion.d/" files for individual tools. Only the "Configuration"
							 | 
						||
| 
								 | 
							
								# section with tool-specific info need differ. Features:
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# - support for short and long opts
							 | 
						||
| 
								 | 
							
								# - support for knowing which options take arguments
							 | 
						||
| 
								 | 
							
								# - support for subcommands (e.g. 'git log <TAB>' to show just options for the
							 | 
						||
| 
								 | 
							
								#   log subcommand)
							 | 
						||
| 
								 | 
							
								# - does the right thing with "--" to stop options
							 | 
						||
| 
								 | 
							
								# - custom optarg and arg types for custom completions
							 | 
						||
| 
								 | 
							
								# - (TODO) support for shells other than Bash (tcsh, zsh, fish?, etc.)
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# Examples/design:
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# 1. Bash "default" completion. By default Bash's 'complete -o default' is
							 | 
						||
| 
								 | 
							
								#    enabled. That means when there are no completions (e.g. if no opts match
							 | 
						||
| 
								 | 
							
								#    the current word), then you'll get Bash's default completion. Most notably
							 | 
						||
| 
								 | 
							
								#    that means you get filename completion. E.g.:
							 | 
						||
| 
								 | 
							
								#       $ tool ./<TAB>
							 | 
						||
| 
								 | 
							
								#       $ tool READ<TAB>
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# 2. all opts and subcmds:
							 | 
						||
| 
								 | 
							
								#       $ tool <TAB>
							 | 
						||
| 
								 | 
							
								#       $ tool -v <TAB>     # assuming '-v' doesn't take an arg
							 | 
						||
| 
								 | 
							
								#       $ tool -<TAB>       # matching opts
							 | 
						||
| 
								 | 
							
								#       $ git lo<TAB>       # matching subcmds
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								#    Long opt completions are given *without* the '=', i.e. we prefer space
							 | 
						||
| 
								 | 
							
								#    separated because that's easier for good completions.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# 3. long opt arg with '='
							 | 
						||
| 
								 | 
							
								#       $ tool --file=<TAB>
							 | 
						||
| 
								 | 
							
								#       $ tool --file=./d<TAB>
							 | 
						||
| 
								 | 
							
								#    We maintain the "--file=" prefix. Limitation: With the attached prefix
							 | 
						||
| 
								 | 
							
								#    the 'complete -o filenames' doesn't know to do dirname '/' suffixing. Meh.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# 4. envvars:
							 | 
						||
| 
								 | 
							
								#       $ tool $<TAB>
							 | 
						||
| 
								 | 
							
								#       $ tool $P<TAB>
							 | 
						||
| 
								 | 
							
								#    Limitation: Currently only getting exported vars, so we miss "PS1" and
							 | 
						||
| 
								 | 
							
								#    others.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# 5. Defer to other completion in a subshell:
							 | 
						||
| 
								 | 
							
								#       $ tool --file $(cat ./<TAB>
							 | 
						||
| 
								 | 
							
								#    We get this from 'complete -o default ...'.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# 6. Custom completion types from a provided bash function.
							 | 
						||
| 
								 | 
							
								#       $ tool --profile <TAB>        # complete available "profiles"
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# Dev Notes:
							 | 
						||
| 
								 | 
							
								# - compgen notes, from http://unix.stackexchange.com/questions/151118/understand-compgen-builtin-command
							 | 
						||
| 
								 | 
							
								# - https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Debugging this completion:
							 | 
						||
| 
								 | 
							
								#   1. Uncomment the "_{{name}}_log_file=..." line.
							 | 
						||
| 
								 | 
							
								#   2. 'tail -f /var/tmp/dashdash-completion.log' in one terminal.
							 | 
						||
| 
								 | 
							
								#   3. Re-source this bash completion file.
							 | 
						||
| 
								 | 
							
								#_{{name}}_log=/var/tmp/dashdash-completion.log
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function _{{name}}_completer {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # ---- cmd definition
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    {{spec}}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # ---- locals
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    declare -a argv
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # ---- support functions
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function trace {
							 | 
						||
| 
								 | 
							
								        [[ -n "$_{{name}}_log" ]] && echo "$*" >&2
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function _dashdash_complete {
							 | 
						||
| 
								 | 
							
								        local idx context
							 | 
						||
| 
								 | 
							
								        idx=$1
							 | 
						||
| 
								 | 
							
								        context=$2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        local shortopts longopts optargs subcmds allsubcmds argtypes
							 | 
						||
| 
								 | 
							
								        shortopts="$(eval "echo \${cmd${context}_shortopts}")"
							 | 
						||
| 
								 | 
							
								        longopts="$(eval "echo \${cmd${context}_longopts}")"
							 | 
						||
| 
								 | 
							
								        optargs="$(eval "echo \${cmd${context}_optargs}")"
							 | 
						||
| 
								 | 
							
								        subcmds="$(eval "echo \${cmd${context}_subcmds}")"
							 | 
						||
| 
								 | 
							
								        allsubcmds="$(eval "echo \${cmd${context}_allsubcmds}")"
							 | 
						||
| 
								 | 
							
								        IFS=', ' read -r -a argtypes <<< "$(eval "echo \${cmd${context}_argtypes}")"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        trace ""
							 | 
						||
| 
								 | 
							
								        trace "_dashdash_complete(idx=$idx, context=$context)"
							 | 
						||
| 
								 | 
							
								        trace "  shortopts: $shortopts"
							 | 
						||
| 
								 | 
							
								        trace "  longopts: $longopts"
							 | 
						||
| 
								 | 
							
								        trace "  optargs: $optargs"
							 | 
						||
| 
								 | 
							
								        trace "  subcmds: $subcmds"
							 | 
						||
| 
								 | 
							
								        trace "  allsubcmds: $allsubcmds"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # Get 'state' of option parsing at this COMP_POINT.
							 | 
						||
| 
								 | 
							
								        # Copying "dashdash.js#parse()" behaviour here.
							 | 
						||
| 
								 | 
							
								        local state=
							 | 
						||
| 
								 | 
							
								        local nargs=0
							 | 
						||
| 
								 | 
							
								        local i=$idx
							 | 
						||
| 
								 | 
							
								        local argtype
							 | 
						||
| 
								 | 
							
								        local optname
							 | 
						||
| 
								 | 
							
								        local prefix
							 | 
						||
| 
								 | 
							
								        local word
							 | 
						||
| 
								 | 
							
								        local dashdashseen=
							 | 
						||
| 
								 | 
							
								        while [[ $i -lt $len && $i -le $COMP_CWORD ]]; do
							 | 
						||
| 
								 | 
							
								            argtype=
							 | 
						||
| 
								 | 
							
								            optname=
							 | 
						||
| 
								 | 
							
								            prefix=
							 | 
						||
| 
								 | 
							
								            word=
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            arg=${argv[$i]}
							 | 
						||
| 
								 | 
							
								            trace "  consider argv[$i]: '$arg'"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if [[ "$arg" == "--" && $i -lt $COMP_CWORD ]]; then
							 | 
						||
| 
								 | 
							
								                trace "    dashdash seen"
							 | 
						||
| 
								 | 
							
								                dashdashseen=yes
							 | 
						||
| 
								 | 
							
								                state=arg
							 | 
						||
| 
								 | 
							
								                word=$arg
							 | 
						||
| 
								 | 
							
								            elif [[ -z "$dashdashseen" && "${arg:0:2}" == "--" ]]; then
							 | 
						||
| 
								 | 
							
								                arg=${arg:2}
							 | 
						||
| 
								 | 
							
								                if [[ "$arg" == *"="* ]]; then
							 | 
						||
| 
								 | 
							
								                    optname=${arg%%=*}
							 | 
						||
| 
								 | 
							
								                    val=${arg##*=}
							 | 
						||
| 
								 | 
							
								                    trace "    long opt: optname='$optname' val='$val'"
							 | 
						||
| 
								 | 
							
								                    state=arg
							 | 
						||
| 
								 | 
							
								                    argtype=$(echo "$optargs" | awk -F "-$optname=" '{print $2}' | cut -d' ' -f1)
							 | 
						||
| 
								 | 
							
								                    word=$val
							 | 
						||
| 
								 | 
							
								                    prefix="--$optname="
							 | 
						||
| 
								 | 
							
								                else
							 | 
						||
| 
								 | 
							
								                    optname=$arg
							 | 
						||
| 
								 | 
							
								                    val=
							 | 
						||
| 
								 | 
							
								                    trace "    long opt: optname='$optname'"
							 | 
						||
| 
								 | 
							
								                    state=longopt
							 | 
						||
| 
								 | 
							
								                    word=--$optname
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    if [[ "$optargs" == *"-$optname="* && $i -lt $COMP_CWORD ]]; then
							 | 
						||
| 
								 | 
							
								                        i=$(( $i + 1 ))
							 | 
						||
| 
								 | 
							
								                        state=arg
							 | 
						||
| 
								 | 
							
								                        argtype=$(echo "$optargs" | awk -F "-$optname=" '{print $2}' | cut -d' ' -f1)
							 | 
						||
| 
								 | 
							
								                        word=${argv[$i]}
							 | 
						||
| 
								 | 
							
								                        trace "    takes arg (consume argv[$i], word='$word')"
							 | 
						||
| 
								 | 
							
								                    fi
							 | 
						||
| 
								 | 
							
								                fi
							 | 
						||
| 
								 | 
							
								            elif [[ -z "$dashdashseen" && "${arg:0:1}" == "-" ]]; then
							 | 
						||
| 
								 | 
							
								                trace "    short opt group"
							 | 
						||
| 
								 | 
							
								                state=shortopt
							 | 
						||
| 
								 | 
							
								                word=$arg
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                local j=1
							 | 
						||
| 
								 | 
							
								                while [[ $j -lt ${#arg} ]]; do
							 | 
						||
| 
								 | 
							
								                    optname=${arg:$j:1}
							 | 
						||
| 
								 | 
							
								                    trace "    consider index $j: optname '$optname'"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    if [[ "$optargs" == *"-$optname="* ]]; then
							 | 
						||
| 
								 | 
							
								                        argtype=$(echo "$optargs" | awk -F "-$optname=" '{print $2}' | cut -d' ' -f1)
							 | 
						||
| 
								 | 
							
								                        if [[ $(( $j + 1 )) -lt ${#arg} ]]; then
							 | 
						||
| 
								 | 
							
								                            state=arg
							 | 
						||
| 
								 | 
							
								                            word=${arg:$(( $j + 1 ))}
							 | 
						||
| 
								 | 
							
								                            trace "      takes arg (rest of this arg, word='$word', argtype='$argtype')"
							 | 
						||
| 
								 | 
							
								                        elif [[ $i -lt $COMP_CWORD ]]; then
							 | 
						||
| 
								 | 
							
								                            state=arg
							 | 
						||
| 
								 | 
							
								                            i=$(( $i + 1 ))
							 | 
						||
| 
								 | 
							
								                            word=${argv[$i]}
							 | 
						||
| 
								 | 
							
								                            trace "    takes arg (word='$word', argtype='$argtype')"
							 | 
						||
| 
								 | 
							
								                        fi
							 | 
						||
| 
								 | 
							
								                        break
							 | 
						||
| 
								 | 
							
								                    fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    j=$(( $j + 1 ))
							 | 
						||
| 
								 | 
							
								                done
							 | 
						||
| 
								 | 
							
								            elif [[ $i -lt $COMP_CWORD && -n "$arg" ]] && $(echo "$allsubcmds" | grep -w "$arg" >/dev/null); then
							 | 
						||
| 
								 | 
							
								                trace "    complete subcmd: recurse _dashdash_complete"
							 | 
						||
| 
								 | 
							
								                _dashdash_complete $(( $i + 1 )) "${context}__${arg/-/_}"
							 | 
						||
| 
								 | 
							
								                return
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								                trace "    not an opt or a complete subcmd"
							 | 
						||
| 
								 | 
							
								                state=arg
							 | 
						||
| 
								 | 
							
								                word=$arg
							 | 
						||
| 
								 | 
							
								                nargs=$(( $nargs + 1 ))
							 | 
						||
| 
								 | 
							
								                if [[ ${#argtypes[@]} -gt 0 ]]; then
							 | 
						||
| 
								 | 
							
								                    argtype="${argtypes[$(( $nargs - 1 ))]}"
							 | 
						||
| 
								 | 
							
								                    if [[ -z "$argtype" ]]; then
							 | 
						||
| 
								 | 
							
								                        # If we have more args than argtypes, we use the
							 | 
						||
| 
								 | 
							
								                        # last type.
							 | 
						||
| 
								 | 
							
								                        argtype="${argtypes[@]: -1:1}"
							 | 
						||
| 
								 | 
							
								                    fi
							 | 
						||
| 
								 | 
							
								                fi
							 | 
						||
| 
								 | 
							
								            fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            trace "    state=$state prefix='$prefix' word='$word'"
							 | 
						||
| 
								 | 
							
								            i=$(( $i + 1 ))
							 | 
						||
| 
								 | 
							
								        done
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        trace "  parsed: state=$state optname='$optname' argtype='$argtype' prefix='$prefix' word='$word' dashdashseen=$dashdashseen"
							 | 
						||
| 
								 | 
							
								        local compgen_opts=
							 | 
						||
| 
								 | 
							
								        if [[ -n "$prefix" ]]; then
							 | 
						||
| 
								 | 
							
								            compgen_opts="$compgen_opts -P $prefix"
							 | 
						||
| 
								 | 
							
								        fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case $state in
							 | 
						||
| 
								 | 
							
								        shortopt)
							 | 
						||
| 
								 | 
							
								            compgen $compgen_opts -W "$shortopts $longopts" -- "$word"
							 | 
						||
| 
								 | 
							
								            ;;
							 | 
						||
| 
								 | 
							
								        longopt)
							 | 
						||
| 
								 | 
							
								            compgen $compgen_opts -W "$longopts" -- "$word"
							 | 
						||
| 
								 | 
							
								            ;;
							 | 
						||
| 
								 | 
							
								        arg)
							 | 
						||
| 
								 | 
							
								            # If we don't know what completion to do, then emit nothing. We
							 | 
						||
| 
								 | 
							
								            # expect that we are running with:
							 | 
						||
| 
								 | 
							
								            #       complete -o default ...
							 | 
						||
| 
								 | 
							
								            # where "default" means: "Use Readline's default completion if
							 | 
						||
| 
								 | 
							
								            # the compspec generates no matches." This gives us the good filename
							 | 
						||
| 
								 | 
							
								            # completion, completion in subshells/backticks.
							 | 
						||
| 
								 | 
							
								            #
							 | 
						||
| 
								 | 
							
								            # We cannot support an argtype="directory" because
							 | 
						||
| 
								 | 
							
								            #       compgen -S '/' -A directory -- "$word"
							 | 
						||
| 
								 | 
							
								            # doesn't give a satisfying result. It doesn't stop at the trailing '/'
							 | 
						||
| 
								 | 
							
								            # so you cannot descend into dirs.
							 | 
						||
| 
								 | 
							
								            if [[ "${word:0:1}" == '$' ]]; then
							 | 
						||
| 
								 | 
							
								                # By default, Bash will complete '$<TAB>' to all envvars. Apparently
							 | 
						||
| 
								 | 
							
								                # 'complete -o default' does *not* give us that. The following
							 | 
						||
| 
								 | 
							
								                # gets *close* to the same completions: '-A export' misses envvars
							 | 
						||
| 
								 | 
							
								                # like "PS1".
							 | 
						||
| 
								 | 
							
								                trace "  completing envvars"
							 | 
						||
| 
								 | 
							
								                compgen $compgen_opts -P '$' -A export -- "${word:1}"
							 | 
						||
| 
								 | 
							
								            elif [[ -z "$argtype" ]]; then
							 | 
						||
| 
								 | 
							
								                # Only include opts in completions if $word is not empty.
							 | 
						||
| 
								 | 
							
								                # This is to avoid completing the leading '-', which foils
							 | 
						||
| 
								 | 
							
								                # using 'default' completion.
							 | 
						||
| 
								 | 
							
								                if [[ -n "$dashdashseen" ]]; then
							 | 
						||
| 
								 | 
							
								                    trace "  completing subcmds, if any (no argtype, dashdash seen)"
							 | 
						||
| 
								 | 
							
								                    compgen $compgen_opts -W "$subcmds" -- "$word"
							 | 
						||
| 
								 | 
							
								                elif [[ -z "$word" ]]; then
							 | 
						||
| 
								 | 
							
								                    trace "  completing subcmds, if any (no argtype, empty word)"
							 | 
						||
| 
								 | 
							
								                    compgen $compgen_opts -W "$subcmds" -- "$word"
							 | 
						||
| 
								 | 
							
								                else
							 | 
						||
| 
								 | 
							
								                    trace "  completing opts & subcmds (no argtype)"
							 | 
						||
| 
								 | 
							
								                    compgen $compgen_opts -W "$shortopts $longopts $subcmds" -- "$word"
							 | 
						||
| 
								 | 
							
								                fi
							 | 
						||
| 
								 | 
							
								            elif [[ $argtype == "none" ]]; then
							 | 
						||
| 
								 | 
							
								                # We want *no* completions, i.e. some way to get the active
							 | 
						||
| 
								 | 
							
								                # 'complete -o default' to not do filename completion.
							 | 
						||
| 
								 | 
							
								                trace "  completing 'none' (hack to imply no completions)"
							 | 
						||
| 
								 | 
							
								                echo "##-no-completion- -results-##"
							 | 
						||
| 
								 | 
							
								            elif [[ $argtype == "file" ]]; then
							 | 
						||
| 
								 | 
							
								                # 'complete -o default' gives the best filename completion, at least
							 | 
						||
| 
								 | 
							
								                # on Mac.
							 | 
						||
| 
								 | 
							
								                trace "  completing 'file' (let 'complete -o default' handle it)"
							 | 
						||
| 
								 | 
							
								                echo ""
							 | 
						||
| 
								 | 
							
								            elif ! type complete_$argtype 2>/dev/null >/dev/null; then
							 | 
						||
| 
								 | 
							
								                trace "  completing '$argtype' (fallback to default b/c complete_$argtype is unknown)"
							 | 
						||
| 
								 | 
							
								                echo ""
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								                trace "  completing custom '$argtype'"
							 | 
						||
| 
								 | 
							
								                completions=$(complete_$argtype "$word")
							 | 
						||
| 
								 | 
							
								                if [[ -z "$completions" ]]; then
							 | 
						||
| 
								 | 
							
								                    trace "  no custom '$argtype' completions"
							 | 
						||
| 
								 | 
							
								                    # These are in ascii and "dictionary" order so they sort
							 | 
						||
| 
								 | 
							
								                    # correctly.
							 | 
						||
| 
								 | 
							
								                    echo "##-no-completion- -results-##"
							 | 
						||
| 
								 | 
							
								                else
							 | 
						||
| 
								 | 
							
								                    echo $completions
							 | 
						||
| 
								 | 
							
								                fi
							 | 
						||
| 
								 | 
							
								            fi
							 | 
						||
| 
								 | 
							
								            ;;
							 | 
						||
| 
								 | 
							
								        *)
							 | 
						||
| 
								 | 
							
								            trace "  unknown state: $state"
							 | 
						||
| 
								 | 
							
								            ;;
							 | 
						||
| 
								 | 
							
								        esac
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    trace ""
							 | 
						||
| 
								 | 
							
								    trace "-- $(date)"
							 | 
						||
| 
								 | 
							
								    #trace "\$IFS: '$IFS'"
							 | 
						||
| 
								 | 
							
								    #trace "\$@: '$@'"
							 | 
						||
| 
								 | 
							
								    #trace "COMP_WORDBREAKS: '$COMP_WORDBREAKS'"
							 | 
						||
| 
								 | 
							
								    trace "COMP_CWORD: '$COMP_CWORD'"
							 | 
						||
| 
								 | 
							
								    trace "COMP_LINE: '$COMP_LINE'"
							 | 
						||
| 
								 | 
							
								    trace "COMP_POINT: $COMP_POINT"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # Guard against negative COMP_CWORD. This is a Bash bug at least on
							 | 
						||
| 
								 | 
							
								    # Mac 10.10.4's bash. See
							 | 
						||
| 
								 | 
							
								    # <https://lists.gnu.org/archive/html/bug-bash/2009-07/msg00125.html>.
							 | 
						||
| 
								 | 
							
								    if [[ $COMP_CWORD -lt 0 ]]; then
							 | 
						||
| 
								 | 
							
								        trace "abort on negative COMP_CWORD"
							 | 
						||
| 
								 | 
							
								        exit 1;
							 | 
						||
| 
								 | 
							
								    fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # I don't know how to do array manip on argv vars,
							 | 
						||
| 
								 | 
							
								    # so copy over to argv array to work on them.
							 | 
						||
| 
								 | 
							
								    shift   # the leading '--'
							 | 
						||
| 
								 | 
							
								    i=0
							 | 
						||
| 
								 | 
							
								    len=$#
							 | 
						||
| 
								 | 
							
								    while [[ $# -gt 0 ]]; do
							 | 
						||
| 
								 | 
							
								        argv[$i]=$1
							 | 
						||
| 
								 | 
							
								        shift;
							 | 
						||
| 
								 | 
							
								        i=$(( $i + 1 ))
							 | 
						||
| 
								 | 
							
								    done
							 | 
						||
| 
								 | 
							
								    trace "argv: '${argv[@]}'"
							 | 
						||
| 
								 | 
							
								    trace "argv[COMP_CWORD-1]: '${argv[$(( $COMP_CWORD - 1 ))]}'"
							 | 
						||
| 
								 | 
							
								    trace "argv[COMP_CWORD]: '${argv[$COMP_CWORD]}'"
							 | 
						||
| 
								 | 
							
								    trace "argv len: '$len'"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    _dashdash_complete 1 ""
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# ---- mainline
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Note: This if-block to help work with 'compdef' and 'compctl' is
							 | 
						||
| 
								 | 
							
								# adapted from 'npm completion'.
							 | 
						||
| 
								 | 
							
								if type complete &>/dev/null; then
							 | 
						||
| 
								 | 
							
								    function _{{name}}_completion {
							 | 
						||
| 
								 | 
							
								        local _log_file=/dev/null
							 | 
						||
| 
								 | 
							
								        [[ -z "$_{{name}}_log" ]] || _log_file="$_{{name}}_log"
							 | 
						||
| 
								 | 
							
								        COMPREPLY=($(COMP_CWORD="$COMP_CWORD" \
							 | 
						||
| 
								 | 
							
								            COMP_LINE="$COMP_LINE" \
							 | 
						||
| 
								 | 
							
								            COMP_POINT="$COMP_POINT" \
							 | 
						||
| 
								 | 
							
								            _{{name}}_completer -- "${COMP_WORDS[@]}" \
							 | 
						||
| 
								 | 
							
								            2>$_log_file)) || return $?
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    complete -o default -F _{{name}}_completion {{name}}
							 | 
						||
| 
								 | 
							
								elif type compdef &>/dev/null; then
							 | 
						||
| 
								 | 
							
								    function _{{name}}_completion {
							 | 
						||
| 
								 | 
							
								        local _log_file=/dev/null
							 | 
						||
| 
								 | 
							
								        [[ -z "$_{{name}}_log" ]] || _log_file="$_{{name}}_log"
							 | 
						||
| 
								 | 
							
								        compadd -- $(COMP_CWORD=$((CURRENT-1)) \
							 | 
						||
| 
								 | 
							
								            COMP_LINE=$BUFFER \
							 | 
						||
| 
								 | 
							
								            COMP_POINT=0 \
							 | 
						||
| 
								 | 
							
								            _{{name}}_completer -- "${words[@]}" \
							 | 
						||
| 
								 | 
							
								            2>$_log_file)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    compdef _{{name}}_completion {{name}}
							 | 
						||
| 
								 | 
							
								elif type compctl &>/dev/null; then
							 | 
						||
| 
								 | 
							
								    function _{{name}}_completion {
							 | 
						||
| 
								 | 
							
								        local cword line point words si
							 | 
						||
| 
								 | 
							
								        read -Ac words
							 | 
						||
| 
								 | 
							
								        read -cn cword
							 | 
						||
| 
								 | 
							
								        let cword-=1
							 | 
						||
| 
								 | 
							
								        read -l line
							 | 
						||
| 
								 | 
							
								        read -ln point
							 | 
						||
| 
								 | 
							
								        local _log_file=/dev/null
							 | 
						||
| 
								 | 
							
								        [[ -z "$_{{name}}_log" ]] || _log_file="$_{{name}}_log"
							 | 
						||
| 
								 | 
							
								        reply=($(COMP_CWORD="$cword" \
							 | 
						||
| 
								 | 
							
								            COMP_LINE="$line" \
							 | 
						||
| 
								 | 
							
								            COMP_POINT="$point" \
							 | 
						||
| 
								 | 
							
								            _{{name}}_completer -- "${words[@]}" \
							 | 
						||
| 
								 | 
							
								            2>$_log_file)) || return $?
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    compctl -K _{{name}}_completion {{name}}
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								##
							 | 
						||
| 
								 | 
							
								## This is a Bash completion file for the '{{name}}' command. You can install
							 | 
						||
| 
								 | 
							
								## with either:
							 | 
						||
| 
								 | 
							
								##
							 | 
						||
| 
								 | 
							
								##     cp FILE /usr/local/etc/bash_completion.d/{{name}}   # Mac
							 | 
						||
| 
								 | 
							
								##     cp FILE /etc/bash_completion.d/{{name}}             # Linux
							 | 
						||
| 
								 | 
							
								##
							 | 
						||
| 
								 | 
							
								## or:
							 | 
						||
| 
								 | 
							
								##
							 | 
						||
| 
								 | 
							
								##     cp FILE > ~/.{{name}}.completion
							 | 
						||
| 
								 | 
							
								##     echo "source ~/.{{name}}.completion" >> ~/.bashrc
							 | 
						||
| 
								 | 
							
								##
							 |