LoginSignup
16
12

More than 5 years have passed since last update.

thorで作ったコマンドラインツールのZsh補完スクリプトを自動生成してくれるthor-zsh_completionでホクホクしてサクサクしてみる

Posted at

自作コマンドラインツールでも補完してサクサク使いたい!
ホクホク顔になりたい!
でもツールを作るたびに補完用の設定を手書きするのはめんどくさい!
という方は多いのではないでしょうか。

そんな方には @labocho さん作の thor-zsh_completion という gem があります。
※この gem は thor を前提にしています。

前提

thor って何?という方は以下をご確認ください。

Ruby の CLI ツールの作成を支援する、 thor gem の基本について

サンプル

以下のリポジトリの内容をベースに試します。

tbpgr/fizzbuzz

変更前

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
  • 動作確認

コマンドがサジェストされるようになりました。

demo.gif

外部資料

16
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
12