bash 補完 メモ


基本骨格

hoge() {
    echo $1
}
hoge_completion() {
    local cur prev cword opts
    _get_comp_words_by_ref -n : cur prev cword
    opts="foo bar baz"
    COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
}
complete -F hoge_completion hoge

$curは現在のワード、
$prevは直前のワード、
$cwordは現在のワードのインデックスを意味します。

compgen関数は、-fでファイルの補完、-dでディレクトリの補完、-cでコマンドの補完ができます。

小技

COMP_WORDSのインデックスアクセス

COMP_WORDSという変数にワードリストが格納されているため、

set ${COMP_WORDS[@]}

とすると、$1のようにして各ワードにアクセスできます。

動的ファイルパス補完(カレントディレクトリ)

hoge_completion() {
    local cur prev cword opts
    _get_comp_words_by_ref -n : cur prev cword
    dir="$(echo ${cur} | grep -o ".*/")"
    if test "${dir}" ;then
        COMPREPLY=( $(compgen -W "$(ls -F ${dir} | sed -E "s@(.*)@${dir}\1@g")" -- "${cur}") )
    else 
        COMPREPLY=( $(compgen -W "$(ls -F)" -- "${cur}") )
    fi
}
complete -o nospace -F hoge_completion hoge

動的ファイルパス補完(ベースディレクトリ指定)

hoge_completion() {
    local cur prev cword opts
    _get_comp_words_by_ref -n : cur prev cword
    dir="$(echo ${cur} | grep -o ".*/")"
    if test "${dir}" ;then
        COMPREPLY=( $(compgen -W "$(ls -F $HOME/events/${dir} | sed -E "s@(.*)@${dir}\1@g")" -- "${cur}") )
    else 
        COMPREPLY=( $(compgen -W "$(ls -F $HOME/events/)" -- "${cur}") )
    fi
}
complete -o nospace -F hoge_completion hoge

動的ファイルパス補完(ディレクトリのみ)

r() {
    cd $HOME/repos/$1
}
r_completion() {
    local cur prev cword opts
    _get_comp_words_by_ref -n : cur prev cword
    dir="$(echo ${cur} | grep -o ".*/")"
    if test "${dir}" ;then
        COMPREPLY=( $(compgen -W "$(ls -F $HOME/repos/${dir} | sed -E "s@(.*)@${dir}\1@g" | grep -o ".*/$")" -- "${cur}") )
    else 
        COMPREPLY=( $(compgen -W "$(ls -F $HOME/repos/ | grep -o ".*/$")" -- "${cur}") )
    fi
}
complete -o nospace -F r_completion r