bash-completion is 便利。
bash-completion って便利ですよね。zsh ユーザには興味のない話かもしれないけど、、zsh に比べ bash はどこでも使えるので便利なんですよね。
brew install bash-completion
また、各コマンドのcompletion もbrew や apt で一緒に入ってくれる。
最近だと、インストールすれば使えるようになっていてナニも考えなくてもイイようになってる。
自分で作ったコマンドはどうするか?
自分で作ったコマンドにも補完機能欲しいじゃん?となると自分で補完も定義することになる。zsh はこの辺たしか自動処理してくれたと思うんだけどね。
自分で作るのめんどくさい?→結構簡単
ぱぱっと読んだだけで、自分で補完機能が簡単に定義できることが分かった。
早速作ってみることに
とりあえず、独自コマンドの代わりに、bash で関数を定義し、関数の引数を補完するようにしてみる。
ステップ1:補完リストを定義して補完する
手順はこんな感じ
- 関数作って(実験用)
- 補完関数作って
- 補完関数をロードして
- 補完関数を試す。
関数と補完関数を作る
completion_test.sh
### 引数をecho するだけの簡単な関数。 function folder() { echo $@ } ### 補完関数。 _folders(){ COMPREPLY=( takuya hatenablog hello completion ) } ### 補完関数と関数の関連付け complete -F _folders folder
関数をロード
takuya@~/temp$ source completion_test.sh
使ってみる
takuya@~/temp$ folder takuya@~/temp$ folder <TAB> takuya hatenablog hello world
おおおおお、補完された
ステップ2:補完リストを動的にしてみる。
このままだと、詰まらないし。いつでも固定の補完しか出来ない。
補完関数の中でコマンドをCallして補完の内容がその時の最新のフォルダ一覧になるようにしてみる。
補完関数の候補の改良
とりあえず、ls の結果を補完に表示してみよう。
### 補完関数。 _folders(){ COMPREPLY=( $( ls ~ ) ) }
このように書いて source コマンドで関数をリロードする。
実際に使ってみると。。。
実際にコマンド補完を実行してみる。すると$HOMEの内容がズラズラと出てくるようになる。
takuya@~/temp$ folder Applications Documents Dropbox Movies Pictures Sites temp Desktop Downloads Library Music Public repos work
これで、補完っぽくなってきた。
ステップ3:入力途中で絞込
ここ迄で補完候補が出るようになったけれど、まだ補完とは言い切れない。
それは入力途中の文字で絞込ができないから。
takuya@~/temp$ folder Do<TAB> Applications Documents Dropbox Movies Pictures Sites temp Desktop Downloads Library Music Public repos work
Do
入力中の文字で絞込処理を書く
### 補完関数。 _folders(){ COMPREPLY=( $(compgen -W "$(ls ~)" ${COMP_WORDS[COMP_CWORD]} ) ) }
compgen -W で絞込した結果を候補に出るようにする。この時に入力途中の文字は 変数から取得する。
これで補完処理になる。
takuya@~/temp$ folder D<TAB> Desktop Documents Downloads Dropbox
これで補完処理になる。
出来たコマンドの置き場所
bash-completion は /etc/bash-completion.d/ に保存すれば、自動的にロードされるようになっている。
それは、bash-completion ば .bashrc で読み込まれるように記述されているため
bashrc
bashrc 中に次のような記述がある。
if [ -f /etc/bash_completion ]; then . /etc/bash_completion fi
ちなみに homebrew 環境下の場合は次のようになっている。
brew_prefix=`brew --prefix` # enable programmable completion features (you don't need to enable # this, if it's already enabled in /etc/bash.bashrc and /etc/profile # sources /etc/bash.bashrc). if [ -f ${brew_prefix}/etc/bash_completion ]; then source ${brew_prefix}/etc/bash_completion fi
さらに/etc/bash-completion/
には、次のように記述されており
# source user completion file [[ $BASH_COMPLETION != ~/.bash_completion && -r ~/.bash_completion ]] \ && . ~/.bash_completion unset -f have unset UNAME USERLAND have
ということで、自作のbash補完関数の保管場所は次の通り。
~/.bash_completion ## 個人用 /etc/bash-completion.d/ ## システム用
に置けば大丈夫。
もちろん、.bashrc に直接書いても問題ないんだけどね。
サブコマンド。
git add ファイル名 git commit -m "コミットログ"
のようにサブコマンドを取るものも、Completionでは定義可能。なのだが、自作コマンドの補完でソコまですることは殆ど無いので。サブコマンドについては参考資料にURLを貼っておくことにする。
自分でちょっと便利に使うためのコマンドでサブコマンドも作りこむことはまぁ少ないよな。
参考資料
bash-completionで独自の補完関数を作成する方法(gistyのサブコマンドを補完するやつ書いてみた) - 今日もスミマセン。