初めてのオレオレbash補完
さて、ひとつ前のエントリは釣りだったわけですが、本題の bash 補完を初めてやってみました。ちょっとした物だったら割と簡単に書けたので、共有。
目標
自作コマンド(仮にsugyan
とします)はこんな感じの I/F だとします。
-
sugyan subcommand [args]
-
いくつかの subcommand は次にくる引数が限られる
- 例えば
sugyan momoclo
の後にはkanako renichan shiorin ahrin momoka
- 例えば
-
sugyan list
でそういう補完の一覧が色々出せるsugyan list command
で subcommand の一覧sugyan list momoclo
でももクロ一覧- 一応
sugyan list
でcommand momoclo
が返る
-
あとはいつもの bash のままにファイルとかを補完して欲しい
-
実際叩くと、
$ sugyan list
command momoclo
$ sugyan list command
momoclo list help
$ sugyan list momoclo
kanako renichan shiorin ahrin momoka
$ sugyan momoclo ahrin
love love love
こんな感じのコマンドに対して
$ sugyan [TAB]
momoclo list help
$ sugyan momoclo [TAB]
kanako renichan shiorin ahrin momoka
的な補完を作りたいとします。
こんな感じ
PATH にsugyan
が通ってる前提で(前のエントリ参照)、以下のような bashrc を読み込んであげればいい感じになります。
解説(間違ってたらすいませんすいません><)
まず 22 行目のcomplete
という関数が bash の組み込みで、補完するための色々をしてくれるようです。-F
で実際に補完する関数として直前で定義したものを指定しています。また、オプションでdefault
を与えておくとマッチするものがなかった時にデフォルトの挙動をしてくれます(bashdefault
の方はよく分かってませんが一応書いてます!)
で、実際の補完する関数の中身ですが、COMP_WORDS
という配列の中にコマンドラインの引数が入ってて、今どこにいるかをCOMP_CWORD
が示しているので、5,6 行目で現在と一個前を取得してます。これらを使って、COMPRELY
という配列に補完候補をぶち込んであげればいい感じです。
で、まずそもそも subcommand 一覧を出すために、COMP_CWORD
が 1 の時はsugyan list command
を実行した結果を使います。一旦変数に格納して、その後compgen
という組み込み関数で実際の補完結果にしてます。-W
というオプションは候補をスペース区切り?のリストで渡しつつ、cur
も渡してあげるとよしなに補完対象を選んでくれます。
あとはmomoclo
とlist
についてはさらに補完対象が絞られるので同じことを次のelif
の中でやってます。
おわりに
やってみたら意外と簡単でした。補完対象とかは、大抵自分で作ったコマンドが知ってると思いますので、一覧を出すようなオプションを準備してあげると簡単に bash 補完が作れます。
もっと込み入ったことをやりたい場合、色々ググってみたり、bash_completion とか、git のやつとかを参考にするといいと思います。