bash-completionでコマンド補完するときにプロ生ちゃんに何か言ってもらう

この記事はプロ生ちゃん Advent Calendar 2015の5日目です。

bashでコマンド補完をするのにbash-completionを使うと便利ですよね。bash-completionはbashスクリプトで実装できるので、対応されてないものに対して作成したり、自作のコマンド向けに作ったりもわりと簡単にできます。というわけで、今回は適当なコマンドをでっち上げてそれに対してbash-completionで補完できるようにしてみます。 これは単純なものならさくっと書けます。

作ったものはこれです。tabキーを押した時に現在のオプションの入力状況を見て再生するものが変わります。

vine.co

スクリプトはこれです。こんな感じのファイルを作成してLinuxなら、/usr/share/bash-completion/completionに置きます。brewだと/usr/localのほうかな?

file_dir="/home/masami/Music/kei1/mp3/"
search_voice="kei_voice_036_1.mp3"
result_voice="kei_voice_032.mp3"
help_voice="kei_voice_091.mp3"
version_voice="kei_voice_031_1.mp3"

play_sound()
{
        mpg123 ${file_dir}$1 >/dev/null 2>&1
}

_puronama()
{
        play_sound ${search_voice}

        local cur prev OPTS
        COMPREPLY=()
        cur="${COMP_WORDS[COMP_CWORD]}"
        prev="${COMP_WORDS[COMP_CWORD-1]}"

        case $prev in
                '-g'|'--greeting')
                        play_sound ${result_voice}
                        COMPREPLY=( $(compgen -W "name" -- $cur) )
                        return 0
                        ;;
                '-h'|'--help')
                        play_sound ${help_voice}
                        return 0
                        ;;
                '-v'|'--version')
                        play_sound ${version_voice}
                        return 0
                        ;;
        esac
        OPTS="--greeting
                --version
                --help"
        COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )
        return 0
}
complete -F _puronama puronama

大体見てのとおりです。一番最下部のところはbashのビルトインコマンドのcompleteで_puronama関数を登録してます。 case文はこの前のオプションが何かによって再生するものを切り替えているところです。これらのケースに該当しない場合はCOMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )が動きます。前のオプションがgreetingの場合はCOMPREPLY=( $(compgen -W "name" -- $cur) )で「name」を表示させてます。

とまあ、こんな感じです。機能としてはcomplete、COMPREPLY、compgen、それに変数のCOMP_WORDSとCOMP_CWORDだけ使えばコマンド補完に必要な機能はほぼ作れますね〜 

[改訂新版] シェルスクリプト基本リファレンス  ??#!/bin/shで、ここまでできる (WEB+DB PRESS plus)

[改訂新版] シェルスクリプト基本リファレンス  ??#!/bin/shで、ここまでできる (WEB+DB PRESS plus)