Blame clients/cli/nmcli-completion

Packit Service b23acc
# nmcli(1) completion
Packit Service b23acc
Packit Service b23acc
_nmcli_array_delete_at()
Packit Service b23acc
{
Packit Service b23acc
    eval "local ARRAY=(\"\${$1[@]}\")"
Packit Service b23acc
    local i
Packit Service b23acc
    local tmp=()
Packit Service b23acc
    local lower=$2
Packit Service b23acc
    local upper=${3:-$lower}
Packit Service b23acc
Packit Service b23acc
    # for some reason the following fails. So this clumsy workaround...
Packit Service b23acc
    #   A=(a "")
Packit Service b23acc
    #   echo " >> ${#A[@]}"
Packit Service b23acc
    #    >> 2
Packit Service b23acc
    #   A=("${A[@]:1}")
Packit Service b23acc
    #   echo " >> ${#A[@]}"
Packit Service b23acc
    #    >> 0
Packit Service b23acc
    # ... seriously???
Packit Service b23acc
Packit Service b23acc
    for i in "${!ARRAY[@]}"; do
Packit Service b23acc
        if [[ "$i" -lt "$2" || "$i" -gt "${3-$2}" ]]; then
Packit Service b23acc
            tmp=("${tmp[@]}" "${ARRAY[$i]}")
Packit Service b23acc
        fi
Packit Service b23acc
    done
Packit Service b23acc
    eval "$1=(\"\${tmp[@]}\")"
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
_nmcli()
Packit Service b23acc
{
Packit Service b23acc
    local cur words cword i output
Packit Service b23acc
    _init_completion || return
Packit Service b23acc
Packit Service b23acc
    # we don't care about any arguments after the current cursor position
Packit Service b23acc
    # because we only parse from left to right. So, if there are some arguments
Packit Service b23acc
    # right of the cursor, just ignore them. Also don't care about ${words[0]}.
Packit Service b23acc
    _nmcli_array_delete_at words $((cword+1)) ${#words[@]}
Packit Service b23acc
    _nmcli_array_delete_at words 0
Packit Service b23acc
Packit Service b23acc
    # _init_completion returns the words with all the quotes and escaping
Packit Service b23acc
    # characters. We don't care about them, drop them at first.
Packit Service b23acc
    for i in ${!words[@]}; do
Packit Service b23acc
        words[i]="$(printf '%s' "${words[i]}" | xargs printf '%s\n' 2>/dev/null || true)"
Packit Service b23acc
    done
Packit Service b23acc
Packit Service b23acc
    # In case the cursor is not at the end of the line,
Packit Service b23acc
    # $cur consists of spaces that we want do remove.
Packit Service b23acc
    # For example: `nmcli connection modify id  <TAB>  lo`
Packit Service b23acc
    if [[ "$cur" =~ ^[[:space:]]+ ]]; then
Packit Service b23acc
        cur=''
Packit Service b23acc
    fi
Packit Service b23acc
Packit Service b23acc
    output="$(nmcli --complete-args "${words[@]}" 2>/dev/null)"
Packit Service b23acc
Packit Service b23acc
    # Bail out early if we're completing a file name
Packit Service b23acc
    if [ $? = 65 ]; then
Packit Service b23acc
        compopt -o default
Packit Service b23acc
        COMPREPLY=()
Packit Service b23acc
        return 0
Packit Service b23acc
    fi
Packit Service b23acc
Packit Service b23acc
    local IFS=$'\n'
Packit Service b23acc
    COMPREPLY=( $( compgen -W '$output' -- $cur ) )
Packit Service b23acc
Packit Service b23acc
    # Now escape special characters (spaces, single and double quotes),
Packit Service b23acc
    # so that the argument is really regarded a single argument by bash.
Packit Service b23acc
    # See http://stackoverflow.com/questions/1146098/properly-handling-spaces-and-quotes-in-bash-completion
Packit Service b23acc
    local escaped_single_quote="'\''"
Packit Service b23acc
    local i=0
Packit Service b23acc
    local entry
Packit Service b23acc
    for entry in ${COMPREPLY[*]}
Packit Service b23acc
    do
Packit Service b23acc
        if [[ "${cur:0:1}" == "'" ]]; then
Packit Service b23acc
            # started with single quote, escaping only other single quotes
Packit Service b23acc
            # [']bla'bla"bla\bla bla --> [']bla'\''bla"bla\bla bla
Packit Service b23acc
            COMPREPLY[$i]="${entry//\'/${escaped_single_quote}}"
Packit Service b23acc
        elif [[ "${cur:0:1}" == '"' ]]; then
Packit Service b23acc
            # started with double quote, escaping all double quotes and all backslashes
Packit Service b23acc
            # ["]bla'bla"bla\bla bla --> ["]bla'bla\"bla\\bla bla
Packit Service b23acc
            entry="${entry//\\/\\\\}"
Packit Service b23acc
            entry="${entry//\"/\\\"}"
Packit Service b23acc
            entry="${entry//!/\"\\!\"}"
Packit Service b23acc
            COMPREPLY[$i]="$entry"
Packit Service b23acc
        else
Packit Service b23acc
            # no quotes in front, escaping _everything_
Packit Service b23acc
            # [ ]bla'bla"bla\bla bla --> [ ]bla\'bla\"bla\\bla\ bla
Packit Service b23acc
            entry="${entry//\\/\\\\}"
Packit Service b23acc
            entry="${entry//\'/\'}"
Packit Service b23acc
            entry="${entry//\"/\\\"}"
Packit Service b23acc
            entry="${entry// /\\ }"
Packit Service b23acc
            entry="${entry//\(/\\(}"
Packit Service b23acc
            entry="${entry//)/\\)}"
Packit Service b23acc
            entry="${entry//!/\\!}"
Packit Service b23acc
            entry="${entry//&/\\&}"
Packit Service b23acc
            COMPREPLY[$i]="$entry"
Packit Service b23acc
        fi
Packit Service b23acc
        (( i++ ))
Packit Service b23acc
    done
Packit Service b23acc
Packit Service b23acc
    # Work-around bash_completion issue where bash interprets a colon
Packit Service b23acc
    # as a separator.
Packit Service b23acc
    # Colon is escaped here. Change "\\:" back to ":".
Packit Service b23acc
    # See also:
Packit Service b23acc
    # http://stackoverflow.com/questions/28479216/how-to-give-correct-suggestions-to-tab-complete-when-my-words-contains-colons
Packit Service b23acc
    # http://stackoverflow.com/questions/2805412/bash-completion-for-maven-escapes-colon/12495727
Packit Service b23acc
    i=0
Packit Service b23acc
    for entry in ${COMPREPLY[*]}
Packit Service b23acc
    do
Packit Service b23acc
        entry="${entry//\\\\:/:}"
Packit Service b23acc
        COMPREPLY[$i]=${entry}
Packit Service b23acc
        (( i++ ))
Packit Service b23acc
    done
Packit Service b23acc
Packit Service b23acc
} &&
Packit Service b23acc
complete -F _nmcli nmcli
Packit Service b23acc
Packit Service b23acc
# ex: ts=4 sw=4 et filetype=sh