Skip to content

Instantly share code, notes, and snippets.

@haxwithaxe
Last active September 25, 2022 12:52
Show Gist options
  • Save haxwithaxe/61788dbdb797872d421e74ec4b374601 to your computer and use it in GitHub Desktop.
Save haxwithaxe/61788dbdb797872d421e74ec4b374601 to your computer and use it in GitHub Desktop.
Bash completion for aliases of python argcomplete scripts

Simple

This is a bash completion function for program example that can be set for any alias:

_example_alias_argcomplete() {
    alias_value="ansible -i"
    alias_name="ans"
    offset=$(( ${#alias_value}-${#alias_name} ))
    COMP_LINE="${COMP_LINE/$alias_name /$alias_value }"
    (( COMP_POINT+=${offset} ))
    local IFS=$'\013'
    local SUPPRESS_SPACE=0
    if compopt +o nospace 2> /dev/null; then
        SUPPRESS_SPACE=1
    fi
    COMPREPLY=( $(IFS="$IFS" \
                  COMP_LINE="$COMP_LINE" \
                  COMP_POINT="$COMP_POINT" \
                  COMP_TYPE="$COMP_TYPE" \
                  _ARGCOMPLETE_COMP_WORDBREAKS="$COMP_WORDBREAKS" \
                  _ARGCOMPLETE=1 \
                  _ARGCOMPLETE_SUPPRESS_SPACE=$SUPPRESS_SPACE \
                  __python_argcomplete_run "ansible") )
    if [[ $? != 0 ]]; then
        unset COMPREPLY
    elif [[ $SUPPRESS_SPACE == 1 ]] && [[ "${COMPREPLY-}" =~ [=/:]$ ]]; then
        compopt -o nospace
    fi
}

To use this function run the following:

complete -o bashdefault -o default -o nospace -F _example_alias_argcomplete ans
alias ans="ansible -i"

Fancy

This function creates an alias with a completion function set for the given alias and program.

_argcomplete_with_alias() {
    local alias_name="$1"
    shift
    local real_exec="$1"
    local alias_value="$@"
    local offset=$(( ${#alias_value}-${#alias_name} ))
    completion_func="__${alias_name}_argcomplete() {
        COMP_LINE=\"\${COMP_LINE/$alias_name /$alias_value }\"
        (( COMP_POINT+=${offset} ))
        local IFS=$'\\013'
        local SUPPRESS_SPACE=0
        if compopt +o nospace 2> /dev/null; then
            SUPPRESS_SPACE=1
        fi
        COMPREPLY=( \$(IFS=\"\$IFS\" \
                      COMP_LINE=\"\$COMP_LINE\" \
                      COMP_POINT=\"\$COMP_POINT\" \
                      COMP_TYPE=\"\$COMP_TYPE\" \
                      _ARGCOMPLETE_COMP_WORDBREAKS=\"\$COMP_WORDBREAKS\" \
                      _ARGCOMPLETE=1 \
                      _ARGCOMPLETE_SUPPRESS_SPACE=\$SUPPRESS_SPACE \
                      __python_argcomplete_run \"${real_exec}\") )
        if [[ \$? != 0 ]]; then
            unset COMPREPLY
        elif [[ \$SUPPRESS_SPACE == 1 ]] && [[ \"\${COMPREPLY-}\" =~ [=/:]$ ]]; then
            compopt -o nospace
        fi
    }"
    eval "$completion_func"
    complete -o bashdefault -o default -o nospace -F __${alias_name}_argcomplete $alias_name
    alias "$alias_name"="$alias_value"
}

Examples

Simple

$ _argcomplete_with_alias ans ansible
$ ans -<tab><tab>
-a                          --connection                -l                          --syntax-check
...
$ ans -

Less Simple

$ _argcomplete_with_alias apbt ansible-playbook --become -i 
$ apbt <tab><tab>
...
test_inventory
...
$ apbt test<tab>
$ apbt test_inventory
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment