bash-completionと自作シェルその後

Thu Mar 6 10:40:57 JST 2025 (modified: Thu Mar 6 12:27:36 JST 2025)
views: 115, keywords:自作シェル, sush, 寿司シェル, bash-completion

 前回、bash-completionが動いたと書いたんですが、当然「動いた」と「使える」は違うわけでいろいろ直していました。で、やっと自分で使ってまあこんなもんかなというところまできたのでまたメモを書いておきます。

gitの補完の謎

 まずあのあと、gitの後のサブコマンド(addbranchとかのアレ)の補完ができないかいろいろ調べていました。どのコマンドがどんなふうに補完されるかは、Bashではcompleteというコマンドで調査できます。次の例はLinuxのBashの例です。

### Bashの例 ###
   $ complete | head -n 3
   complete -F _longopt mv
   complete -F _root_command gksudo
   complete -F _command nice

出力の読み方は、たとえば1行目については「mv_longoptという関数をつかって補完候補を見つける」というふうに読みます。_longoptというのはコマンドのロングオプション(とファイル)を探す関数で、Bashがbash-completionを読み込んだときに一緒に読み込まれます。

 ということは、gitの補完方法についてはcomplete | grep gitとすれば探せるはずですが、立ち上げたばかりのBashの場合、

### Bashの例 ###
   $ complete | grep git
   $      #何も出てこない

というように空振ります。

 じゃあどうやって補完しているんだという話になりますが、1回gitで補完をしてcompleteの出力を調べると、

### Bashの例 ###
   $ git <tab> #←なにか補完を試みる(なんでもよい)
   $ complete | grep git
   complete -o bashdefault -o default -o nospace -F __git_wrap__gitk_main gitk
   complete -o bashdefault -o default -o nospace -F __git_wrap__git_main /usr/bin/git
   complete -o bashdefault -o default -o nospace -F __git_wrap__git_main git

というように、しれっとgitの項目ができているのがわかります。

補完機能の自動ロード

 ということは自動で補完機能がロードされているということになります。で、どうやってということになるんですが、「デフォルトの補完機能」というものがあり、これを調べると手がかりになります。

### Bashの例 ###
   $ complete | grep 'complete .* -D'
   complete -F _comp_complete_load -D

これは「補完対象に対応する補完機能が見当たらない場合、_comp_complete_loadで補完しろ」ということを意味します。で、_comp_complete_loadがなにかやってるなということになります。実際、コマンドに対応する機能をロードしているのはこの関数から呼ばれている_comp_loadです。_comp_loadのコードはここで読めます。めっちゃ長いですが。わたしは読みましたよ。読んだというか自分の作っているシェルに文法全部理解させましたよ。ええ。死ぬ。

ということで

 自作シェルでもcomplete -Dの関数が呼ばれるようにして、このたびめでたくgitの補完ができるようになりました。やってることがまともではないので誰も褒めてくれませんが褒めて褒めて。

 _comp_complete_loadが呼ばれている様子です。

### 自作シェルの例 ###
   $ sush
   Rusty Bash (a.k.a. Sushi shell), version 1.0.4 - release
   🍣 complete | grep git
   🍣 git a                          #なんか補完してみる
   add      am       archive  apply
                         ^C
   🍣 complete | grep git
   complete -F __git_wrap__gitk_main gitk
   complete -F __git_wrap__git_main git    #セットされている
   #今後の課題: ほんとはもうひとつ読み込まれるはずだけど読み込まれていない#

さらにその後

gitに気をとられてたらcdとかvimとかの補完がうまく動かなくなったことに気づいて直してました。いまは直したものが最新のリリースになっているので使ってみてissueに文句でも書いていただければ幸いです。

現場からは以上です。

ノート   このエントリーをはてなブックマークに追加 
 

prev:自作シェルでbash-completionが動き始めた next:bash-completionと自作シェルその後

やり散らかし一覧

記事いろいろ