templerのコマンドのbash completion作ってみる

はじめに

templer使おうとしたけれどコマンド入力するのが面倒になったのでbashの補完を作成してみる。

step0 about complete

completeという関数を利用して補完候補を設定するらしい。

bash: complete: -h: invalid option
complete: usage: complete [-abcdefgjksuv] [-pr] [-DE] [-o option] [-A action] [-G globpat] [-W wordlist]  [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]

ubuntuでは/etc/bash_completion.d以下に現在のbashの環境で補完に使われている設定が置かれてい模様。
覗いてて見たところ、補完の候補を表示する関数を定義し、complete -Fを使っているものが多かった。

completeの引数に渡せるのに以下のようなものがある。(詳しい情報はman bash)

-W 直接指定した文字列の中から絞り込み
-F 指定した関数を実行した結果から絞り込み

ためしに補完を作ってみる。

以下は、wheeというコマンドを定義し、その補完候補に[foo,bar,boo]を設定する場合の例。

touch ~/bin/whee #~/binに$PATHが通っている
chmod -c u+x ~/bin/whee 
complete -W "foo bar boo" whee

このようにすると、シェル上でwheeとタブを押下した際に、foo,bar,booを補完候補として表示してくれる。

step1 全候補表示

templerの候補は以下のようにして絞り込める

templer --list | grep ":" | cut -d ":" -f 1

というわけで、以下のようにしてtemplerの補完を追加できる

_templer(){
  COMPREPLY=($(templer --list | grep ":" | cut -d ":" -f 1 ))
}
complete -F _templer templer

関数の中でCOMPREPLYという変数に代入された値が補完候補として扱われるらしい。
ただ、現状では、補完候補として表示されるものの補完はしてくれない

step2 実際に補完してもらう。(compgen)

補完はcompgenがやってくれるらしい。以下のように変える。

_templer(){
  local cur
  cur=${COMP_WORDS[COMP_CWORD]}	
  COMPREPLY=($( compgen -W "`templer --list | grep ':' | cut -d ':' -f 1`" -- $cur))
}
complete -F _templer templer

ただ、現状では、-付きのオプションなどを補完してくれない。

step3 -の引数に対応

あとはbashのプログラミング

_templer(){
  local cur opts templates
  cur=${COMP_WORDS[COMP_CWORD]}	
  opts="--help --make-config-file --list --version"
  templates="`templer --list | grep ':' | cut -d ':' -f 1`"

  if [[ ${cur} == "" ]] ; then
    COMPREPLY=($( compgen -W "${opts} ${templates}" -- $cur))
  elif [[ ${cur} == -* ]] ; then
    COMPREPLY=($( compgen -W "${opts}" -- $cur))
  else   
    COMPREPLY=($( compgen -W "${templates}" -- $cur))
  fi
}
complete -F _templer templer