Basics

Most Debian installed bash completions live under /usr/share/bash_completion/completions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# the first argument ($1) is the name of the command whose  arguments are being completed
# the second argument ($2) is the word being completed,
# and the third argument ($3) is the word preceding the word  being  completed  on the current command line
# In the context of this function the following variables are defined:
# COMP_LINE, COMP_POINT, COMP_KEY, and COMP_TYPE
# as well as COMP_WORDS and COMP_CWORD
#  It must put the possible completions in the COMPREPLY array
# See bash(1) '^  Programmable Completion' for more information
_some_function() {
  local cur cmd
  cur=${COMP_WORDS[$COMP_CWORD]}
  cmd=( "${COMP_WORDS[@]}" )
}
complete -F _some_function command

complete options

Some complete options you want:

  • -o bashdefault - if no completions are found do the bash default thing
  • -o default - readline completions if both the complete function and bash expansions fail
  • -o nospace - don’t append a space at the end of matches (useful if you’re doing directory stuffs)
  • -S or -P - a prefix or suffix that is added at the end of a completion generated by the function passed to complete -F

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# Many of the ideas presented in this script were stolen
# in-part or wholesale from
# <https://github.com/git/git/blob/master/contrib/completion/git-completion.bash>
__scap_subcommands=
__scap_get_subcommands() {
    if [ -n "$__scap_subcommands" ]; then
        return
    fi

    __scap_subcommands=$(scap --_autocomplete)
}

_scap() {
    local cur cmd=() sub rep

    cur=${COMP_WORDS[$COMP_CWORD]}
    cmd=( "${COMP_WORDS[@]}" )

    if (( COMP_CWORD == 1 )); then
        __scap_get_subcommands
        rep=$( compgen -W "$__scap_subcommands" -- "$cur" )
        COMPREPLY=( $rep )
        return
    fi

    # limit the command to autocomplete to the first 3 words
    if (( COMP_CWORD >= 2 )); then
        # don't complete any sub-subcommands, only options
        if <span class="createlink"><a href="//ikiwiki.tylercipriani.com/cgi?do=create&amp;from=blog%2F2016%2F08%2F30%2Fbash-completion&amp;page=_-n___34____36__cur__34_____38____38_____34____36____123__cur%3A0%3A1__125____34_____33____61_____39__-__39___" rel="nofollow">?</a> -n &#34;&#36;cur&#34; &#38;&#38; &#34;&#36;&#123;cur:0:1&#125;&#34; &#33;&#61; &#39;-&#39; </span>; then
            COMPREPLY=()
            return
        fi
        cmd=( "${COMP_WORDS[@]:0:3}" )
    fi

    # replace the last word in the command with '--_autocomplete'
    cmd[ $(( ${#cmd[@]} - 1 )) ]='--_autocomplete'

    rep=$( compgen -W "$( ${cmd[@]} )" -- "$cur" )

    COMPREPLY=( $rep )
}

# By default append nospace except when completion comes from _scap
complete -S' ' -o bashdefault -o default -o nospace -F _scap scap