Blame bash_completion

Packit 8462d6
#                                                          -*- shell-script -*-
Packit 8462d6
#
Packit 8462d6
#   bash_completion - programmable completion functions for bash 4.1+
Packit 8462d6
#
Packit 8462d6
#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>
Packit 8462d6
#             © 2009-2017, Bash Completion Maintainers
Packit 8462d6
#
Packit 8462d6
#   This program is free software; you can redistribute it and/or modify
Packit 8462d6
#   it under the terms of the GNU General Public License as published by
Packit 8462d6
#   the Free Software Foundation; either version 2, or (at your option)
Packit 8462d6
#   any later version.
Packit 8462d6
#
Packit 8462d6
#   This program is distributed in the hope that it will be useful,
Packit 8462d6
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 8462d6
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 8462d6
#   GNU General Public License for more details.
Packit 8462d6
#
Packit 8462d6
#   You should have received a copy of the GNU General Public License
Packit 8462d6
#   along with this program; if not, write to the Free Software Foundation,
Packit 8462d6
#   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Packit 8462d6
#
Packit 8462d6
#   The latest version of this software can be obtained here:
Packit 8462d6
#
Packit 8462d6
#   https://github.com/scop/bash-completion
Packit 8462d6
Packit 8462d6
BASH_COMPLETION_VERSINFO=(2 7)
Packit 8462d6
Packit 8462d6
if [[ $- == *v* ]]; then
Packit 8462d6
    BASH_COMPLETION_ORIGINAL_V_VALUE="-v"
Packit 8462d6
else
Packit 8462d6
    BASH_COMPLETION_ORIGINAL_V_VALUE="+v"
Packit 8462d6
fi
Packit 8462d6
Packit 8462d6
if [[ ${BASH_COMPLETION_DEBUG-} ]]; then
Packit 8462d6
    set -v
Packit 8462d6
else
Packit 8462d6
    set +v
