ターミナルのコマンド自動補完の設定について

3 min read読了の目安(約2800字

動機

Dockerのコマンド補完をzshで設定しようと思ったのですが、公式サイトの設定方法を確認したところzshの場合はoh-my-zshとそうでない場合にわかれていて、後者を設定してもcompletion(自動補完)が設定できませんでした。

そもそもcompletionの設定ってどのようにやっているんだろう?と疑問に思い調べたので、設定方法も含めて載せます。

completionとは

自動補完のことです。
例えば、ターミナルで githerokuなどのコマンドを打ち込んでtabを押すと

$ git 

 -- common commands --
add       -- add file contents to the index
bisect    -- find by binary search the change that introduced a bug
branch    -- list, create, or delete branches
...

のように、次に打ち込むべきコマンドを表示してくれます。

どうやって自動補完を設定しているのか

では、なぜ gitと打ちこんでtabを押すと自動補完が表示されるのでしょうか。
されるものとされないものの違いは?

下記フォルダを確認してみてください。

/usr/local/share/zsh/site-functions

すると

$ ll /usr/local/share/zsh/site-functions 

lrwxr-xr-x  1 admin  56  1 19 16:20 _git@ -> ../../../Cellar/git/2.30.0/share/zsh/site-functions/_git
lrwxr-xr-x  1 admin  56  7 21  2020 _hub@ -> ../../../Cellar/hub/2.14.2/share/zsh/site-functions/_hub
lrwxr-xr-x  1 admin  62  1 19 16:22 _heroku@ -> ../../../Cellar/heroku/7.47.7/share/zsh/site-functions/_heroku

のように、_git_hubなどといったファイルがあり、各ソフトの内部にある_gitや_hubといったcompletionの設定ファイルにシンボリックリンクが貼られています。

この設定があるからこそ、自動補完が可能になります。
試しにファイル名を_gitから_giなどにmvしてみてください。gitでの自動補完が効かなくなります。

Dockerの場合どうするべきか

であるなら、ゴールは見えました。

1. dockerのcompletion設定ファイルを用意する
2. site-functionsフォルダに_dockerを作成する
3. 1に2へのシンボリックリンクを貼る

実際に設定してみます。

1. 設定ファイルを用意する

まずずはcompletion設定ファイルを用意します。といいたいのですが、実はDocker内部にdocker/docker-composeの設定ファイルが既に存在します。
パスは下記かとおもいますが、違っていたら/Application内で探してみてください。

/Applications/Docker.app/Contents/Resources/etc

僕の場合、下記のように設定ファイルが存在しています。

ll /Applications/Docker.app/Contents/Resources/etc 

-rwxr-xr-x@ 1 admin   13367  3  5 18:45 docker-compose.bash-completion*
-rw-r--r--@ 1 admin    1895  3  5 18:45 docker-compose.fish-completion
-rw-r--r--@ 1 admin   18170  3  5 18:45 docker-compose.zsh-completion
-rwxr-xr-x@ 1 admin  116318  3  5 18:45 docker.bash-completion*
-rwxr-xr-x@ 1 admin   52077  3  5 18:45 docker.fish-completion*
-rwxr-xr-x@ 1 admin  130482  3  5 18:45 docker.zsh-completion*

2. シンボリックリンクを作成する

ファイル作成なのでtouchをしたくなりますが、lnでシンボリックリンクを作成するときに
ファイルがなければ自動生成されるので、touchは行いません。

docker=/Applications/Docker.app/Contents/Resources/etc

// docker
ln -s $docker/docker.zsh-completion /usr/local/share/zsh/site-functions/_docker

// docker-compose
ln -s $docker/docker-compose.zsh-completion /usr/local/share/zsh/site-functions/_docker-compose

結果

これで自動補完が使えるようになりました。

$ docker 

 -- docker command --
app*       -- Docker App (Docker Inc., v0.9.1-beta3)
attach     -- Attach local standard input, output, and error streams to a running container
build      -- Build an image from a Dockerfile

まとめ

/usr/local/share/zsh/site-functionsのファイルと自動補完設定ファイルを
シンボリックリンクで紐付けることで、自動補完ができるようになる