thor で作ったコマンドラインツールの zsh 用補完スクリプトを生成する gem を作りました

thor は、サブコマンドを持つコマンドラインツールを作成するのに便利ですが、オプションやサブコマンドが増えてくると、補完したくなってきます。とはいえ、zsh 用の補完スクリプトを書くのはなかなか面倒です (たまにしか書かないから忘れるし)。

thor はオプションやサブコマンドの情報を保持しているはずなので、そこから補完用のスクリプトが生成できたら便利だろうと思って作りました。

機能

作成できる補完スクリプトは下記のようなものです。

  • ネストしたもの (knife solo cook みたいな) も含めサブコマンドの補完ができます。
  • オプション (-n--name など) の補完ができます。
  • サブコマンド、オプションの引数の補完はできません。すべてファイルとして補完します。

使い方

インストールは gem install thor-zsh_completion で。 ハイフンとアンダースコアがあるので注意。

サブコマンドで補完スクリプトを生成する場合は Thor のサブクラスで include Thor::ZshCompletion::Command してください。

require "thor"
require "thor/zsh_completion"

class MyCommand < Thor
  include Thor::ZshCompletion::Command
  ...
end

MyCommand.start(ARGV)

zsh-completion というサブコマンドが追加されます。

$ ./my_command.rb zsh-completion

--name, -n オプションでコマンド名を指定できます。

$ ./my_command.rb -n my_command zsh-completion

これで出力されるスクリプトを fpath のどこかに _コマンド名 で保存すれば OK です。

$ ./my_command.rb -n my_command zsh-completion > /path/to/fpath/_my_command

サブコマンド追加したくない、補完スクリプト書き換えたい、他人の作ったコマンドの補完スクリプト作りたいなどの場合は、下記のようにすれば文字列で返すので、あとはお好きにどうぞ。

require "thor"
require "thor/zsh_completion"

class MyCommand < Thor
  ...
end

script = Thor::ZshCompletion::Generator.new(MyCommand, "コマンド名").generate

出力例

出力例を載せようと思ったけど長いので gist に置きました (下のほうに Ruby のコードがあります)。

参考文献

zsh の補完スクリプトの書き方については、下記の情報が参考になりました。ありがとうございます。