自作コマンドラインツールでも補完してサクサク使いたい!
ホクホク顔になりたい!
でもツールを作るたびに補完用の設定を手書きするのはめんどくさい!
という方は多いのではないでしょうか。
そんな方には @labocho さん作の thor-zsh_completion という gem があります。
※この gem は thor を前提にしています。
前提
thor って何?という方は以下をご確認ください。
Ruby の CLI ツールの作成を支援する、 thor gem の基本について
サンプル
以下のリポジトリの内容をベースに試します。
変更前
thor を使った CLI の定義部分は以下のようになっています。
lib/cli.rb
require 'thor'
# Fizzbuzz::Models
module Fizzbuzz
# CLI
#
# FizzBuzzのコマンドライン
class CLI < Thor
class_option :help, type: :boolean, aliases: '-h', desc: 'help message.'
class_option :version, type: :boolean, desc: 'version'
class_option :debug, type: :boolean, aliases: '-d', desc: 'debug mode'
desc 'fizzbuzz', 'Get fizzbuzz result from limit number'
def fizzbuzz(limit)
print Fizzbuzz.fizzbuzz(limit).join(',')
exit
rescue => e
output_error_if_debug_mode(e)
exit(false)
end
desc 'version', 'version'
def version
puts Fizzbuzz::VERSION
end
private
def output_error_if_debug_mode(e)
return unless options[:debug]
STDERR.puts(e.message)
STDERR.puts(e.backtrace)
end
end
end
変更後
- gemspec に thor-zsh_completion を追加
fizzbuzz.gemspec
# 略
spec.add_runtime_dependency 'thor-zsh_completion'
# 略
lib/cli.rb
require 'thor'
# :new: 追加
require 'thor/zsh_completion'
# Fizzbuzz::Models
module Fizzbuzz
# CLI
#
# FizzBuzzのコマンドライン
class CLI < Thor
# :new: 追加
include ZshCompletion::Command
デモ
- zsh-completion コマンドが増えます
$ fizzbuzz
Commands:
fizzbuzz fizzbuzz # Get fizzbuzz result from limit number
fizzbuzz help [COMMAND] # Describe available commands or one specific command
fizzbuzz version # version
fizzbuzz zsh-completion # Print zsh completion script
Options:
-h, [--help], [--no-help] # help message.
[--version], [--no-version] # version
-d, [--debug], [--no-debug] # debug mode
- zsh-completion コマンドを実行します
$ fizzbuzz zsh-completion
#compdef fizzbuzz
local state
_fizzbuzz() {
__fizzbuzz
}
__fizzbuzz() {
readonly local DEPTH=2
case $CURRENT in
$DEPTH)
_arguments \
'*: :->subcommands'
case $state in
subcommands)
_values \
'subcommand' \
'zsh-completion[Print zsh completion script]' \
'fizzbuzz[Get fizzbuzz result from limit number]' \
'version[version]' \
;
;;
esac
;;
*)
case $words[$DEPTH] in
zsh-completion)
__fizzbuzz_zsh-completion
;;
fizzbuzz)
__fizzbuzz_fizzbuzz
;;
version)
__fizzbuzz_version
;;
*)
# if does not match any subcommand
# complete rest arguments
_files
;;
esac
;;
esac
}
__fizzbuzz_zsh-completion() {
_arguments \
{--help,--h}help message. \
{--version}version \
{--debug,--d}debug mode \
{--name,-n} \
'*: :->rest'
case $state in
rest)
# complete rest arguments
_files
;;
esac
}
__fizzbuzz_fizzbuzz() {
_arguments \
{--help,--h}help message. \
{--version}version \
{--debug,--d}debug mode \
'*: :->rest'
case $state in
rest)
# complete rest arguments
_files
;;
esac
}
__fizzbuzz_version() {
_arguments \
{--help,--h}help message. \
{--version}version \
{--debug,--d}debug mode \
'*: :->rest'
case $state in
rest)
# complete rest arguments
_files
;;
esac
}
compdef _fizzbuzz fizzbuzz
- 生成したコードを zsh の設定に追加します
私は prezto を使っているので、以下のように指定します
$ fizzbuzz zsh-completion > ~/.zprezto/modules/completion/external/src/_fizzbuzz
$ exec $SHELL -l
- 動作確認
コマンドがサジェストされるようになりました。