Packit 8462d6
fi
Packit 8462d6
Packit 8462d6
# Blacklisted completions, causing problems with our code.
Packit 8462d6
#
Packit 8462d6
_blacklist_glob='@(acroread.sh)'
Packit 8462d6
Packit 8462d6
# Turn on extended globbing and programmable completion
Packit 8462d6
shopt -s extglob progcomp
Packit 8462d6
Packit 8462d6
# A lot of the following one-liners were taken directly from the
Packit 8462d6
# completion examples provided with the bash 2.04 source distribution
Packit 8462d6
Packit 8462d6
# start of section containing compspecs that can be handled within bash
Packit 8462d6
Packit 8462d6
# user commands see only users
Packit 8462d6
complete -u groups slay w sux
Packit 8462d6
Packit 8462d6
# bg completes with stopped jobs
Packit 8462d6
complete -A stopped -P '"%' -S '"' bg
Packit 8462d6
Packit 8462d6
# other job commands
Packit 8462d6
complete -j -P '"%' -S '"' fg jobs disown
Packit 8462d6
Packit 8462d6
# readonly and unset complete with shell variables
Packit 8462d6
complete -v readonly unset
Packit 8462d6
Packit 8462d6
# set completes with set options
Packit 8462d6
complete -A setopt set
Packit 8462d6
Packit 8462d6
# shopt completes with shopt options
Packit 8462d6
complete -A shopt shopt
Packit 8462d6
Packit 8462d6
# helptopics
Packit 8462d6
complete -A helptopic help
Packit 8462d6
Packit 8462d6
# unalias completes with aliases
Packit 8462d6
complete -a unalias
Packit 8462d6
Packit 8462d6
# type and which complete on commands
Packit 8462d6
complete -c command type which
Packit 8462d6
Packit 8462d6
# builtin completes on builtins
Packit 8462d6
complete -b builtin
Packit 8462d6
Packit 8462d6
# start of section containing completion functions called by other functions
Packit 8462d6
Packit 8462d6
# Check if we're running on the given userland
Packit 8462d6
# @param $1 userland to check for
Packit 8462d6
_userland()
Packit 8462d6
{
Packit 8462d6
    local userland=$( uname -s )
Packit 8462d6
    [[ $userland == @(Linux|GNU/*) ]] && userland=GNU
Packit 8462d6
    [[ $userland == $1 ]]
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function sets correct SysV init directories
Packit 8462d6
#
Packit 8462d6
_sysvdirs()
Packit 8462d6
{
Packit 8462d6
    sysvdirs=( )
Packit 8462d6
    [[ -d /etc/rc.d/init.d ]] && sysvdirs+=( /etc/rc.d/init.d )
Packit 8462d6
    [[ -d /etc/init.d ]] && sysvdirs+=( /etc/init.d )
Packit 8462d6
    # Slackware uses /etc/rc.d
Packit 8462d6
    [[ -f /etc/slackware-version ]] && sysvdirs=( /etc/rc.d )
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function checks whether we have a given program on the system.
Packit 8462d6
#
Packit 8462d6
_have()
Packit 8462d6
{
Packit 8462d6
    # Completions for system administrator commands are installed as well in
Packit 8462d6
    # case completion is attempted via `sudo command ...'.
Packit 8462d6
    PATH=$PATH:/usr/sbin:/sbin:/usr/local/sbin type $1 &>/dev/null
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# Backwards compatibility for compat completions that use have().
Packit 8462d6
# @deprecated should no longer be used; generally not needed with dynamically
Packit 8462d6
#             loaded completions, and _have is suitable for runtime use.
Packit 8462d6
have()
Packit 8462d6
{
Packit 8462d6
    unset -v have
Packit 8462d6
    _have $1 && have=yes
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function checks whether a given readline variable
Packit 8462d6
# is `on'.
Packit 8462d6
#
Packit 8462d6
_rl_enabled()
Packit 8462d6
{
Packit 8462d6
    [[ "$( bind -v )" == *$1+([[:space:]])on* ]]
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function shell-quotes the argument
Packit 8462d6
quote()
Packit 8462d6
{
Packit 8462d6
    local quoted=${1//\'/\'\\\'\'}
Packit 8462d6
    printf "'%s'" "$quoted"
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# @see _quote_readline_by_ref()
Packit 8462d6
quote_readline()
Packit 8462d6
{
Packit 8462d6
    local quoted
Packit 8462d6
    _quote_readline_by_ref "$1" ret
Packit 8462d6
    printf %s "$ret"
Packit 8462d6
} # quote_readline()
Packit 8462d6
Packit 8462d6
Packit 8462d6
# This function shell-dequotes the argument
Packit 8462d6
dequote()
Packit 8462d6
{
Packit 8462d6
    eval printf %s "$1" 2> /dev/null
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
Packit 8462d6
# Assign variable one scope above the caller
Packit 8462d6
# Usage: local "$1" && _upvar $1 "value(s)"
Packit 8462d6
# Param: $1  Variable name to assign value to
Packit 8462d6
# Param: $*  Value(s) to assign.  If multiple values, an array is
Packit 8462d6
#            assigned, otherwise a single value is assigned.
Packit 8462d6
# NOTE: For assigning multiple variables, use '_upvars'.  Do NOT
Packit 8462d6
#       use multiple '_upvar' calls, since one '_upvar' call might
Packit 8462d6
#       reassign a variable to be used by another '_upvar' call.
Packit 8462d6
# See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference
Packit 8462d6
_upvar()
Packit 8462d6
{
Packit 8462d6
    if unset -v "$1"; then           # Unset & validate varname
Packit 8462d6
        if (( $# == 2 )); then
Packit 8462d6
            eval $1=\"\$2\"          # Return single value
Packit 8462d6
        else
Packit 8462d6
            eval $1=\(\"\${@:2}\"\)  # Return array
Packit 8462d6
        fi
Packit 8462d6
    fi
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
Packit 8462d6
# Assign variables one scope above the caller
Packit 8462d6
# Usage: local varname [varname ...] &&
Packit 8462d6
#        _upvars [-v varname value] | [-aN varname [value ...]] ...
Packit 8462d6
# Available OPTIONS:
Packit 8462d6
#     -aN  Assign next N values to varname as array
Packit 8462d6
#     -v   Assign single value to varname
Packit 8462d6
# Return: 1 if error occurs
Packit 8462d6
# See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference
Packit 8462d6
_upvars()
Packit 8462d6
{
Packit 8462d6
    if ! (( $# )); then
Packit 8462d6
        echo "${FUNCNAME[0]}: usage: ${FUNCNAME[0]} [-v varname"\
Packit 8462d6
            "value] | [-aN varname [value ...]] ..." 1>&2
Packit 8462d6
        return 2
Packit 8462d6
    fi
Packit 8462d6
    while (( $# )); do
Packit 8462d6
        case $1 in
Packit 8462d6
            -a*)
Packit 8462d6
                # Error checking
Packit 8462d6
                [[ ${1#-a} ]] || { echo "bash: ${FUNCNAME[0]}: \`$1': missing"\
Packit 8462d6
                    "number specifier" 1>&2; return 1; }
Packit 8462d6
                printf %d "${1#-a}" &> /dev/null || { echo "bash:"\
Packit 8462d6
                    "${FUNCNAME[0]}: \`$1': invalid number specifier" 1>&2
Packit 8462d6
                    return 1; }
Packit 8462d6
                # Assign array of -aN elements
Packit 8462d6
                [[ "$2" ]] && unset -v "$2" && eval $2=\(\"\${@:3:${1#-a}}\"\) &&
Packit 8462d6
                shift $((${1#-a} + 2)) || { echo "bash: ${FUNCNAME[0]}:"\
Packit 8462d6
                    "\`$1${2+ }$2': missing argument(s)" 1>&2; return 1; }
Packit 8462d6
                ;;
Packit 8462d6
            -v)
Packit 8462d6
                # Assign single value
Packit 8462d6
                [[ "$2" ]] && unset -v "$2" && eval $2=\"\$3\" &&
Packit 8462d6
                shift 3 || { echo "bash: ${FUNCNAME[0]}: $1: missing"\
Packit 8462d6
                "argument(s)" 1>&2; return 1; }
Packit 8462d6
                ;;
Packit 8462d6
            *)
Packit 8462d6
                echo "bash: ${FUNCNAME[0]}: $1: invalid option" 1>&2
Packit 8462d6
                return 1 ;;
Packit 8462d6
        esac
Packit 8462d6
    done
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
Packit 8462d6
# Reassemble command line words, excluding specified characters from the
Packit 8462d6
# list of word completion separators (COMP_WORDBREAKS).
Packit 8462d6
# @param $1 chars  Characters out of $COMP_WORDBREAKS which should
Packit 8462d6
#     NOT be considered word breaks. This is useful for things like scp where
Packit 8462d6
#     we want to return host:path and not only path, so we would pass the
Packit 8462d6
#     colon (:) as $1 here.
Packit 8462d6
# @param $2 words  Name of variable to return words to
Packit 8462d6
# @param $3 cword  Name of variable to return cword to
Packit 8462d6
#
Packit 8462d6
__reassemble_comp_words_by_ref()
Packit 8462d6
{
Packit 8462d6
    local exclude i j line ref
Packit 8462d6
    # Exclude word separator characters?
Packit 8462d6
    if [[ $1 ]]; then
Packit 8462d6
        # Yes, exclude word separator characters;
Packit 8462d6
        # Exclude only those characters, which were really included
Packit 8462d6
        exclude="${1//[^$COMP_WORDBREAKS]}"
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    # Default to cword unchanged
Packit 8462d6
    printf -v "$3" %s "$COMP_CWORD"
Packit 8462d6
    # Are characters excluded which were former included?
Packit 8462d6
    if [[ $exclude ]]; then
Packit 8462d6
        # Yes, list of word completion separators has shrunk;
Packit 8462d6
        line=$COMP_LINE
Packit 8462d6
        # Re-assemble words to complete
Packit 8462d6
        for (( i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
Packit 8462d6
            # Is current word not word 0 (the command itself) and is word not
Packit 8462d6
            # empty and is word made up of just word separator characters to
Packit 8462d6
            # be excluded and is current word not preceded by whitespace in
Packit 8462d6
            # original line?
Packit 8462d6
            while [[ $i -gt 0 && ${COMP_WORDS[$i]} == +([$exclude]) ]]; do
Packit 8462d6
                # Is word separator not preceded by whitespace in original line
Packit 8462d6
                # and are we not going to append to word 0 (the command
Packit 8462d6
                # itself), then append to current word.
Packit 8462d6
                [[ $line != [[:blank:]]* ]] && (( j >= 2 )) && ((j--))
Packit 8462d6
                # Append word separator to current or new word
Packit 8462d6
                ref="$2[$j]"
Packit 8462d6
                printf -v "$ref" %s "${!ref}${COMP_WORDS[i]}"
Packit 8462d6
                # Indicate new cword
Packit 8462d6
                [[ $i == $COMP_CWORD ]] && printf -v "$3" %s "$j"
Packit 8462d6
                # Remove optional whitespace + word separator from line copy
Packit 8462d6
                line=${line#*"${COMP_WORDS[$i]}"}
Packit 8462d6
                # Start new word if word separator in original line is
Packit 8462d6
                # followed by whitespace.
Packit 8462d6
                [[ $line == [[:blank:]]* ]] && ((j++))
Packit 8462d6
                # Indicate next word if available, else end *both* while and
Packit 8462d6
                # for loop
Packit 8462d6
                (( $i < ${#COMP_WORDS[@]} - 1)) && ((i++)) || break 2
Packit 8462d6
            done
Packit 8462d6
            # Append word to current word
Packit 8462d6
            ref="$2[$j]"
Packit 8462d6
            printf -v "$ref" %s "${!ref}${COMP_WORDS[i]}"
Packit 8462d6
            # Remove optional whitespace + word from line copy
Packit 8462d6
            line=${line#*"${COMP_WORDS[i]}"}
Packit 8462d6
            # Indicate new cword
Packit 8462d6
            [[ $i == $COMP_CWORD ]] && printf -v "$3" %s "$j"
Packit 8462d6
        done
Packit 8462d6
        [[ $i == $COMP_CWORD ]] && printf -v "$3" %s "$j"
Packit 8462d6
    else
Packit 8462d6
        # No, list of word completions separators hasn't changed;
Packit 8462d6
        for i in ${!COMP_WORDS[@]}; do
Packit 8462d6
            printf -v "$2[i]" %s "${COMP_WORDS[i]}"
Packit 8462d6
        done
Packit 8462d6
    fi
Packit 8462d6
} # __reassemble_comp_words_by_ref()
Packit 8462d6
Packit 8462d6
Packit 8462d6
# @param $1 exclude  Characters out of $COMP_WORDBREAKS which should NOT be
Packit 8462d6
#     considered word breaks. This is useful for things like scp where
Packit 8462d6
#     we want to return host:path and not only path, so we would pass the
Packit 8462d6
#     colon (:) as $1 in this case.
Packit 8462d6
# @param $2 words  Name of variable to return words to
Packit 8462d6
# @param $3 cword  Name of variable to return cword to
Packit 8462d6
# @param $4 cur  Name of variable to return current word to complete to
Packit 8462d6
# @see __reassemble_comp_words_by_ref()
Packit 8462d6
__get_cword_at_cursor_by_ref()
Packit 8462d6
{
Packit 8462d6
    local cword words=()
Packit 8462d6
    __reassemble_comp_words_by_ref "$1" words cword
Packit 8462d6
Packit 8462d6
    local i cur index=$COMP_POINT lead=${COMP_LINE:0:$COMP_POINT}
Packit 8462d6
    # Cursor not at position 0 and not leaded by just space(s)?
Packit 8462d6
    if [[ $index -gt 0 && ( $lead && ${lead//[[:space:]]} ) ]]; then
Packit 8462d6
        cur=$COMP_LINE
Packit 8462d6
        for (( i = 0; i <= cword; ++i )); do
Packit 8462d6
            while [[
Packit 8462d6
                # Current word fits in $cur?
Packit 8462d6
                ${#cur} -ge ${#words[i]} &&
Packit 8462d6
                # $cur doesn't match cword?
Packit 8462d6
                "${cur:0:${#words[i]}}" != "${words[i]}"
Packit 8462d6
            ]]; do
Packit 8462d6
                # Strip first character
Packit 8462d6
                cur="${cur:1}"
Packit 8462d6
                # Decrease cursor position, staying >= 0
Packit 8462d6
                [[ $index -gt 0 ]] && ((index--))
Packit 8462d6
            done
Packit 8462d6
Packit 8462d6
            # Does found word match cword?
Packit 8462d6
            if [[ $i -lt $cword ]]; then
Packit 8462d6
                # No, cword lies further;
Packit 8462d6
                local old_size=${#cur}
Packit 8462d6
                cur="${cur#"${words[i]}"}"
Packit 8462d6
                local new_size=${#cur}
Packit 8462d6
                index=$(( index - old_size + new_size ))
Packit 8462d6
            fi
Packit 8462d6
        done
Packit 8462d6
        # Clear $cur if just space(s)
Packit 8462d6
        [[ $cur && ! ${cur//[[:space:]]} ]] && cur=
Packit 8462d6
        # Zero $index if negative
Packit 8462d6
        [[ $index -lt 0 ]] && index=0
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    local "$2" "$3" "$4" && _upvars -a${#words[@]} $2 "${words[@]}" \
Packit 8462d6
        -v $3 "$cword" -v $4 "${cur:0:$index}"
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
Packit 8462d6
# Get the word to complete and optional previous words.
Packit 8462d6
# This is nicer than ${COMP_WORDS[$COMP_CWORD]}, since it handles cases
Packit 8462d6
# where the user is completing in the middle of a word.
Packit 8462d6
# (For example, if the line is "ls foobar",
Packit 8462d6
# and the cursor is here -------->   ^
Packit 8462d6
# Also one is able to cross over possible wordbreak characters.
Packit 8462d6
# Usage: _get_comp_words_by_ref [OPTIONS] [VARNAMES]
Packit 8462d6
# Available VARNAMES:
Packit 8462d6
#     cur         Return cur via $cur
Packit 8462d6
#     prev        Return prev via $prev
Packit 8462d6
#     words       Return words via $words
Packit 8462d6
#     cword       Return cword via $cword
Packit 8462d6
#
Packit 8462d6
# Available OPTIONS:
Packit 8462d6
#     -n EXCLUDE  Characters out of $COMP_WORDBREAKS which should NOT be
Packit 8462d6
#                 considered word breaks. This is useful for things like scp
Packit 8462d6
#                 where we want to return host:path and not only path, so we
Packit 8462d6
#                 would pass the colon (:) as -n option in this case.
Packit 8462d6
#     -c VARNAME  Return cur via $VARNAME
Packit 8462d6
#     -p VARNAME  Return prev via $VARNAME
Packit 8462d6
#     -w VARNAME  Return words via $VARNAME
Packit 8462d6
#     -i VARNAME  Return cword via $VARNAME
Packit 8462d6
#
Packit 8462d6
# Example usage:
Packit 8462d6
#
Packit 8462d6
#    $ _get_comp_words_by_ref -n : cur prev
Packit 8462d6
#
Packit 8462d6
_get_comp_words_by_ref()
Packit 8462d6
{
Packit 8462d6
    local exclude flag i OPTIND=1
Packit 8462d6
    local cur cword words=()
Packit 8462d6
    local upargs=() upvars=() vcur vcword vprev vwords
Packit 8462d6
Packit 8462d6
    while getopts "c:i:n:p:w:" flag "$@"; do
Packit 8462d6
        case $flag in
Packit 8462d6
            c) vcur=$OPTARG ;;
Packit 8462d6
            i) vcword=$OPTARG ;;
Packit 8462d6
            n) exclude=$OPTARG ;;
Packit 8462d6
            p) vprev=$OPTARG ;;
Packit 8462d6
            w) vwords=$OPTARG ;;
Packit 8462d6
        esac
Packit 8462d6
    done
Packit 8462d6
    while [[ $# -ge $OPTIND ]]; do
Packit 8462d6
        case ${!OPTIND} in
Packit 8462d6
            cur)   vcur=cur ;;
Packit 8462d6
            prev)  vprev=prev ;;
Packit 8462d6
            cword) vcword=cword ;;
Packit 8462d6
            words) vwords=words ;;
Packit 8462d6
            *) echo "bash: $FUNCNAME(): \`${!OPTIND}': unknown argument" \
Packit 8462d6
                1>&2; return 1
Packit 8462d6
        esac
Packit 8462d6
        let "OPTIND += 1"
Packit 8462d6
    done
Packit 8462d6
Packit 8462d6
    __get_cword_at_cursor_by_ref "$exclude" words cword cur
Packit 8462d6
Packit 8462d6
    [[ $vcur   ]] && { upvars+=("$vcur"  ); upargs+=(-v $vcur   "$cur"  ); }
Packit 8462d6
    [[ $vcword ]] && { upvars+=("$vcword"); upargs+=(-v $vcword "$cword"); }
Packit 8462d6
    [[ $vprev && $cword -ge 1 ]] && { upvars+=("$vprev" ); upargs+=(-v $vprev
Packit 8462d6
        "${words[cword - 1]}"); }
Packit 8462d6
    [[ $vwords ]] && { upvars+=("$vwords"); upargs+=(-a${#words[@]} $vwords
Packit 8462d6
        "${words[@]}"); }
Packit 8462d6
Packit 8462d6
    (( ${#upvars[@]} )) && local "${upvars[@]}" && _upvars "${upargs[@]}"
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
Packit 8462d6
# Get the word to complete.
Packit 8462d6
# This is nicer than ${COMP_WORDS[$COMP_CWORD]}, since it handles cases
Packit 8462d6
# where the user is completing in the middle of a word.
Packit 8462d6
# (For example, if the line is "ls foobar",
Packit 8462d6
# and the cursor is here -------->   ^
Packit 8462d6
# @param $1 string  Characters out of $COMP_WORDBREAKS which should NOT be
Packit 8462d6
#     considered word breaks. This is useful for things like scp where
Packit 8462d6
#     we want to return host:path and not only path, so we would pass the
Packit 8462d6
#     colon (:) as $1 in this case.
Packit 8462d6
# @param $2 integer  Index number of word to return, negatively offset to the
Packit 8462d6
#     current word (default is 0, previous is 1), respecting the exclusions
Packit 8462d6
#     given at $1.  For example, `_get_cword "=:" 1' returns the word left of
Packit 8462d6
#     the current word, respecting the exclusions "=:".
Packit 8462d6
# @deprecated  Use `_get_comp_words_by_ref cur' instead
Packit 8462d6
# @see _get_comp_words_by_ref()
Packit 8462d6
_get_cword()
Packit 8462d6
{
Packit 8462d6
    local LC_CTYPE=C
Packit 8462d6
    local cword words
Packit 8462d6
    __reassemble_comp_words_by_ref "$1" words cword
Packit 8462d6
Packit 8462d6
    # return previous word offset by $2
Packit 8462d6
    if [[ ${2//[^0-9]/} ]]; then
Packit 8462d6
        printf "%s" "${words[cword-$2]}"
Packit 8462d6
    elif [[ "${#words[cword]}" -eq 0 || "$COMP_POINT" == "${#COMP_LINE}" ]]; then
Packit 8462d6
        printf "%s" "${words[cword]}"
Packit 8462d6
    else
Packit 8462d6
        local i
Packit 8462d6
        local cur="$COMP_LINE"
Packit 8462d6
        local index="$COMP_POINT"
Packit 8462d6
        for (( i = 0; i <= cword; ++i )); do
Packit 8462d6
            while [[
Packit 8462d6
                # Current word fits in $cur?
Packit 8462d6
                "${#cur}" -ge ${#words[i]} &&
Packit 8462d6
                # $cur doesn't match cword?
Packit 8462d6
                "${cur:0:${#words[i]}}" != "${words[i]}"
Packit 8462d6
            ]]; do
Packit 8462d6
                # Strip first character
Packit 8462d6
                cur="${cur:1}"
Packit 8462d6
                # Decrease cursor position, staying >= 0
Packit 8462d6
                [[ $index -gt 0 ]] && ((index--))
Packit 8462d6
            done
Packit 8462d6
Packit 8462d6
            # Does found word matches cword?
Packit 8462d6
            if [[ "$i" -lt "$cword" ]]; then
Packit 8462d6
                # No, cword lies further;
Packit 8462d6
                local old_size="${#cur}"
Packit 8462d6
                cur="${cur#${words[i]}}"
Packit 8462d6
                local new_size="${#cur}"
Packit 8462d6
                index=$(( index - old_size + new_size ))
Packit 8462d6
            fi
Packit 8462d6
        done
Packit 8462d6
Packit 8462d6
        if [[ "${words[cword]:0:${#cur}}" != "$cur" ]]; then
Packit 8462d6
            # We messed up! At least return the whole word so things
Packit 8462d6
            # keep working
Packit 8462d6
            printf "%s" "${words[cword]}"
Packit 8462d6
        else
Packit 8462d6
            printf "%s" "${cur:0:$index}"
Packit 8462d6
        fi
Packit 8462d6
    fi
Packit 8462d6
} # _get_cword()
Packit 8462d6
Packit 8462d6
Packit 8462d6
# Get word previous to the current word.
Packit 8462d6
# This is a good alternative to `prev=${COMP_WORDS[COMP_CWORD-1]}' because bash4
Packit 8462d6
# will properly return the previous word with respect to any given exclusions to
Packit 8462d6
# COMP_WORDBREAKS.
Packit 8462d6
# @deprecated  Use `_get_comp_words_by_ref cur prev' instead
Packit 8462d6
# @see _get_comp_words_by_ref()
Packit 8462d6
#
Packit 8462d6
_get_pword()
Packit 8462d6
{
Packit 8462d6
    if [[ $COMP_CWORD -ge 1 ]]; then
Packit 8462d6
        _get_cword "${@:-}" 1
Packit 8462d6
    fi
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
Packit 8462d6
# If the word-to-complete contains a colon (:), left-trim COMPREPLY items with
Packit 8462d6
# word-to-complete.
Packit 8462d6
# With a colon in COMP_WORDBREAKS, words containing
Packit 8462d6
# colons are always completed as entire words if the word to complete contains
Packit 8462d6
# a colon.  This function fixes this, by removing the colon-containing-prefix
Packit 8462d6
# from COMPREPLY items.
Packit 8462d6
# The preferred solution is to remove the colon (:) from COMP_WORDBREAKS in
Packit 8462d6
# your .bashrc:
Packit 8462d6
#
Packit 8462d6
#    # Remove colon (:) from list of word completion separators
Packit 8462d6
#    COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
Packit 8462d6
#
Packit 8462d6
# See also: Bash FAQ - E13) Why does filename completion misbehave if a colon
Packit 8462d6
# appears in the filename? - http://tiswww.case.edu/php/chet/bash/FAQ
Packit 8462d6
# @param $1 current word to complete (cur)
Packit 8462d6
# @modifies global array $COMPREPLY
Packit 8462d6
#
Packit 8462d6
__ltrim_colon_completions()
Packit 8462d6
{
Packit 8462d6
    if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
Packit 8462d6
        # Remove colon-word prefix from COMPREPLY items
Packit 8462d6
        local colon_word=${1%"${1##*:}"}
Packit 8462d6
        local i=${#COMPREPLY[*]}
Packit 8462d6
        while [[ $((--i)) -ge 0 ]]; do
Packit 8462d6
            COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
Packit 8462d6
        done
Packit 8462d6
    fi
Packit 8462d6
} # __ltrim_colon_completions()
Packit 8462d6
Packit 8462d6
Packit 8462d6
# This function quotes the argument in a way so that readline dequoting
Packit 8462d6
# results in the original argument.  This is necessary for at least
Packit 8462d6
# `compgen' which requires its arguments quoted/escaped:
Packit 8462d6
#
Packit 8462d6
#     $ ls "a'b/"
Packit 8462d6
#     c
Packit 8462d6
#     $ compgen -f "a'b/"       # Wrong, doesn't return output
Packit 8462d6
#     $ compgen -f "a\'b/"      # Good
Packit 8462d6
#     a\'b/c
Packit 8462d6
#
Packit 8462d6
# See also:
Packit 8462d6
# - http://lists.gnu.org/archive/html/bug-bash/2009-03/msg00155.html
Packit 8462d6
# - http://www.mail-archive.com/bash-completion-devel@lists.alioth.\
Packit 8462d6
#   debian.org/msg01944.html
Packit 8462d6
# @param $1  Argument to quote
Packit 8462d6
# @param $2  Name of variable to return result to
Packit 8462d6
_quote_readline_by_ref()
Packit 8462d6
{
Packit 8462d6
    if [[ $1 == \'* ]]; then
Packit 8462d6
        # Leave out first character
Packit 8462d6
        printf -v $2 %s "${1:1}"
Packit 8462d6
    else
Packit 8462d6
        printf -v $2 %q "$1"
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    # If result becomes quoted like this: $'string', re-evaluate in order to
Packit 8462d6
    # drop the additional quoting.  See also: http://www.mail-archive.com/
Packit 8462d6
    # bash-completion-devel@lists.alioth.debian.org/msg01942.html
Packit 8462d6
    [[ ${!2} == \$* ]] && eval $2=${!2}
Packit 8462d6
} # _quote_readline_by_ref()
Packit 8462d6
Packit 8462d6
Packit 8462d6
# This function performs file and directory completion. It's better than
Packit 8462d6
# simply using 'compgen -f', because it honours spaces in filenames.
Packit 8462d6
# @param $1  If `-d', complete only on directories.  Otherwise filter/pick only
Packit 8462d6
#            completions with `.$1' and the uppercase version of it as file
Packit 8462d6
#            extension.
Packit 8462d6
#
Packit 8462d6
_filedir()
Packit 8462d6
{
Packit 8462d6
    local IFS=$'\n'
Packit 8462d6
Packit 8462d6
    _tilde "$cur" || return
Packit 8462d6
Packit 8462d6
    local -a toks
Packit 8462d6
    local x tmp
Packit 8462d6
Packit 8462d6
    x=$( compgen -d -- "$cur" ) &&
Packit 8462d6
    while read -r tmp; do
Packit 8462d6
        toks+=( "$tmp" )
Packit 8462d6
    done <<< "$x"
Packit 8462d6
Packit 8462d6
    if [[ "$1" != -d ]]; then
Packit 8462d6
        local quoted
Packit 8462d6
        _quote_readline_by_ref "$cur" quoted
Packit 8462d6
Packit 8462d6
        # Munge xspec to contain uppercase version too
Packit 8462d6
        # http://thread.gmane.org/gmane.comp.shells.bash.bugs/15294/focus=15306
Packit 8462d6
        local xspec=${1:+"!*.@($1|${1^^})"}
Packit 8462d6
        x=$( compgen -f -X "$xspec" -- $quoted ) &&
Packit 8462d6
        while read -r tmp; do
Packit 8462d6
            toks+=( "$tmp" )
Packit 8462d6
        done <<< "$x"
Packit 8462d6
Packit 8462d6
        # Try without filter if it failed to produce anything and configured to
Packit 8462d6
        [[ -n ${COMP_FILEDIR_FALLBACK:-} && -n "$1" && ${#toks[@]} -lt 1 ]] && \
Packit 8462d6
            x=$( compgen -f -- $quoted ) &&
Packit 8462d6
            while read -r tmp; do
Packit 8462d6
                toks+=( "$tmp" )
Packit 8462d6
            done <<< "$x"
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    if [[ ${#toks[@]} -ne 0 ]]; then
Packit 8462d6
        # 2>/dev/null for direct invocation, e.g. in the _filedir unit test
Packit 8462d6
        compopt -o filenames 2>/dev/null
Packit 8462d6
        COMPREPLY+=( "${toks[@]}" )
Packit 8462d6
    fi
Packit 8462d6
} # _filedir()
Packit 8462d6
Packit 8462d6
Packit 8462d6
# This function splits $cur=--foo=bar into $prev=--foo, $cur=bar, making it
Packit 8462d6
# easier to support both "--foo bar" and "--foo=bar" style completions.
Packit 8462d6
# `=' should have been removed from COMP_WORDBREAKS when setting $cur for
Packit 8462d6
# this to be useful.
Packit 8462d6
# Returns 0 if current option was split, 1 otherwise.
Packit 8462d6
#
Packit 8462d6
_split_longopt()
Packit 8462d6
{
Packit 8462d6
    if [[ "$cur" == --?*=* ]]; then
Packit 8462d6
        # Cut also backslash before '=' in case it ended up there
Packit 8462d6
        # for some reason.
Packit 8462d6
        prev="${cur%%?(\\)=*}"
Packit 8462d6
        cur="${cur#*=}"
Packit 8462d6
        return 0
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    return 1
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# Complete variables.
Packit 8462d6
# @return  True (0) if variables were completed,
Packit 8462d6
#          False (> 0) if not.
Packit 8462d6
_variables()
Packit 8462d6
{
Packit 8462d6
    if [[ $cur =~ ^(\$(\{[!#]?)?)([A-Za-z0-9_]*)$ ]]; then
Packit 8462d6
        # Completing $var / ${var / ${!var / ${#var
Packit 8462d6
        if [[ $cur == \${* ]]; then
Packit 8462d6
            local arrs vars
Packit 8462d6
            vars=( $( compgen -A variable -P ${BASH_REMATCH[1]} -S '}' -- ${BASH_REMATCH[3]} ) ) && \
Packit 8462d6
            arrs=( $( compgen -A arrayvar -P ${BASH_REMATCH[1]} -S '[' -- ${BASH_REMATCH[3]} ) )
Packit 8462d6
            if [[ ${#vars[@]} -eq 1 && $arrs ]]; then
Packit 8462d6
                # Complete ${arr with ${array[ if there is only one match, and that match is an array variable
Packit 8462d6
                compopt -o nospace
Packit 8462d6
                COMPREPLY+=( ${arrs[*]} )
Packit 8462d6
            else
Packit 8462d6
                # Complete ${var with ${variable}
Packit 8462d6
                COMPREPLY+=( ${vars[*]} )
Packit 8462d6
            fi
Packit 8462d6
        else
Packit 8462d6
            # Complete $var with $variable
Packit 8462d6
            COMPREPLY+=( $( compgen -A variable -P '$' -- "${BASH_REMATCH[3]}" ) )
Packit 8462d6
        fi
Packit 8462d6
        return 0
Packit 8462d6
    elif [[ $cur =~ ^(\$\{[#!]?)([A-Za-z0-9_]*)\[([^]]*)$ ]]; then
Packit 8462d6
        # Complete ${array[i with ${array[idx]}
Packit 8462d6
        local IFS=$'\n'
Packit 8462d6
        COMPREPLY+=( $( compgen -W '$(printf %s\\n "${!'${BASH_REMATCH[2]}'[@]}")' \
Packit 8462d6
            -P "${BASH_REMATCH[1]}${BASH_REMATCH[2]}[" -S ']}' -- "${BASH_REMATCH[3]}" ) )
Packit 8462d6
        # Complete ${arr[@ and ${arr[*
Packit 8462d6
        if [[ ${BASH_REMATCH[3]} == [@*] ]]; then
Packit 8462d6
            COMPREPLY+=( "${BASH_REMATCH[1]}${BASH_REMATCH[2]}[${BASH_REMATCH[3]}]}" )
Packit 8462d6
        fi
Packit 8462d6
        __ltrim_colon_completions "$cur"    # array indexes may have colons
Packit 8462d6
        return 0
Packit 8462d6
    elif [[ $cur =~ ^\$\{[#!]?[A-Za-z0-9_]*\[.*\]$ ]]; then
Packit 8462d6
        # Complete ${array[idx] with ${array[idx]}
Packit 8462d6
        COMPREPLY+=( "$cur}" )
Packit 8462d6
        __ltrim_colon_completions "$cur"
Packit 8462d6
        return 0
Packit 8462d6
    else
Packit 8462d6
        case $prev in
Packit 8462d6
            TZ)
Packit 8462d6
                cur=/usr/share/zoneinfo/$cur
Packit 8462d6
                _filedir
Packit 8462d6
                for i in ${!COMPREPLY[@]}; do
Packit 8462d6
                    if [[ ${COMPREPLY[i]} == *.tab ]]; then
Packit 8462d6
                        unset 'COMPREPLY[i]'
Packit 8462d6
                        continue
Packit 8462d6
                    elif [[ -d ${COMPREPLY[i]} ]]; then
Packit 8462d6
                        COMPREPLY[i]+=/
Packit 8462d6
                        compopt -o nospace
Packit 8462d6
                    fi
Packit 8462d6
                    COMPREPLY[i]=${COMPREPLY[i]#/usr/share/zoneinfo/}
Packit 8462d6
                done
Packit 8462d6
                return 0
Packit 8462d6
                ;;
Packit 8462d6
        esac
Packit 8462d6
    fi
Packit 8462d6
    return 1
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# Initialize completion and deal with various general things: do file
Packit 8462d6
# and variable completion where appropriate, and adjust prev, words,
Packit 8462d6
# and cword as if no redirections exist so that completions do not
Packit 8462d6
# need to deal with them.  Before calling this function, make sure
Packit 8462d6
# cur, prev, words, and cword are local, ditto split if you use -s.
Packit 8462d6
#
Packit 8462d6
# Options:
Packit 8462d6
#     -n EXCLUDE  Passed to _get_comp_words_by_ref -n with redirection chars
Packit 8462d6
#     -e XSPEC    Passed to _filedir as first arg for stderr redirections
Packit 8462d6
#     -o XSPEC    Passed to _filedir as first arg for other output redirections
Packit 8462d6
#     -i XSPEC    Passed to _filedir as first arg for stdin redirections
Packit 8462d6
#     -s          Split long options with _split_longopt, implies -n =
Packit 8462d6
# @return  True (0) if completion needs further processing,
Packit 8462d6
#          False (> 0) no further processing is necessary.
Packit 8462d6
#
Packit 8462d6
_init_completion()
Packit 8462d6
{
Packit 8462d6
    local exclude= flag outx errx inx OPTIND=1
Packit 8462d6
Packit 8462d6
    while getopts "n:e:o:i:s" flag "$@"; do
Packit 8462d6
        case $flag in
Packit 8462d6
            n) exclude+=$OPTARG ;;
Packit 8462d6
            e) errx=$OPTARG ;;
Packit 8462d6
            o) outx=$OPTARG ;;
Packit 8462d6
            i) inx=$OPTARG ;;
Packit 8462d6
            s) split=false ; exclude+== ;;
Packit 8462d6
        esac
Packit 8462d6
    done
Packit 8462d6
Packit 8462d6
    # For some reason completion functions are not invoked at all by
Packit 8462d6
    # bash (at least as of 4.1.7) after the command line contains an
Packit 8462d6
    # ampersand so we don't get a chance to deal with redirections
Packit 8462d6
    # containing them, but if we did, hopefully the below would also
Packit 8462d6
    # do the right thing with them...
Packit 8462d6
Packit 8462d6
    COMPREPLY=()
Packit 8462d6
    local redir="@(?([0-9])<|?([0-9&])>?(>)|>&)"
Packit 8462d6
    _get_comp_words_by_ref -n "$exclude<>&" cur prev words cword
Packit 8462d6
Packit 8462d6
    # Complete variable names.
Packit 8462d6
    _variables && return 1
Packit 8462d6
Packit 8462d6
    # Complete on files if current is a redirect possibly followed by a
Packit 8462d6
    # filename, e.g. ">foo", or previous is a "bare" redirect, e.g. ">".
Packit 8462d6
    if [[ $cur == $redir* || $prev == $redir ]]; then
Packit 8462d6
        local xspec
Packit 8462d6
        case $cur in
Packit 8462d6
            2'>'*) xspec=$errx ;;
Packit 8462d6
            *'>'*) xspec=$outx ;;
Packit 8462d6
            *'<'*) xspec=$inx ;;
Packit 8462d6
            *)
Packit 8462d6
                case $prev in
Packit 8462d6
                    2'>'*) xspec=$errx ;;
Packit 8462d6
                    *'>'*) xspec=$outx ;;
Packit 8462d6
                    *'<'*) xspec=$inx ;;
Packit 8462d6
                esac
Packit 8462d6
                ;;
Packit 8462d6
        esac
Packit 8462d6
        cur="${cur##$redir}"
Packit 8462d6
        _filedir $xspec
Packit 8462d6
        return 1
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    # Remove all redirections so completions don't have to deal with them.
Packit 8462d6
    local i skip
Packit 8462d6
    for (( i=1; i < ${#words[@]}; )); do
Packit 8462d6
        if [[ ${words[i]} == $redir* ]]; then
Packit 8462d6
            # If "bare" redirect, remove also the next word (skip=2).
Packit 8462d6
            [[ ${words[i]} == $redir ]] && skip=2 || skip=1
Packit 8462d6
            words=( "${words[@]:0:i}" "${words[@]:i+skip}" )
Packit 8462d6
            [[ $i -le $cword ]] && cword=$(( cword - skip ))
Packit 8462d6
        else
Packit 8462d6
            i=$(( ++i ))
Packit 8462d6
        fi
Packit 8462d6
    done
Packit 8462d6
Packit 8462d6
    [[ $cword -le 0 ]] && return 1
Packit 8462d6
    prev=${words[cword-1]}
Packit 8462d6
Packit 8462d6
    [[ ${split-} ]] && _split_longopt && split=true
Packit 8462d6
Packit 8462d6
    return 0
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# Helper function for _parse_help and _parse_usage.
Packit 8462d6
__parse_options()
Packit 8462d6
{
Packit 8462d6
    local option option2 i IFS=$' \t\n,/|'
Packit 8462d6
Packit 8462d6
    # Take first found long option, or first one (short) if not found.
Packit 8462d6
    option=
Packit 8462d6
    local -a array
Packit 8462d6
    read -a array <<<"$1"
Packit 8462d6
    for i in "${array[@]}"; do
Packit 8462d6
        case "$i" in
Packit 8462d6
            ---*) break ;;
Packit 8462d6
            --?*) option=$i ; break ;;
Packit 8462d6
            -?*)  [[ $option ]] || option=$i ;;
Packit 8462d6
            *)    break ;;
Packit 8462d6
        esac
Packit 8462d6
    done
Packit 8462d6
    [[ $option ]] || return
Packit 8462d6
Packit 8462d6
    IFS=$' \t\n' # affects parsing of the regexps below...
Packit 8462d6
Packit 8462d6
    # Expand --[no]foo to --foo and --nofoo etc
Packit 8462d6
    if [[ $option =~ (\[((no|dont)-?)\]). ]]; then
Packit 8462d6
        option2=${option/"${BASH_REMATCH[1]}"/}
Packit 8462d6
        option2=${option2%%[<{().[]*}
Packit 8462d6
        printf '%s\n' "${option2/=*/=}"
Packit 8462d6
        option=${option/"${BASH_REMATCH[1]}"/"${BASH_REMATCH[2]}"}
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    option=${option%%[<{().[]*}
Packit 8462d6
    printf '%s\n' "${option/=*/=}"
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# Parse GNU style help output of the given command.
Packit 8462d6
# @param $1  command; if "-", read from stdin and ignore rest of args
Packit 8462d6
# @param $2  command options (default: --help)
Packit 8462d6
#
Packit 8462d6
_parse_help()
Packit 8462d6
{
Packit 8462d6
    eval local cmd=$( quote "$1" )
Packit 8462d6
    local line
Packit 8462d6
    { case $cmd in
Packit 8462d6
        -) cat ;;
Packit 8462d6
        *) LC_ALL=C "$( dequote "$cmd" )" ${2:---help} 2>&1 ;;
Packit 8462d6
      esac } \
Packit 8462d6
    | while read -r line; do
Packit 8462d6
Packit 8462d6
        [[ $line == *([[:blank:]])-* ]] || continue
Packit 8462d6
        # transform "-f FOO, --foo=FOO" to "-f , --foo=FOO" etc
Packit 8462d6
        while [[ $line =~ \
Packit 8462d6
            ((^|[^-])-[A-Za-z0-9?][[:space:]]+)\[?[A-Z0-9]+\]? ]]; do
Packit 8462d6
            line=${line/"${BASH_REMATCH[0]}"/"${BASH_REMATCH[1]}"}
Packit 8462d6
        done
Packit 8462d6
        __parse_options "${line// or /, }"
Packit 8462d6
Packit 8462d6
    done
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# Parse BSD style usage output (options in brackets) of the given command.
Packit 8462d6
# @param $1  command; if "-", read from stdin and ignore rest of args
Packit 8462d6
# @param $2  command options (default: --usage)
Packit 8462d6
#
Packit 8462d6
_parse_usage()
Packit 8462d6
{
Packit 8462d6
    eval local cmd=$( quote "$1" )
Packit 8462d6
    local line match option i char
Packit 8462d6
    { case $cmd in
Packit 8462d6
        -) cat ;;
Packit 8462d6
        *) LC_ALL=C "$( dequote "$cmd" )" ${2:---usage} 2>&1 ;;
Packit 8462d6
      esac } \
Packit 8462d6
    | while read -r line; do
Packit 8462d6
Packit 8462d6
        while [[ $line =~ \[[[:space:]]*(-[^]]+)[[:space:]]*\] ]]; do
Packit 8462d6
            match=${BASH_REMATCH[0]}
Packit 8462d6
            option=${BASH_REMATCH[1]}
Packit 8462d6
            case $option in
Packit 8462d6
                -?(\[)+([a-zA-Z0-9?]))
Packit 8462d6
                    # Treat as bundled short options
Packit 8462d6
                    for (( i=1; i < ${#option}; i++ )); do
Packit 8462d6
                        char=${option:i:1}
Packit 8462d6
                        [[ $char != '[' ]] && printf '%s\n' -$char
Packit 8462d6
                    done
Packit 8462d6
                    ;;
Packit 8462d6
                *)
Packit 8462d6
                    __parse_options "$option"
Packit 8462d6
                    ;;
Packit 8462d6
            esac
Packit 8462d6
            line=${line#*"$match"}
Packit 8462d6
        done
Packit 8462d6
Packit 8462d6
    done
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on signal names (minus the SIG prefix)
Packit 8462d6
# @param $1 prefix
Packit 8462d6
_signals()
Packit 8462d6
{
Packit 8462d6
    local -a sigs=( $( compgen -P "$1" -A signal "SIG${cur#$1}" ) )
Packit 8462d6
    COMPREPLY+=( "${sigs[@]/#${1}SIG/${1}}" )
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on known mac addresses
Packit 8462d6
#
Packit 8462d6
_mac_addresses()
Packit 8462d6
{
Packit 8462d6
    local re='\([A-Fa-f0-9]\{2\}:\)\{5\}[A-Fa-f0-9]\{2\}'
Packit 8462d6
    local PATH="$PATH:/sbin:/usr/sbin"
Packit 8462d6
Packit 8462d6
    # Local interfaces
Packit 8462d6
    # - ifconfig on Linux: HWaddr or ether
Packit 8462d6
    # - ifconfig on FreeBSD: ether
Packit 8462d6
    # - ip link: link/ether
Packit 8462d6
    COMPREPLY+=( $( \
Packit 8462d6
        { LC_ALL=C ifconfig -a || ip link show; } 2>/dev/null | command sed -ne \
Packit 8462d6
        "s/.*[[:space:]]HWaddr[[:space:]]\{1,\}\($re\)[[:space:]].*/\1/p" -ne \
Packit 8462d6
        "s/.*[[:space:]]HWaddr[[:space:]]\{1,\}\($re\)[[:space:]]*$/\1/p" -ne \
Packit 8462d6
        "s|.*[[:space:]]\(link/\)\{0,1\}ether[[:space:]]\{1,\}\($re\)[[:space:]].*|\2|p" -ne \
Packit 8462d6
        "s|.*[[:space:]]\(link/\)\{0,1\}ether[[:space:]]\{1,\}\($re\)[[:space:]]*$|\2|p"
Packit 8462d6
        ) )
Packit 8462d6
Packit 8462d6
    # ARP cache
Packit 8462d6
    COMPREPLY+=( $( { arp -an || ip neigh show; } 2>/dev/null | command sed -ne \
Packit 8462d6
        "s/.*[[:space:]]\($re\)[[:space:]].*/\1/p" -ne \
Packit 8462d6
        "s/.*[[:space:]]\($re\)[[:space:]]*$/\1/p" ) )
Packit 8462d6
Packit 8462d6
    # /etc/ethers
Packit 8462d6
    COMPREPLY+=( $( command sed -ne \
Packit 8462d6
        "s/^[[:space:]]*\($re\)[[:space:]].*/\1/p" /etc/ethers 2>/dev/null ) )
Packit 8462d6
Packit 8462d6
    COMPREPLY=( $( compgen -W '${COMPREPLY[@]}' -- "$cur" ) )
Packit 8462d6
    __ltrim_colon_completions "$cur"
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on configured network interfaces
Packit 8462d6
#
Packit 8462d6
_configured_interfaces()
Packit 8462d6
{
Packit 8462d6
    if [[ -f /etc/debian_version ]]; then
Packit 8462d6
        # Debian system
Packit 8462d6
        COMPREPLY=( $( compgen -W "$( command sed -ne 's|^iface \([^ ]\{1,\}\).*$|\1|p'\
Packit 8462d6
            /etc/network/interfaces /etc/network/interfaces.d/* 2>/dev/null )" \
Packit 8462d6
            -- "$cur" ) )
Packit 8462d6
    elif [[ -f /etc/SuSE-release ]]; then
Packit 8462d6
        # SuSE system
Packit 8462d6
        COMPREPLY=( $( compgen -W "$( printf '%s\n' \
Packit 8462d6
            /etc/sysconfig/network/ifcfg-* | \
Packit 8462d6
            command sed -ne 's|.*ifcfg-\([^*].*\)$|\1|p' )" -- "$cur" ) )
Packit 8462d6
    elif [[ -f /etc/pld-release ]]; then
Packit 8462d6
        # PLD Linux
Packit 8462d6
        COMPREPLY=( $( compgen -W "$( command ls -B \
Packit 8462d6
            /etc/sysconfig/interfaces | \
Packit 8462d6
            command sed -ne 's|.*ifcfg-\([^*].*\)$|\1|p' )" -- "$cur" ) )
Packit 8462d6
    else
Packit 8462d6
        # Assume Red Hat
Packit 8462d6
        COMPREPLY=( $( compgen -W "$( printf '%s\n' \
Packit 8462d6
            /etc/sysconfig/network-scripts/ifcfg-* | \
Packit 8462d6
            command sed -ne 's|.*ifcfg-\([^*].*\)$|\1|p' )" -- "$cur" ) )
Packit 8462d6
    fi
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# Local IP addresses.
Packit 8462d6
#
Packit 8462d6
_ip_addresses()
Packit 8462d6
{
Packit 8462d6
    local PATH=$PATH:/sbin
Packit 8462d6
    COMPREPLY+=( $( compgen -W \
Packit 8462d6
        "$( { LC_ALL=C ifconfig -a || ip addr show; } 2>/dev/null | command sed -ne \
Packit 8462d6
            's/.*addr:\([^[:space:]]*\).*/\1/p' -ne \
Packit 8462d6
            's|.*inet[[:space:]]\{1,\}\([^[:space:]/]*\).*|\1|p' )" \
Packit 8462d6
        -- "$cur" ) )
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on available kernels
Packit 8462d6
#
Packit 8462d6
_kernel_versions()
Packit 8462d6
{
Packit 8462d6
    COMPREPLY=( $( compgen -W '$( command ls /lib/modules )' -- "$cur" ) )
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on all available network interfaces
Packit 8462d6
# -a: restrict to active interfaces only
Packit 8462d6
# -w: restrict to wireless interfaces only
Packit 8462d6
#
Packit 8462d6
_available_interfaces()
Packit 8462d6
{
Packit 8462d6
    local cmd PATH=$PATH:/sbin
Packit 8462d6
Packit 8462d6
    if [[ ${1:-} == -w ]]; then
Packit 8462d6
        cmd="iwconfig"
Packit 8462d6
    elif [[ ${1:-} == -a ]]; then
Packit 8462d6
        cmd="{ ifconfig || ip link show up; }"
Packit 8462d6
    else
Packit 8462d6
        cmd="{ ifconfig -a || ip link show; }"
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    COMPREPLY=( $( eval $cmd 2>/dev/null | awk \
Packit 8462d6
        '/^[^ \t]/ { if ($1 ~ /^[0-9]+:/) { print $2 } else { print $1 } }' ) )
Packit 8462d6
    COMPREPLY=( $( compgen -W '${COMPREPLY[@]/%[[:punct:]]/}' -- "$cur" ) )
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# Echo number of CPUs, falling back to 1 on failure.
Packit 8462d6
_ncpus()
Packit 8462d6
{
Packit 8462d6
    local var=NPROCESSORS_ONLN
Packit 8462d6
    [[ $OSTYPE == *linux* ]] && var=_$var
Packit 8462d6
    local n=$( getconf $var 2>/dev/null )
Packit 8462d6
    printf %s ${n:-1}
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# Perform tilde (~) completion
Packit 8462d6
# @return  True (0) if completion needs further processing,
Packit 8462d6
#          False (> 0) if tilde is followed by a valid username, completions
Packit 8462d6
#          are put in COMPREPLY and no further processing is necessary.
Packit 8462d6
_tilde()
Packit 8462d6
{
Packit 8462d6
    local result=0
Packit 8462d6
    if [[ $1 == \~* && $1 != */* ]]; then
Packit 8462d6
        # Try generate ~username completions
Packit 8462d6
        COMPREPLY=( $( compgen -P '~' -u -- "${1#\~}" ) )
Packit 8462d6
        result=${#COMPREPLY[@]}
Packit 8462d6
        # 2>/dev/null for direct invocation, e.g. in the _tilde unit test
Packit 8462d6
        [[ $result -gt 0 ]] && compopt -o filenames 2>/dev/null
Packit 8462d6
    fi
Packit 8462d6
    return $result
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
Packit 8462d6
# Expand variable starting with tilde (~)
Packit 8462d6
# We want to expand ~foo/... to /home/foo/... to avoid problems when
Packit 8462d6
# word-to-complete starting with a tilde is fed to commands and ending up
Packit 8462d6
# quoted instead of expanded.
Packit 8462d6
# Only the first portion of the variable from the tilde up to the first slash
Packit 8462d6
# (~../) is expanded.  The remainder of the variable, containing for example
Packit 8462d6
# a dollar sign variable ($) or asterisk (*) is not expanded.
Packit 8462d6
# Example usage:
Packit 8462d6
#
Packit 8462d6
#    $ v="~"; __expand_tilde_by_ref v; echo "$v"
Packit 8462d6
#
Packit 8462d6
# Example output:
Packit 8462d6
#
Packit 8462d6
#       v                  output
Packit 8462d6
#    --------         ----------------
Packit 8462d6
#    ~                /home/user
Packit 8462d6
#    ~foo/bar         /home/foo/bar
Packit 8462d6
#    ~foo/$HOME       /home/foo/$HOME
Packit 8462d6
#    ~foo/a  b        /home/foo/a  b
Packit 8462d6
#    ~foo/*           /home/foo/*
Packit 8462d6
#
Packit 8462d6
# @param $1  Name of variable (not the value of the variable) to expand
Packit 8462d6
__expand_tilde_by_ref()
Packit 8462d6
{
Packit 8462d6
    # Does $1 start with tilde (~)?
Packit 8462d6
    if [[ ${!1} == \~* ]]; then
Packit 8462d6
        # Does $1 contain slash (/)?
Packit 8462d6
        if [[ ${!1} == */* ]]; then
Packit 8462d6
            # Yes, $1 contains slash;
Packit 8462d6
            # 1: Remove * including and after first slash (/), i.e. "~a/b"
Packit 8462d6
            #    becomes "~a".  Double quotes allow eval.
Packit 8462d6
            # 2: Remove * before the first slash (/), i.e. "~a/b"
Packit 8462d6
            #    becomes "b".  Single quotes prevent eval.
Packit 8462d6
            #       +-----1----+ +---2----+
Packit 8462d6
            eval $1="${!1/%\/*}"/'${!1#*/}'
Packit 8462d6
        else
Packit 8462d6
            # No, $1 doesn't contain slash
Packit 8462d6
            eval $1="${!1}"
Packit 8462d6
        fi
Packit 8462d6
    fi
Packit 8462d6
} # __expand_tilde_by_ref()
Packit 8462d6
Packit 8462d6
Packit 8462d6
# This function expands tildes in pathnames
Packit 8462d6
#
Packit 8462d6
_expand()
Packit 8462d6
{
Packit 8462d6
    # FIXME: Why was this here?
Packit 8462d6
    #[ "$cur" != "${cur%\\}" ] && cur+="\\"
Packit 8462d6
Packit 8462d6
    # Expand ~username type directory specifications.  We want to expand
Packit 8462d6
    # ~foo/... to /home/foo/... to avoid problems when $cur starting with
Packit 8462d6
    # a tilde is fed to commands and ending up quoted instead of expanded.
Packit 8462d6
Packit 8462d6
    if [[ "$cur" == \~*/* ]]; then
Packit 8462d6
        eval cur=$cur 2>/dev/null
Packit 8462d6
    elif [[ "$cur" == \~* ]]; then
Packit 8462d6
        cur=${cur#\~}
Packit 8462d6
        COMPREPLY=( $( compgen -P '~' -u -- "$cur" ) )
Packit 8462d6
        [[ ${#COMPREPLY[@]} -eq 1 ]] && eval COMPREPLY[0]=${COMPREPLY[0]}
Packit 8462d6
        return ${#COMPREPLY[@]}
Packit 8462d6
    fi
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on process IDs.
Packit 8462d6
# AIX and Solaris ps prefers X/Open syntax.
Packit 8462d6
[[ $OSTYPE == *@(solaris|aix)* ]] &&
Packit 8462d6
_pids()
Packit 8462d6
{
Packit 8462d6
    COMPREPLY=( $( compgen -W '$( command ps -efo pid | command sed 1d )' -- "$cur" ))
Packit 8462d6
} ||
Packit 8462d6
_pids()
Packit 8462d6
{
Packit 8462d6
    COMPREPLY=( $( compgen -W '$( command ps axo pid= )' -- "$cur" ) )
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on process group IDs.
Packit 8462d6
# AIX and SunOS prefer X/Open, all else should be BSD.
Packit 8462d6
[[ $OSTYPE == *@(solaris|aix)* ]] &&
Packit 8462d6
_pgids()
Packit 8462d6
{
Packit 8462d6
    COMPREPLY=( $( compgen -W '$( command ps -efo pgid | command sed 1d )' -- "$cur" ))
Packit 8462d6
} ||
Packit 8462d6
_pgids()
Packit 8462d6
{
Packit 8462d6
    COMPREPLY=( $( compgen -W '$( command ps axo pgid= )' -- "$cur" ))
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on process names.
Packit 8462d6
# AIX and SunOS prefer X/Open, all else should be BSD.
Packit 8462d6
# @param $1 if -s, don't try to avoid truncated command names
Packit 8462d6
[[ $OSTYPE == *@(solaris|aix)* ]] &&
Packit 8462d6
_pnames()
Packit 8462d6
{
Packit 8462d6
    COMPREPLY=( $( compgen -X '<defunct>' -W '$( command ps -efo comm | \
Packit 8462d6
        command sed -e 1d -e "s:.*/::" -e "s/^-//" | sort -u )' -- "$cur" ) )
Packit 8462d6
} ||
Packit 8462d6
_pnames()
Packit 8462d6
{
Packit 8462d6
    if [[ "$1" == -s ]]; then
Packit 8462d6
        COMPREPLY=( $( compgen -X '<defunct>' \
Packit 8462d6
            -W '$( command ps axo comm | command sed -e 1d )' -- "$cur" ) )
Packit 8462d6
    else
Packit 8462d6
        # FIXME: completes "[kblockd/0]" to "0". Previously it was completed
Packit 8462d6
        # to "kblockd" which isn't correct either. "kblockd/0" would be
Packit 8462d6
        # arguably most correct, but killall from psmisc 22 treats arguments
Packit 8462d6
        # containing "/" specially unless -r is given so that wouldn't quite
Packit 8462d6
        # work either. Perhaps it'd be best to not complete these to anything
Packit 8462d6
        # for now.
Packit 8462d6
        COMPREPLY=( $( compgen -X '<defunct>' -W '$( command ps axo command= | command sed -e \
Packit 8462d6
            "s/ .*//" -e \
Packit 8462d6
            "s:.*/::" -e \
Packit 8462d6
            "s/:$//" -e \
Packit 8462d6
            "s/^[[(-]//" -e \
Packit 8462d6
            "s/[])]$//" | sort -u )' -- "$cur" ) )
Packit 8462d6
    fi
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on user IDs
Packit 8462d6
#
Packit 8462d6
_uids()
Packit 8462d6
{
Packit 8462d6
    if type getent &>/dev/null; then
Packit 8462d6
        COMPREPLY=( $( compgen -W '$( getent passwd | cut -d: -f3 )' -- "$cur" ) )
Packit 8462d6
    elif type perl &>/dev/null; then
Packit 8462d6
        COMPREPLY=( $( compgen -W '$( perl -e '"'"'while (($uid) = (getpwent)[2]) { print $uid . "\n" }'"'"' )' -- "$cur" ) )
Packit 8462d6
    else
Packit 8462d6
        # make do with /etc/passwd
Packit 8462d6
        COMPREPLY=( $( compgen -W '$( cut -d: -f3 /etc/passwd )' -- "$cur" ) )
Packit 8462d6
    fi
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on group IDs
Packit 8462d6
#
Packit 8462d6
_gids()
Packit 8462d6
{
Packit 8462d6
    if type getent &>/dev/null; then
Packit 8462d6
        COMPREPLY=( $( compgen -W '$( getent group | cut -d: -f3 )' \
Packit 8462d6
            -- "$cur" ) )
Packit 8462d6
    elif type perl &>/dev/null; then
Packit 8462d6
        COMPREPLY=( $( compgen -W '$( perl -e '"'"'while (($gid) = (getgrent)[2]) { print $gid . "\n" }'"'"' )' -- "$cur" ) )
Packit 8462d6
    else
Packit 8462d6
        # make do with /etc/group
Packit 8462d6
        COMPREPLY=( $( compgen -W '$( cut -d: -f3 /etc/group )' -- "$cur" ) )
Packit 8462d6
    fi
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# Glob for matching various backup files.
Packit 8462d6
#
Packit 8462d6
_backup_glob='@(#*#|*@(~|.@(bak|orig|rej|swp|dpkg*|rpm@(orig|new|save))))'
Packit 8462d6
Packit 8462d6
# Complete on xinetd services
Packit 8462d6
#
Packit 8462d6
_xinetd_services()
Packit 8462d6
{
Packit 8462d6
    local xinetddir=/etc/xinetd.d
Packit 8462d6
    if [[ -d $xinetddir ]]; then
Packit 8462d6
        local restore_nullglob=$(shopt -p nullglob); shopt -s nullglob
Packit 8462d6
        local -a svcs=( $( printf '%s\n' $xinetddir/!($_backup_glob) ) )
Packit 8462d6
        $restore_nullglob
Packit 8462d6
        COMPREPLY+=( $( compgen -W '${svcs[@]#$xinetddir/}' -- "$cur" ) )
Packit 8462d6
    fi
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on services
Packit 8462d6
#
Packit 8462d6
_services()
Packit 8462d6
{
Packit 8462d6
    local sysvdirs
Packit 8462d6
    _sysvdirs
Packit 8462d6
Packit 8462d6
    local restore_nullglob=$(shopt -p nullglob); shopt -s nullglob
Packit 8462d6
    COMPREPLY=( \
Packit 8462d6
        $( printf '%s\n' ${sysvdirs[0]}/!($_backup_glob|functions|README) ) )
Packit 8462d6
    $restore_nullglob
Packit 8462d6
Packit 8462d6
    COMPREPLY+=( $( systemctl list-units --full --all 2>/dev/null | \
Packit 8462d6
        awk '$1 ~ /\.service$/ { sub("\\.service$", "", $1); print $1 }' ) )
Packit 8462d6
Packit 8462d6
    if [[ -x /sbin/upstart-udev-bridge ]]; then
Packit 8462d6
        COMPREPLY+=( $( initctl list 2>/dev/null | cut -d' ' -f1 ) )
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    COMPREPLY=( $( compgen -W '${COMPREPLY[@]#${sysvdirs[0]}/}' -- "$cur" ) )
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This completes on a list of all available service scripts for the
Packit 8462d6
# 'service' command and/or the SysV init.d directory, followed by
Packit 8462d6
# that script's available commands
Packit 8462d6
#
Packit 8462d6
_service()
Packit 8462d6
{
Packit 8462d6
    local cur prev words cword
Packit 8462d6
    _init_completion || return
Packit 8462d6
Packit 8462d6
    # don't complete past 2nd token
Packit 8462d6
    [[ $cword -gt 2 ]] && return
Packit 8462d6
Packit 8462d6
    if [[ $cword -eq 1 && $prev == ?(*/)service ]]; then
Packit 8462d6
        _services
Packit 8462d6
        [[ -e /etc/mandrake-release ]] && _xinetd_services
Packit 8462d6
    else
Packit 8462d6
        local sysvdirs
Packit 8462d6
        _sysvdirs
Packit 8462d6
        COMPREPLY=( $( compgen -W '`command sed -e "y/|/ /" \
Packit 8462d6
            -ne "s/^.*\(U\|msg_u\)sage.*{\(.*\)}.*$/\2/p" \
Packit 8462d6
            ${sysvdirs[0]}/${prev##*/} 2>/dev/null` start stop' -- "$cur" ) )
Packit 8462d6
    fi
Packit 8462d6
} &&
Packit 8462d6
complete -F _service service
Packit 8462d6
_sysvdirs
Packit 8462d6
for svcdir in ${sysvdirs[@]}; do
Packit 8462d6
    for svc in $svcdir/!($_backup_glob); do
Packit 8462d6
        [[ -x $svc ]] && complete -F _service $svc
Packit 8462d6
    done
Packit 8462d6
done
Packit 8462d6
unset svc svcdir sysvdirs
Packit 8462d6
Packit 8462d6
# This function completes on modules
Packit 8462d6
#
Packit 8462d6
_modules()
Packit 8462d6
{
Packit 8462d6
    local modpath
Packit 8462d6
    modpath=/lib/modules/$1
Packit 8462d6
    COMPREPLY=( $( compgen -W "$( command ls -RL $modpath 2>/dev/null | \
Packit 8462d6
        command sed -ne 's/^\(.*\)\.k\{0,1\}o\(\.[gx]z\)\{0,1\}$/\1/p' )" -- "$cur" ) )
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on installed modules
Packit 8462d6
#
Packit 8462d6
_installed_modules()
Packit 8462d6
{
Packit 8462d6
    COMPREPLY=( $( compgen -W "$( PATH="$PATH:/sbin" lsmod | \
Packit 8462d6
        awk '{if (NR != 1) print $1}' )" -- "$1" ) )
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on user or user:group format; as for chown and cpio.
Packit 8462d6
#
Packit 8462d6
# The : must be added manually; it will only complete usernames initially.
Packit 8462d6
# The legacy user.group format is not supported.
Packit 8462d6
#
Packit 8462d6
# @param $1  If -u, only return users/groups the user has access to in
Packit 8462d6
#            context of current completion.
Packit 8462d6
_usergroup()
Packit 8462d6
{
Packit 8462d6
    if [[ $cur == *\\\\* || $cur == *:*:* ]]; then
Packit 8462d6
        # Give up early on if something seems horribly wrong.
Packit 8462d6
        return
Packit 8462d6
    elif [[ $cur == *\\:* ]]; then
Packit 8462d6
        # Completing group after 'user\:gr<TAB>'.
Packit 8462d6
        # Reply with a list of groups prefixed with 'user:', readline will
Packit 8462d6
        # escape to the colon.
Packit 8462d6
        local prefix
Packit 8462d6
        prefix=${cur%%*([^:])}
Packit 8462d6
        prefix=${prefix//\\}
Packit 8462d6
        local mycur="${cur#*[:]}"
Packit 8462d6
        if [[ $1 == -u ]]; then
Packit 8462d6
            _allowed_groups "$mycur"
Packit 8462d6
        else
Packit 8462d6
            local IFS=$'\n'
Packit 8462d6
            COMPREPLY=( $( compgen -g -- "$mycur" ) )
Packit 8462d6
        fi
Packit 8462d6
        COMPREPLY=( $( compgen -P "$prefix" -W "${COMPREPLY[@]}" ) )
Packit 8462d6
    elif [[ $cur == *:* ]]; then
Packit 8462d6
        # Completing group after 'user:gr<TAB>'.
Packit 8462d6
        # Reply with a list of unprefixed groups since readline with split on :
Packit 8462d6
        # and only replace the 'gr' part
Packit 8462d6
        local mycur="${cur#*:}"
Packit 8462d6
        if [[ $1 == -u ]]; then
Packit 8462d6
            _allowed_groups "$mycur"
Packit 8462d6
        else
Packit 8462d6
            local IFS=$'\n'
Packit 8462d6
            COMPREPLY=( $( compgen -g -- "$mycur" ) )
Packit 8462d6
        fi
Packit 8462d6
    else
Packit 8462d6
        # Completing a partial 'usernam<TAB>'.
Packit 8462d6
        #
Packit 8462d6
        # Don't suffix with a : because readline will escape it and add a
Packit 8462d6
        # slash. It's better to complete into 'chown username ' than 'chown
Packit 8462d6
        # username\:'.
Packit 8462d6
        if [[ $1 == -u ]]; then
Packit 8462d6
            _allowed_users "$cur"
Packit 8462d6
        else
Packit 8462d6
            local IFS=$'\n'
Packit 8462d6
            COMPREPLY=( $( compgen -u -- "$cur" ) )
Packit 8462d6
        fi
Packit 8462d6
    fi
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
_allowed_users()
Packit 8462d6
{
Packit 8462d6
    if _complete_as_root; then
Packit 8462d6
        local IFS=$'\n'
Packit 8462d6
        COMPREPLY=( $( compgen -u -- "${1:-$cur}" ) )
Packit 8462d6
    else
Packit 8462d6
        local IFS=$'\n '
Packit 8462d6
        COMPREPLY=( $( compgen -W \
Packit 8462d6
            "$( id -un 2>/dev/null || whoami 2>/dev/null )" -- "${1:-$cur}" ) )
Packit 8462d6
    fi
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
_allowed_groups()
Packit 8462d6
{
Packit 8462d6
    if _complete_as_root; then
Packit 8462d6
        local IFS=$'\n'
Packit 8462d6
        COMPREPLY=( $( compgen -g -- "$1" ) )
Packit 8462d6
    else
Packit 8462d6
        local IFS=$'\n '
Packit 8462d6
        COMPREPLY=( $( compgen -W \
Packit 8462d6
            "$( id -Gn 2>/dev/null || groups 2>/dev/null )" -- "$1" ) )
Packit 8462d6
    fi
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on valid shells
Packit 8462d6
#
Packit 8462d6
_shells()
Packit 8462d6
{
Packit 8462d6
    local shell rest
Packit 8462d6
    while read -r shell rest; do
Packit 8462d6
        [[ $shell == /* && $shell == "$cur"* ]] && COMPREPLY+=( $shell )
Packit 8462d6
    done 2>/dev/null < /etc/shells
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on valid filesystem types
Packit 8462d6
#
Packit 8462d6
_fstypes()
Packit 8462d6
{
Packit 8462d6
    local fss
Packit 8462d6
Packit 8462d6
    if [[ -e /proc/filesystems ]]; then
Packit 8462d6
        # Linux
Packit 8462d6
        fss="$( cut -d$'\t' -f2 /proc/filesystems )
Packit 8462d6
            $( awk '! /\*/ { print $NF }' /etc/filesystems 2>/dev/null )"
Packit 8462d6
    else
Packit 8462d6
        # Generic
Packit 8462d6
        fss="$( awk '/^[ \t]*[^#]/ { print $3 }' /etc/fstab 2>/dev/null )
Packit 8462d6
            $( awk '/^[ \t]*[^#]/ { print $3 }' /etc/mnttab 2>/dev/null )
Packit 8462d6
            $( awk '/^[ \t]*[^#]/ { print $4 }' /etc/vfstab 2>/dev/null )
Packit 8462d6
            $( awk '{ print $1 }' /etc/dfs/fstypes 2>/dev/null )
Packit 8462d6
            $( [[ -d /etc/fs ]] && command ls /etc/fs )"
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    [[ -n $fss ]] && COMPREPLY+=( $( compgen -W "$fss" -- "$cur" ) )
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# Get real command.
Packit 8462d6
# - arg: $1  Command
Packit 8462d6
# - stdout:  Filename of command in PATH with possible symbolic links resolved.
Packit 8462d6
#            Empty string if command not found.
Packit 8462d6
# - return:  True (0) if command found, False (> 0) if not.
Packit 8462d6
_realcommand()
Packit 8462d6
{
Packit 8462d6
    type -P "$1" > /dev/null && {
Packit 8462d6
        if type -p realpath > /dev/null; then
Packit 8462d6
            realpath "$(type -P "$1")"
Packit 8462d6
        elif type -p greadlink > /dev/null; then
Packit 8462d6
            greadlink -f "$(type -P "$1")"
Packit 8462d6
        elif type -p readlink > /dev/null; then
Packit 8462d6
            readlink -f "$(type -P "$1")"
Packit 8462d6
        else
Packit 8462d6
            type -P "$1"
Packit 8462d6
        fi
Packit 8462d6
    }
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function returns the first argument, excluding options
Packit 8462d6
# @param $1 chars  Characters out of $COMP_WORDBREAKS which should
Packit 8462d6
#     NOT be considered word breaks. See __reassemble_comp_words_by_ref.
Packit 8462d6
_get_first_arg()
Packit 8462d6
{
Packit 8462d6
    local i
Packit 8462d6
Packit 8462d6
    arg=
Packit 8462d6
    for (( i=1; i < COMP_CWORD; i++ )); do
Packit 8462d6
        if [[ "${COMP_WORDS[i]}" != -* ]]; then
Packit 8462d6
            arg=${COMP_WORDS[i]}
Packit 8462d6
            break
Packit 8462d6
        fi
Packit 8462d6
    done
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
Packit 8462d6
# This function counts the number of args, excluding options
Packit 8462d6
# @param $1 chars  Characters out of $COMP_WORDBREAKS which should
Packit 8462d6
#     NOT be considered word breaks. See __reassemble_comp_words_by_ref.
Packit 8462d6
_count_args()
Packit 8462d6
{
Packit 8462d6
    local i cword words
Packit 8462d6
    __reassemble_comp_words_by_ref "$1" words cword
Packit 8462d6
Packit 8462d6
    args=1
Packit 8462d6
    for i in "${words[@]:1:cword-1}"; do
Packit 8462d6
        [[ "$i" != -* ]] && args=$(($args+1))
Packit 8462d6
    done
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on PCI IDs
Packit 8462d6
#
Packit 8462d6
_pci_ids()
Packit 8462d6
{
Packit 8462d6
    COMPREPLY+=( $( compgen -W \
Packit 8462d6
        "$( PATH="$PATH:/sbin" lspci -n | awk '{print $3}')" -- "$cur" ) )
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# This function completes on USB IDs
Packit 8462d6
#
Packit 8462d6
_usb_ids()
Packit 8462d6
{
Packit 8462d6
    COMPREPLY+=( $( compgen -W \
Packit 8462d6
        "$( PATH="$PATH:/sbin" lsusb | awk '{print $6}' )" -- "$cur" ) )
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# CD device names
Packit 8462d6
_cd_devices()
Packit 8462d6
{
Packit 8462d6
    COMPREPLY+=( $( compgen -f -d -X "!*/?([amrs])cd*" -- "${cur:-/dev/}" ) )
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# DVD device names
Packit 8462d6
_dvd_devices()
Packit 8462d6
{
Packit 8462d6
    COMPREPLY+=( $( compgen -f -d -X "!*/?(r)dvd*" -- "${cur:-/dev/}" ) )
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# TERM environment variable values
Packit 8462d6
_terms()
Packit 8462d6
{
Packit 8462d6
    COMPREPLY+=( $( compgen -W \
Packit 8462d6
        "$( command sed -ne 's/^\([^[:space:]#|]\{2,\}\)|.*/\1/p' /etc/termcap \
Packit 8462d6
            2>/dev/null )" -- "$cur" ) )
Packit 8462d6
    COMPREPLY+=( $( compgen -W "$( { toe -a 2>/dev/null || toe 2>/dev/null; } \
Packit 8462d6
        | awk '{ print $1 }' | sort -u )" -- "$cur" ) )
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# a little help for FreeBSD ports users
Packit 8462d6
[[ $OSTYPE == *freebsd* ]] && complete -W 'index search fetch fetch-list
Packit 8462d6
    extract patch configure build install reinstall deinstall clean
Packit 8462d6
    clean-depends kernel buildworld' make
Packit 8462d6
Packit 8462d6
# This function provides simple user@host completion
Packit 8462d6
#
Packit 8462d6
_user_at_host()
Packit 8462d6
{
Packit 8462d6
    local cur prev words cword
Packit 8462d6
    _init_completion -n : || return
Packit 8462d6
Packit 8462d6
    if [[ $cur == *@* ]]; then
Packit 8462d6
        _known_hosts_real "$cur"
Packit 8462d6
    else
Packit 8462d6
        COMPREPLY=( $( compgen -u -S @ -- "$cur" ) )
Packit 8462d6
        compopt -o nospace
Packit 8462d6
    fi
Packit 8462d6
}
Packit 8462d6
shopt -u hostcomplete && complete -F _user_at_host talk ytalk finger
Packit 8462d6
Packit 8462d6
# NOTE: Using this function as a helper function is deprecated.  Use
Packit 8462d6
#       `_known_hosts_real' instead.
Packit 8462d6
_known_hosts()
Packit 8462d6
{
Packit 8462d6
    local cur prev words cword
Packit 8462d6
    _init_completion -n : || return
Packit 8462d6
Packit 8462d6
    # NOTE: Using `_known_hosts' as a helper function and passing options
Packit 8462d6
    #       to `_known_hosts' is deprecated: Use `_known_hosts_real' instead.
Packit 8462d6
    local options
Packit 8462d6
    [[ "$1" == -a || "$2" == -a ]] && options=-a
Packit 8462d6
    [[ "$1" == -c || "$2" == -c ]] && options+=" -c"
Packit 8462d6
    _known_hosts_real $options -- "$cur"
Packit 8462d6
} # _known_hosts()
Packit 8462d6
Packit 8462d6
# Helper function to locate ssh included files in configs
Packit 8462d6
# This function look for the "Include" keyword in ssh config files and include
Packit 8462d6
# them recursively adding each result to the config variable
Packit 8462d6
_included_ssh_config_files()
Packit 8462d6
{
Packit 8462d6
    [[ $# -lt 1 ]] && echo "error: $FUNCNAME: missing mandatory argument CONFIG"
Packit 8462d6
    local configfile i f
Packit 8462d6
    configfile=$1
Packit 8462d6
    local included=$( command sed -ne 's/^[[:blank:]]*[Ii][Nn][Cc][Ll][Uu][Dd][Ee][[:blank:]]\{1,\}\([^#%]*\)\(#.*\)\{0,1\}$/\1/p' "${configfile}" )
Packit 8462d6
    for i in ${included[@]}; do
Packit 8462d6
        # Check the origin of $configfile to complete relative included paths on included
Packit 8462d6
        # files according to ssh_config(5):
Packit 8462d6
        #  "[...] Files without absolute paths are assumed to be in ~/.ssh if included in a user
Packit 8462d6
        #   configuration file or /etc/ssh if included from the system configuration file.[...]"
Packit 8462d6
        if ! [[ "$i" =~ ^\~.*|^\/.* ]]; then
Packit 8462d6
            if [[ "$configfile" =~ ^\/etc\/ssh.* ]]; then
Packit 8462d6
                i="/etc/ssh/$i"
Packit 8462d6
            else
Packit 8462d6
                i="$HOME/.ssh/$i"
Packit 8462d6
            fi
Packit 8462d6
        fi
Packit 8462d6
        __expand_tilde_by_ref i
Packit 8462d6
        # In case the expanded variable contains multiple paths
Packit 8462d6
        for f in ${i}; do
Packit 8462d6
            if [ -r $f ]; then
Packit 8462d6
                config+=( "$f" )
Packit 8462d6
                # The Included file is processed to look for Included files in itself
Packit 8462d6
                _included_ssh_config_files $f
Packit 8462d6
            fi
Packit 8462d6
        done
Packit 8462d6
    done
Packit 8462d6
} # _included_ssh_config_files()
Packit 8462d6
Packit 8462d6
# Helper function for completing _known_hosts.
Packit 8462d6
# This function performs host completion based on ssh's config and known_hosts
Packit 8462d6
# files, as well as hostnames reported by avahi-browse if
Packit 8462d6
# COMP_KNOWN_HOSTS_WITH_AVAHI is set to a non-empty value.  Also hosts from
Packit 8462d6
# HOSTFILE (compgen -A hostname) are added, unless
Packit 8462d6
# COMP_KNOWN_HOSTS_WITH_HOSTFILE is set to an empty value.
Packit 8462d6
# Usage: _known_hosts_real [OPTIONS] CWORD
Packit 8462d6
# Options:  -a             Use aliases
Packit 8462d6
#           -c             Use `:' suffix
Packit 8462d6
#           -F configfile  Use `configfile' for configuration settings
Packit 8462d6
#           -p PREFIX      Use PREFIX
Packit 8462d6
# Return: Completions, starting with CWORD, are added to COMPREPLY[]
Packit 8462d6
_known_hosts_real()
Packit 8462d6
{
Packit 8462d6
    local configfile flag prefix
Packit 8462d6
    local cur curd awkcur user suffix aliases i host
Packit 8462d6
    local -a kh khd config
Packit 8462d6
Packit 8462d6
    local OPTIND=1
Packit 8462d6
    while getopts "acF:p:" flag "$@"; do
Packit 8462d6
        case $flag in
Packit 8462d6
            a) aliases='yes' ;;
Packit 8462d6
            c) suffix=':' ;;
Packit 8462d6
            F) configfile=$OPTARG ;;
Packit 8462d6
            p) prefix=$OPTARG ;;
Packit 8462d6
        esac
Packit 8462d6
    done
Packit 8462d6
    [[ $# -lt $OPTIND ]] && echo "error: $FUNCNAME: missing mandatory argument CWORD"
Packit 8462d6
    cur=${!OPTIND}; let "OPTIND += 1"
Packit 8462d6
    [[ $# -ge $OPTIND ]] && echo "error: $FUNCNAME("$@"): unprocessed arguments:"\
Packit 8462d6
    $(while [[ $# -ge $OPTIND ]]; do printf '%s\n' ${!OPTIND}; shift; done)
Packit 8462d6
Packit 8462d6
    [[ $cur == *@* ]] && user=${cur%@*}@ && cur=${cur#*@}
Packit 8462d6
    kh=()
Packit 8462d6
Packit 8462d6
    # ssh config files
Packit 8462d6
    if [[ -n $configfile ]]; then
Packit 8462d6
        [[ -r $configfile ]] && config+=( "$configfile" )
Packit 8462d6
    else
Packit 8462d6
        for i in /etc/ssh/ssh_config ~/.ssh/config ~/.ssh2/config; do
Packit 8462d6
            [[ -r $i ]] && config+=( "$i" )
Packit 8462d6
        done
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    # "Include" keyword in ssh config files
Packit 8462d6
    for i in "${config[@]}"; do
Packit 8462d6
        _included_ssh_config_files "$i"
Packit 8462d6
    done
Packit 8462d6
Packit 8462d6
    # Known hosts files from configs
Packit 8462d6
    if [[ ${#config[@]} -gt 0 ]]; then
Packit 8462d6
        local OIFS=$IFS IFS=$'\n' j
Packit 8462d6
        local -a tmpkh
Packit 8462d6
        # expand paths (if present) to global and user known hosts files
Packit 8462d6
        # TODO(?): try to make known hosts files with more than one consecutive
Packit 8462d6
        #          spaces in their name work (watch out for ~ expansion
Packit 8462d6
        #          breakage! Alioth#311595)
Packit 8462d6
        tmpkh=( $( awk 'sub("^[ \t]*([Gg][Ll][Oo][Bb][Aa][Ll]|[Uu][Ss][Ee][Rr])[Kk][Nn][Oo][Ww][Nn][Hh][Oo][Ss][Tt][Ss][Ff][Ii][Ll][Ee][ \t]+", "") { print $0 }' "${config[@]}" | sort -u ) )
Packit 8462d6
        IFS=$OIFS
Packit 8462d6
        for i in "${tmpkh[@]}"; do
Packit 8462d6
            # First deal with quoted entries...
Packit 8462d6
            while [[ $i =~ ^([^\"]*)\"([^\"]*)\"(.*)$ ]]; do
Packit 8462d6
                i=${BASH_REMATCH[1]}${BASH_REMATCH[3]}
Packit 8462d6
                j=${BASH_REMATCH[2]}
Packit 8462d6
                __expand_tilde_by_ref j # Eval/expand possible `~' or `~user'
Packit 8462d6
                [[ -r $j ]] && kh+=( "$j" )
Packit 8462d6
            done
Packit 8462d6
            # ...and then the rest.
Packit 8462d6
            for j in $i; do
Packit 8462d6
                __expand_tilde_by_ref j # Eval/expand possible `~' or `~user'
Packit 8462d6
                [[ -r $j ]] && kh+=( "$j" )
Packit 8462d6
            done
Packit 8462d6
        done
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    if [[ -z $configfile ]]; then
Packit 8462d6
        # Global and user known_hosts files
Packit 8462d6
        for i in /etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2 \
Packit 8462d6
            /etc/known_hosts /etc/known_hosts2 ~/.ssh/known_hosts \
Packit 8462d6
            ~/.ssh/known_hosts2; do
Packit 8462d6
            [[ -r $i ]] && kh+=( "$i" )
Packit 8462d6
        done
Packit 8462d6
        for i in /etc/ssh2/knownhosts ~/.ssh2/hostkeys; do
Packit 8462d6
            [[ -d $i ]] && khd+=( "$i"/*pub )
Packit 8462d6
        done
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    # If we have known_hosts files to use
Packit 8462d6
    if [[ ${#kh[@]} -gt 0 || ${#khd[@]} -gt 0 ]]; then
Packit 8462d6
        # Escape slashes and dots in paths for awk
Packit 8462d6
        awkcur=${cur//\//\\\/}
Packit 8462d6
        awkcur=${awkcur//\./\\\.}
Packit 8462d6
        curd=$awkcur
Packit 8462d6
Packit 8462d6
        if [[ "$awkcur" == [0-9]*[.:]* ]]; then
Packit 8462d6
            # Digits followed by a dot or a colon - just search for that
Packit 8462d6
            awkcur="^$awkcur[.:]*"
Packit 8462d6
        elif [[ "$awkcur" == [0-9]* ]]; then
Packit 8462d6
            # Digits followed by no dot or colon - search for digits followed
Packit 8462d6
            # by a dot or a colon
Packit 8462d6
            awkcur="^$awkcur.*[.:]"
Packit 8462d6
        elif [[ -z $awkcur ]]; then
Packit 8462d6
            # A blank - search for a dot, a colon, or an alpha character
Packit 8462d6
            awkcur="[a-z.:]"
Packit 8462d6
        else
Packit 8462d6
            awkcur="^$awkcur"
Packit 8462d6
        fi
Packit 8462d6
Packit 8462d6
        if [[ ${#kh[@]} -gt 0 ]]; then
Packit 8462d6
            # FS needs to look for a comma separated list
Packit 8462d6
            COMPREPLY+=( $( awk 'BEGIN {FS=","}
Packit 8462d6
            /^\s*[^|\#]/ {
Packit 8462d6
            sub("^@[^ ]+ +", ""); \
Packit 8462d6
            sub(" .*$", ""); \
Packit 8462d6
            for (i=1; i<=NF; ++i) { \
Packit 8462d6
            sub("^\\[", "", $i); sub("\\](:[0-9]+)?$", "", $i); \
Packit 8462d6
            if ($i !~ /[*?]/ && $i ~ /'"$awkcur"'/) {print $i} \
Packit 8462d6
            }}' "${kh[@]}" 2>/dev/null ) )
Packit 8462d6
        fi
Packit 8462d6
        if [[ ${#khd[@]} -gt 0 ]]; then
Packit 8462d6
            # Needs to look for files called
Packit 8462d6
            # .../.ssh2/key_22_<hostname>.pub
Packit 8462d6
            # dont fork any processes, because in a cluster environment,
Packit 8462d6
            # there can be hundreds of hostkeys
Packit 8462d6
            for i in "${khd[@]}" ; do
Packit 8462d6
                if [[ "$i" == *key_22_$curd*.pub && -r "$i" ]]; then
Packit 8462d6
                    host=${i/#*key_22_/}
Packit 8462d6
                    host=${host/%.pub/}
Packit 8462d6
                    COMPREPLY+=( $host )
Packit 8462d6
                fi
Packit 8462d6
            done
Packit 8462d6
        fi
Packit 8462d6
Packit 8462d6
        # apply suffix and prefix
Packit 8462d6
        for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
Packit 8462d6
            COMPREPLY[i]=$prefix$user${COMPREPLY[i]}$suffix
Packit 8462d6
        done
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    # append any available aliases from config files
Packit 8462d6
    if [[ ${#config[@]} -gt 0 && -n "$aliases" ]]; then
Packit 8462d6
        local hosts=$( command sed -ne 's/^[[:blank:]]*[Hh][Oo][Ss][Tt][[:blank:]]\{1,\}\([^#*?%]*\)\(#.*\)\{0,1\}$/\1/p' "${config[@]}" )
Packit 8462d6
        COMPREPLY+=( $( compgen -P "$prefix$user" \
Packit 8462d6
            -S "$suffix" -W "$hosts" -- "$cur" ) )
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    # Add hosts reported by avahi-browse, if desired and it's available.
Packit 8462d6
    if [[ ${COMP_KNOWN_HOSTS_WITH_AVAHI:-} ]] && \
Packit 8462d6
        type avahi-browse &>/dev/null; then
Packit 8462d6
        # The original call to avahi-browse also had "-k", to avoid lookups
Packit 8462d6
        # into avahi's services DB. We don't need the name of the service, and
Packit 8462d6
        # if it contains ";", it may mistify the result. But on Gentoo (at
Packit 8462d6
        # least), -k wasn't available (even if mentioned in the manpage) some
Packit 8462d6
        # time ago, so...
Packit 8462d6
        COMPREPLY+=( $( compgen -P "$prefix$user" -S "$suffix" -W \
Packit 8462d6
            "$( avahi-browse -cpr _workstation._tcp 2>/dev/null | \
Packit 8462d6
                awk -F';' '/^=/ { print $7 }' | sort -u )" -- "$cur" ) )
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    # Add hosts reported by ruptime.
Packit 8462d6
    COMPREPLY+=( $( compgen -W \
Packit 8462d6
        "$( ruptime 2>/dev/null | awk '!/^ruptime:/ { print $1 }' )" \
Packit 8462d6
        -- "$cur" ) )
Packit 8462d6
Packit 8462d6
    # Add results of normal hostname completion, unless
Packit 8462d6
    # `COMP_KNOWN_HOSTS_WITH_HOSTFILE' is set to an empty value.
Packit 8462d6
    if [[ -n ${COMP_KNOWN_HOSTS_WITH_HOSTFILE-1} ]]; then
Packit 8462d6
        COMPREPLY+=(
Packit 8462d6
            $( compgen -A hostname -P "$prefix$user" -S "$suffix" -- "$cur" ) )
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    __ltrim_colon_completions "$prefix$user$cur"
Packit 8462d6
Packit 8462d6
} # _known_hosts_real()
Packit 8462d6
complete -F _known_hosts traceroute traceroute6 tracepath tracepath6 \
Packit 8462d6
    fping fping6 telnet rsh rlogin ftp dig mtr ssh-installkeys showmount
Packit 8462d6
Packit 8462d6
# This meta-cd function observes the CDPATH variable, so that cd additionally
Packit 8462d6
# completes on directories under those specified in CDPATH.
Packit 8462d6
#
Packit 8462d6
_cd()
Packit 8462d6
{
Packit 8462d6
    local cur prev words cword
Packit 8462d6
    _init_completion || return
Packit 8462d6
Packit 8462d6
    local IFS=$'\n' i j k
Packit 8462d6
Packit 8462d6
    compopt -o filenames
Packit 8462d6
Packit 8462d6
    # Use standard dir completion if no CDPATH or parameter starts with /,
Packit 8462d6
    # ./ or ../
Packit 8462d6
    if [[ -z "${CDPATH:-}" || "$cur" == ?(.)?(.)/* ]]; then
Packit 8462d6
        _filedir -d
Packit 8462d6
        return
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    local -r mark_dirs=$(_rl_enabled mark-directories && echo y)
Packit 8462d6
    local -r mark_symdirs=$(_rl_enabled mark-symlinked-directories && echo y)
Packit 8462d6
Packit 8462d6
    # we have a CDPATH, so loop on its contents
Packit 8462d6
    for i in ${CDPATH//:/$'\n'}; do
Packit 8462d6
        # create an array of matched subdirs
Packit 8462d6
        k="${#COMPREPLY[@]}"
Packit 8462d6
        for j in $( compgen -d -- $i/$cur ); do
Packit 8462d6
            if [[ ( $mark_symdirs && -h $j || $mark_dirs && ! -h $j ) && ! -d ${j#$i/} ]]; then
Packit 8462d6
                j+="/"
Packit 8462d6
            fi
Packit 8462d6
            COMPREPLY[k++]=${j#$i/}
Packit 8462d6
        done
Packit 8462d6
    done
Packit 8462d6
Packit 8462d6
    _filedir -d
Packit 8462d6
Packit 8462d6
    if [[ ${#COMPREPLY[@]} -eq 1 ]]; then
Packit 8462d6
        i=${COMPREPLY[0]}
Packit 8462d6
        if [[ "$i" == "$cur" && $i != "*/" ]]; then
Packit 8462d6
            COMPREPLY[0]="${i}/"
Packit 8462d6
        fi
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    return
Packit 8462d6
}
Packit 8462d6
if shopt -q cdable_vars; then
Packit 8462d6
    complete -v -F _cd -o nospace cd pushd
Packit 8462d6
else
Packit 8462d6
    complete -F _cd -o nospace cd pushd
Packit 8462d6
fi
Packit 8462d6
Packit 8462d6
# a wrapper method for the next one, when the offset is unknown
Packit 8462d6
_command()
Packit 8462d6
{
Packit 8462d6
    local offset i
Packit 8462d6
Packit 8462d6
    # find actual offset, as position of the first non-option
Packit 8462d6
    offset=1
Packit 8462d6
    for (( i=1; i <= COMP_CWORD; i++ )); do
Packit 8462d6
        if [[ "${COMP_WORDS[i]}" != -* ]]; then
Packit 8462d6
            offset=$i
Packit 8462d6
            break
Packit 8462d6
        fi
Packit 8462d6
    done
Packit 8462d6
    _command_offset $offset
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# A meta-command completion function for commands like sudo(8), which need to
Packit 8462d6
# first complete on a command, then complete according to that command's own
Packit 8462d6
# completion definition.
Packit 8462d6
#
Packit 8462d6
_command_offset()
Packit 8462d6
{
Packit 8462d6
    # rewrite current completion context before invoking
Packit 8462d6
    # actual command completion
Packit 8462d6
Packit 8462d6
    # find new first word position, then
Packit 8462d6
    # rewrite COMP_LINE and adjust COMP_POINT
Packit 8462d6
    local word_offset=$1 i j
Packit 8462d6
    for (( i=0; i < $word_offset; i++ )); do
Packit 8462d6
        for (( j=0; j <= ${#COMP_LINE}; j++ )); do
Packit 8462d6
            [[ "$COMP_LINE" == "${COMP_WORDS[i]}"* ]] && break
Packit 8462d6
            COMP_LINE=${COMP_LINE:1}
Packit 8462d6
            ((COMP_POINT--))
Packit 8462d6
        done
Packit 8462d6
        COMP_LINE=${COMP_LINE#"${COMP_WORDS[i]}"}
Packit 8462d6
        ((COMP_POINT-=${#COMP_WORDS[i]}))
Packit 8462d6
    done
Packit 8462d6
Packit 8462d6
    # shift COMP_WORDS elements and adjust COMP_CWORD
Packit 8462d6
    for (( i=0; i <= COMP_CWORD - $word_offset; i++ )); do
Packit 8462d6
        COMP_WORDS[i]=${COMP_WORDS[i+$word_offset]}
Packit 8462d6
    done
Packit 8462d6
    for (( i; i <= COMP_CWORD; i++ )); do
Packit 8462d6
        unset 'COMP_WORDS[i]'
Packit 8462d6
    done
Packit 8462d6
    ((COMP_CWORD -= $word_offset))
Packit 8462d6
Packit 8462d6
    COMPREPLY=()
Packit 8462d6
    local cur
Packit 8462d6
    _get_comp_words_by_ref cur
Packit 8462d6
Packit 8462d6
    if [[ $COMP_CWORD -eq 0 ]]; then
Packit 8462d6
        local IFS=$'\n'
Packit 8462d6
        compopt -o filenames
Packit 8462d6
        COMPREPLY=( $( compgen -d -c -- "$cur" ) )
Packit 8462d6
    else
Packit 8462d6
        local cmd=${COMP_WORDS[0]} compcmd=${COMP_WORDS[0]}
Packit 8462d6
        local cspec=$( complete -p $cmd 2>/dev/null )
Packit 8462d6
Packit 8462d6
        # If we have no completion for $cmd yet, see if we have for basename
Packit 8462d6
        if [[ ! $cspec && $cmd == */* ]]; then
Packit 8462d6
            cspec=$( complete -p ${cmd##*/} 2>/dev/null )
Packit 8462d6
            [[ $cspec ]] && compcmd=${cmd##*/}
Packit 8462d6
        fi
Packit 8462d6
        # If still nothing, just load it for the basename
Packit 8462d6
        if [[ ! $cspec ]]; then
Packit 8462d6
            compcmd=${cmd##*/}
Packit 8462d6
            _completion_loader $compcmd
Packit 8462d6
            cspec=$( complete -p $compcmd 2>/dev/null )
Packit 8462d6
        fi
Packit 8462d6
Packit 8462d6
        if [[ -n $cspec ]]; then
Packit 8462d6
            if [[ ${cspec#* -F } != $cspec ]]; then
Packit 8462d6
                # complete -F <function>
Packit 8462d6
Packit 8462d6
                # get function name
Packit 8462d6
                local func=${cspec#*-F }
Packit 8462d6
                func=${func%% *}
Packit 8462d6
Packit 8462d6
                if [[ ${#COMP_WORDS[@]} -ge 2 ]]; then
Packit 8462d6
                    $func $cmd "${COMP_WORDS[${#COMP_WORDS[@]}-1]}" "${COMP_WORDS[${#COMP_WORDS[@]}-2]}"
Packit 8462d6
                else
Packit 8462d6
                    $func $cmd "${COMP_WORDS[${#COMP_WORDS[@]}-1]}"
Packit 8462d6
                fi
Packit 8462d6
Packit 8462d6
                # restore initial compopts
Packit 8462d6
                local opt
Packit 8462d6
                while [[ $cspec == *" -o "* ]]; do
Packit 8462d6
                    # FIXME: should we take "+o opt" into account?
Packit 8462d6
                    cspec=${cspec#*-o }
Packit 8462d6
                    opt=${cspec%% *}
Packit 8462d6
                    compopt -o $opt
Packit 8462d6
                    cspec=${cspec#$opt}
Packit 8462d6
                done
Packit 8462d6
            else
Packit 8462d6
                cspec=${cspec#complete}
Packit 8462d6
                cspec=${cspec%%$compcmd}
Packit 8462d6
                COMPREPLY=( $( eval compgen "$cspec" -- '$cur' ) )
Packit 8462d6
            fi
Packit 8462d6
        elif [[ ${#COMPREPLY[@]} -eq 0 ]]; then
Packit 8462d6
            # XXX will probably never happen as long as completion loader loads
Packit 8462d6
            #     *something* for every command thrown at it ($cspec != empty)
Packit 8462d6
            _minimal
Packit 8462d6
        fi
Packit 8462d6
    fi
Packit 8462d6
}
Packit 8462d6
complete -F _command aoss command do else eval exec ltrace nice nohup padsp \
Packit 8462d6
    then time tsocks vsound xargs
Packit 8462d6
Packit 8462d6
_root_command()
Packit 8462d6
{
Packit 8462d6
    local PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin
Packit 8462d6
    local root_command=$1
Packit 8462d6
    _command
Packit 8462d6
}
Packit 8462d6
complete -F _root_command fakeroot gksu gksudo kdesudo really
Packit 8462d6
Packit 8462d6
# Return true if the completion should be treated as running as root
Packit 8462d6
_complete_as_root()
Packit 8462d6
{
Packit 8462d6
    [[ $EUID -eq 0 || ${root_command:-} ]]
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
_longopt()
Packit 8462d6
{
Packit 8462d6
    local cur prev words cword split
Packit 8462d6
    _init_completion -s || return
Packit 8462d6
Packit 8462d6
    case "${prev,,}" in
Packit 8462d6
        --help|--usage|--version)
Packit 8462d6
            return
Packit 8462d6
            ;;
Packit 8462d6
        --*dir*)
Packit 8462d6
            _filedir -d
Packit 8462d6
            return
Packit 8462d6
            ;;
Packit 8462d6
        --*file*|--*path*)
Packit 8462d6
            _filedir
Packit 8462d6
            return
Packit 8462d6
            ;;
Packit 8462d6
        --+([-a-z0-9_]))
Packit 8462d6
            local argtype=$( LC_ALL=C $1 --help 2>&1 | command sed -ne \
Packit 8462d6
                "s|.*$prev\[\{0,1\}=[<[]\{0,1\}\([-A-Za-z0-9_]\{1,\}\).*|\1|p" )
Packit 8462d6
            case ${argtype,,} in
Packit 8462d6
                *dir*)
Packit 8462d6
                    _filedir -d
Packit 8462d6
                    return
Packit 8462d6
                    ;;
Packit 8462d6
                *file*|*path*)
Packit 8462d6
                    _filedir
Packit 8462d6
                    return
Packit 8462d6
                    ;;
Packit 8462d6
            esac
Packit 8462d6
            ;;
Packit 8462d6
    esac
Packit 8462d6
Packit 8462d6
    $split && return
Packit 8462d6
Packit 8462d6
    if [[ "$cur" == -* ]]; then
Packit 8462d6
        COMPREPLY=( $( compgen -W "$( LC_ALL=C $1 --help 2>&1 | \
Packit 8462d6
            command sed -ne 's/.*\(--[-A-Za-z0-9]\{1,\}=\{0,1\}\).*/\1/p' | sort -u )" \
Packit 8462d6
            -- "$cur" ) )
Packit 8462d6
        [[ $COMPREPLY == *= ]] && compopt -o nospace
Packit 8462d6
    elif [[ "$1" == @(@(mk|rm)dir|chroot) ]]; then
Packit 8462d6
        _filedir -d
Packit 8462d6
    else
Packit 8462d6
        _filedir
Packit 8462d6
    fi
Packit 8462d6
}
Packit 8462d6
# makeinfo and texi2dvi are defined elsewhere.
Packit 8462d6
complete -F _longopt a2ps awk base64 bash bc bison cat chroot colordiff cp \
Packit 8462d6
    csplit cut date df diff dir du enscript env expand fmt fold gperf \
Packit 8462d6
    grep grub head irb ld ldd less ln ls m4 md5sum mkdir mkfifo mknod \
Packit 8462d6
    mv netstat nl nm objcopy objdump od paste pr ptx readelf rm rmdir \
Packit 8462d6
    sed seq sha{,1,224,256,384,512}sum shar sort split strip sum tac tail tee \
Packit 8462d6
    texindex touch tr uname unexpand uniq units vdir wc who
Packit 8462d6
Packit 8462d6
declare -A _xspecs
Packit 8462d6
_filedir_xspec()
Packit 8462d6
{
Packit 8462d6
    local cur prev words cword
Packit 8462d6
    _init_completion || return
Packit 8462d6
Packit 8462d6
    _tilde "$cur" || return
Packit 8462d6
Packit 8462d6
    local IFS=$'\n' xspec=${_xspecs[${1##*/}]} tmp
Packit 8462d6
    local -a toks
Packit 8462d6
Packit 8462d6
    toks=( $(
Packit 8462d6
        compgen -d -- "$(quote_readline "$cur")" | {
Packit 8462d6
        while read -r tmp; do
Packit 8462d6
            printf '%s\n' $tmp
Packit 8462d6
        done
Packit 8462d6
        }
Packit 8462d6
        ))
Packit 8462d6
Packit 8462d6
    # Munge xspec to contain uppercase version too
Packit 8462d6
    # http://thread.gmane.org/gmane.comp.shells.bash.bugs/15294/focus=15306
Packit 8462d6
    eval xspec="${xspec}"
Packit 8462d6
    local matchop=!
Packit 8462d6
    if [[ $xspec == !* ]]; then
Packit 8462d6
        xspec=${xspec#!}
Packit 8462d6
        matchop=@
Packit 8462d6
    fi
Packit 8462d6
    xspec="$matchop($xspec|${xspec^^})"
Packit 8462d6
Packit 8462d6
    toks+=( $(
Packit 8462d6
        eval compgen -f -X "'!$xspec'" -- "\$(quote_readline "\$cur")" | {
Packit 8462d6
        while read -r tmp; do
Packit 8462d6
            [[ -n $tmp ]] && printf '%s\n' $tmp
Packit 8462d6
        done
Packit 8462d6
        }
Packit 8462d6
        ))
Packit 8462d6
Packit 8462d6
    if [[ ${#toks[@]} -ne 0 ]]; then
Packit 8462d6
        compopt -o filenames
Packit 8462d6
        COMPREPLY=( "${toks[@]}" )
Packit 8462d6
    fi
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
_install_xspec()
Packit 8462d6
{
Packit 8462d6
    local xspec=$1 cmd
Packit 8462d6
    shift
Packit 8462d6
    for cmd in $@; do
Packit 8462d6
        _xspecs[$cmd]=$xspec
Packit 8462d6
    done
Packit 8462d6
    complete -F _filedir_xspec $@
Packit 8462d6
}
Packit 8462d6
# bzcmp, bzdiff, bz*grep, bzless, bzmore intentionally not here, see Debian: #455510
Packit 8462d6
_install_xspec '!*.?(t)bz?(2)' bunzip2 bzcat pbunzip2 pbzcat lbunzip2 lbzcat
Packit 8462d6
_install_xspec '!*.@(zip|[ejsw]ar|exe|pk3|wsz|zargo|xpi|s[tx][cdiw]|sx[gm]|o[dt][tspgfc]|od[bm]|oxt|epub|apk|ipa|do[ct][xm]|p[op]t[mx]|xl[st][xm]|pyz)' unzip zipinfo
Packit 8462d6
_install_xspec '*.Z' compress znew
Packit 8462d6
# zcmp, zdiff, z*grep, zless, zmore intentionally not here, see Debian: #455510
Packit 8462d6
_install_xspec '!*.@(Z|[gGd]z|t[ag]z)' gunzip zcat
Packit 8462d6
_install_xspec '!*.@(Z|[gGdz]z|t[ag]z)' unpigz
Packit 8462d6
_install_xspec '!*.Z' uncompress
Packit 8462d6
# lzcmp, lzdiff intentionally not here, see Debian: #455510
Packit 8462d6
_install_xspec '!*.@(tlz|lzma)' lzcat lzegrep lzfgrep lzgrep lzless lzmore unlzma
Packit 8462d6
_install_xspec '!*.@(?(t)xz|tlz|lzma)' unxz xzcat
Packit 8462d6
_install_xspec '!*.lrz' lrunzip
Packit 8462d6
_install_xspec '!*.@(gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx)' ee
Packit 8462d6
_install_xspec '!*.@(gif|jp?(e)g|tif?(f)|png|p[bgp]m|bmp|x[bp]m|rle|rgb|pcx|fits|pm|svg)' qiv
Packit 8462d6
_install_xspec '!*.@(gif|jp?(e)g?(2)|j2[ck]|jp[2f]|tif?(f)|png|p[bgp]m|bmp|x[bp]m|rle|rgb|pcx|fits|pm|?(e)ps)' xv
Packit 8462d6
_install_xspec '!*.@(@(?(e)ps|?(E)PS|pdf|PDF)?(.gz|.GZ|.bz2|.BZ2|.Z))' gv ggv kghostview
Packit 8462d6
_install_xspec '!*.@(dvi|DVI)?(.@(gz|Z|bz2))' xdvi kdvi
Packit 8462d6
_install_xspec '!*.dvi' dvips dviselect dvitype dvipdf advi dvipdfm dvipdfmx
Packit 8462d6
_install_xspec '!*.[pf]df' acroread gpdf xpdf
Packit 8462d6
_install_xspec '!*.@(?(e)ps|pdf)' kpdf
Packit 8462d6
_install_xspec '!*.@(okular|@(?(e|x)ps|?(E|X)PS|[pf]df|[PF]DF|dvi|DVI|cb[rz]|CB[RZ]|djv?(u)|DJV?(U)|dvi|DVI|gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx|GIF|JP?(E)G|MIFF|TIF?(F)|PN[GM]|P[BGP]M|BMP|XPM|ICO|XWD|TGA|PCX|epub|EPUB|odt|ODT|fb?(2)|FB?(2)|mobi|MOBI|g3|G3|chm|CHM)?(.?(gz|GZ|bz2|BZ2)))' okular
Packit 8462d6
_install_xspec '!*.pdf' epdfview pdfunite
Packit 8462d6
_install_xspec '!*.@(cb[rz7t]|djv?(u)|?(e)ps|pdf)' zathura
Packit 8462d6
_install_xspec '!*.@(?(e)ps|pdf)' ps2pdf ps2pdf12 ps2pdf13 ps2pdf14 ps2pdfwr
Packit 8462d6
_install_xspec '!*.texi*' makeinfo texi2html
Packit 8462d6
_install_xspec '!*.@(?(la)tex|texi|dtx|ins|ltx|dbj)' tex latex slitex jadetex pdfjadetex pdftex pdflatex texi2dvi xetex xelatex luatex lualatex
Packit 8462d6
_install_xspec '!*.mp3' mpg123 mpg321 madplay
Packit 8462d6
_install_xspec '!*@(.@(mp?(e)g|MP?(E)G|wm[av]|WM[AV]|avi|AVI|asf|vob|VOB|bin|dat|divx|DIVX|vcd|ps|pes|fli|flv|FLV|fxm|FXM|viv|rm|ram|yuv|mov|MOV|qt|QT|web[am]|WEB[AM]|mp[234]|MP[234]|m?(p)4[av]|M?(P)4[AV]|mkv|MKV|og[gmv]|OG[GMV]|t[ps]|T[PS]|m2t?(s)|M2T?(S)|mts|MTS|wav|WAV|flac|FLAC|asx|ASX|mng|MNG|srt|m[eo]d|M[EO]D|s[3t]m|S[3T]M|it|IT|xm|XM)|+([0-9]).@(vdr|VDR))?(.part)' xine aaxine fbxine
Packit 8462d6
_install_xspec '!*@(.@(mp?(e)g|MP?(E)G|wm[av]|WM[AV]|avi|AVI|asf|vob|VOB|bin|dat|divx|DIVX|vcd|ps|pes|fli|flv|FLV|fxm|FXM|viv|rm|ram|yuv|mov|MOV|qt|QT|web[am]|WEB[AM]|mp[234]|MP[234]|m?(p)4[av]|M?(P)4[AV]|mkv|MKV|og[gmv]|OG[GMV]|t[ps]|T[PS]|m2t?(s)|M2T?(S)|mts|MTS|wav|WAV|flac|FLAC|asx|ASX|mng|MNG|srt|m[eo]d|M[EO]D|s[3t]m|S[3T]M|it|IT|xm|XM|iso|ISO)|+([0-9]).@(vdr|VDR))?(.part)' kaffeine dragon
Packit 8462d6
_install_xspec '!*.@(avi|asf|wmv)' aviplay
Packit 8462d6
_install_xspec '!*.@(rm?(j)|ra?(m)|smi?(l))' realplay
Packit 8462d6
_install_xspec '!*.@(mpg|mpeg|avi|mov|qt)' xanim
Packit 8462d6
_install_xspec '!*.@(ogg|m3u|flac|spx)' ogg123
Packit 8462d6
_install_xspec '!*.@(mp3|ogg|pls|m3u)' gqmpeg freeamp
Packit 8462d6
_install_xspec '!*.fig' xfig
Packit 8462d6
_install_xspec '!*.@(mid?(i)|cmf)' playmidi
Packit 8462d6
_install_xspec '!*.@(mid?(i)|rmi|rcp|[gr]36|g18|mod|xm|it|x3m|s[3t]m|kar)' timidity
Packit 8462d6
_install_xspec '!*.@(669|abc|am[fs]|d[bs]m|dmf|far|it|mdl|m[eo]d|mid?(i)|mt[2m]|oct|okt?(a)|p[st]m|s[3t]m|ult|umx|wav|xm)' modplugplay modplug123
Packit 8462d6
_install_xspec '*.@([ao]|so|so.!(conf|*/*)|[rs]pm|gif|jp?(e)g|mp3|mp?(e)g|avi|asf|ogg|class)' vi vim gvim rvim view rview rgvim rgview gview emacs xemacs sxemacs kate kwrite
Packit 8462d6
_install_xspec '!*.@(zip|z|gz|tgz)' bzme
Packit 8462d6
# konqueror not here on purpose, it's more than a web/html browser
Packit 8462d6
_install_xspec '!*.@(?([xX]|[sS])[hH][tT][mM]?([lL]))' netscape mozilla lynx galeon dillo elinks amaya epiphany
Packit 8462d6
_install_xspec '!*.@(?([xX]|[sS])[hH][tT][mM]?([lL])|[pP][dD][fF])' firefox mozilla-firefox iceweasel google-chrome chromium-browser
Packit 8462d6
_install_xspec '!*.@(sxw|stw|sxg|sgl|doc?([mx])|dot?([mx])|rtf|txt|htm|html|?(f)odt|ott|odm|pdf)' oowriter
Packit 8462d6
_install_xspec '!*.@(sxi|sti|pps?(x)|ppt?([mx])|pot?([mx])|?(f)odp|otp)' ooimpress
Packit 8462d6
_install_xspec '!*.@(sxc|stc|xls?([bmx])|xlw|xlt?([mx])|[ct]sv|?(f)ods|ots)' oocalc
Packit 8462d6
_install_xspec '!*.@(sxd|std|sda|sdd|?(f)odg|otg)' oodraw
Packit 8462d6
_install_xspec '!*.@(sxm|smf|mml|odf)' oomath
Packit 8462d6
_install_xspec '!*.odb' oobase
Packit 8462d6
_install_xspec '!*.[rs]pm' rpm2cpio
Packit 8462d6
_install_xspec '!*.aux' bibtex
Packit 8462d6
_install_xspec '!*.po' poedit gtranslator kbabel lokalize
Packit 8462d6
_install_xspec '!*.@([Pp][Rr][Gg]|[Cc][Ll][Pp])' harbour gharbour hbpp
Packit 8462d6
_install_xspec '!*.[Hh][Rr][Bb]' hbrun
Packit 8462d6
_install_xspec '!*.ly' lilypond ly2dvi
Packit 8462d6
_install_xspec '!*.@(dif?(f)|?(d)patch)?(.@([gx]z|bz2|lzma))' cdiff
Packit 8462d6
_install_xspec '!@(*.@(ks|jks|jceks|p12|pfx|bks|ubr|gkr|cer|crt|cert|p7b|pkipath|pem|p10|csr|crl)|cacerts)' portecle
Packit 8462d6
_install_xspec '!*.@(mp[234c]|og[ag]|@(fl|a)ac|m4[abp]|spx|tta|w?(a)v|wma|aif?(f)|asf|ape)' kid3 kid3-qt
Packit 8462d6
unset -f _install_xspec
Packit 8462d6
Packit 8462d6
# Minimal completion to use as fallback in _completion_loader.
Packit 8462d6
_minimal()
Packit 8462d6
{
Packit 8462d6
    local cur prev words cword split
Packit 8462d6
    _init_completion -s || return
Packit 8462d6
    $split && return
Packit 8462d6
    _filedir
Packit 8462d6
}
Packit 8462d6
# Complete the empty string to allow completion of '>', '>>', and '<' on < 4.3
Packit 8462d6
# http://lists.gnu.org/archive/html/bug-bash/2012-01/msg00045.html
Packit 8462d6
complete -F _minimal ''
Packit 8462d6
Packit 8462d6
Packit 8462d6
__load_completion()
Packit 8462d6
{
Packit 8462d6
    local -a dirs=( ${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions )
Packit 8462d6
    local OIFS=$IFS IFS=: dir cmd="$1" compfile
Packit 8462d6
    for dir in ${XDG_DATA_DIRS:-/usr/local/share:/usr/share}; do
Packit 8462d6
        dirs+=( $dir/bash-completion/completions )
Packit 8462d6
    done
Packit 8462d6
    IFS=$OIFS
Packit 8462d6
Packit 8462d6
    if [[ $BASH_SOURCE == */* ]]; then
Packit 8462d6
        dirs+=( "${BASH_SOURCE%/*}/completions" )
Packit 8462d6
    else
Packit 8462d6
        dirs+=( ./completions )
Packit 8462d6
    fi
Packit 8462d6
Packit 8462d6
    for dir in "${dirs[@]}"; do
Packit 8462d6
        for compfile in "${cmd##*/}" "${cmd##*/}".bash _"${cmd##*/}"; do
Packit 8462d6
            compfile="$dir/$compfile"
Packit 8462d6
            # Avoid trying to source dirs; https://bugzilla.redhat.com/903540
Packit 8462d6
            [[ -f "$compfile" ]] && . "$compfile" &>/dev/null && return 0
Packit 8462d6
        done
Packit 8462d6
    done
Packit 8462d6
Packit 8462d6
    return 1
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# set up dynamic completion loading
Packit 8462d6
_completion_loader()
Packit 8462d6
{
Packit 8462d6
    # $1=_EmptycmD_ already for empty cmds in bash 4.3, set to it for earlier
Packit 8462d6
    local cmd="${1:-_EmptycmD_}"
Packit 8462d6
Packit 8462d6
    __load_completion "$cmd" && return 124
Packit 8462d6
Packit 8462d6
    # Need to define *something*, otherwise there will be no completion at all.
Packit 8462d6
    complete -F _minimal -- "$cmd" && return 124
Packit 8462d6
} &&
Packit 8462d6
complete -D -F _completion_loader
Packit 8462d6
Packit 8462d6
# Function for loading and calling functions from dynamically loaded
Packit 8462d6
# completion files that may not have been sourced yet.
Packit 8462d6
# @param $1 completion file to load function from in case it is missing
Packit 8462d6
# @param $2... function and its arguments
Packit 8462d6
_xfunc()
Packit 8462d6
{
Packit 8462d6
    set -- "$@"
Packit 8462d6
    local srcfile=$1
Packit 8462d6
    shift
Packit 8462d6
    declare -F $1 &>/dev/null || {
Packit 8462d6
        __load_completion "$srcfile"
Packit 8462d6
    }
Packit 8462d6
    "$@"
Packit 8462d6
}
Packit 8462d6
Packit 8462d6
# source compat completion directory definitions
Packit 8462d6
compat_dir=${BASH_COMPLETION_COMPAT_DIR:-/etc/bash_completion.d}
Packit 8462d6
if [[ -d $compat_dir && -r $compat_dir && -x $compat_dir ]]; then
Packit 8462d6
    for i in "$compat_dir"/*; do
Packit 8462d6
        [[ ${i##*/} != @($_backup_glob|Makefile*|$_blacklist_glob) \
Packit 8462d6
            && -f $i && -r $i ]] && . "$i"
Packit 8462d6
    done
Packit 8462d6
fi
Packit 8462d6
unset compat_dir i _blacklist_glob
Packit 8462d6
Packit 8462d6
# source user completion file
Packit 8462d6
user_completion=${BASH_COMPLETION_USER_FILE:-~/.bash_completion}
Packit 8462d6
[[ ${BASH_SOURCE[0]} != $user_completion && -r $user_completion ]] \
Packit 8462d6
    && . $user_completion
Packit 8462d6
unset user_completion
Packit 8462d6
Packit 8462d6
unset -f have
Packit 8462d6
unset have
Packit 8462d6
Packit 8462d6
set $BASH_COMPLETION_ORIGINAL_V_VALUE
Packit 8462d6
unset BASH_COMPLETION_ORIGINAL_V_VALUE
Packit 8462d6
Packit 8462d6
# ex: filetype=sh