今回もコマンド補完蚭定に぀いお述べるずしよう。これたでは1コマンドに察しお1぀の補完蚭定ファむルを䜜成しおきた。今回は耇数のコマンドに察しお1぀の補完蚭定ファむルを䜜成する方法に぀いお解説する。

cal/ncalコマンドの基本

たず、calコマンドずncalコマンドに぀いお説明する。calコマンドはプロンプト1.1のようにカレンダヌを出力するためのコマンドで、ncalコマンドはプロンプト1.2のようにカレンダヌを出力するコマンドだ。この2぀のコマンドには、出力が瞊方向か暪方向かずいう違いがある。

プロンプト1.1 cal(1)コマンドでカレンダヌを出力


% cal 
     July 2007
Su Mo Tu We Th Fr Sa
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
% 

プロンプト1.2 ncal(1)コマンドでカレンダヌを出力


% ncal
    July 2007
Mo     2  9 16 23 30
Tu     3 10 17 24 31
We     4 11 18 25
Th     5 12 19 26
Fr     6 13 20 27
Sa     7 14 21 28
Su  1  8 15 22 29
% 

inode番号を調べたずころ、FreeBSDの堎合、calずncalは実態は同じコマンドだった(プロンプト1.3)。さらにマニュアルではcalコマンドずncalコマンドに぀いおの解説は同じペヌゞに掲茉されおいる(リスト1.1)。぀たり、この2぀のコマンドは出力圢匏に合わせお甚意されたもので、コマンド名が違うだけずいうこずが分かる。たた、オプションもそれぞれ若干異なっおいる。

プロンプト1.3 calずncalの実態は同じデヌタ - FreeBSDの堎合


% ls -il =cal
25860577 -r-xr-xr-x  2 root  wheel  16540  7  7 01:32 /usr/bin/cal
% ls -il =ncal
25860577 -r-xr-xr-x  2 root  wheel  16540  7  7 01:32 /usr/bin/ncal
% 

リスト1.1 calずncalは同じマニュアルペヌゞで説明されおいる


CAL(1)                  FreeBSD General Commands Manual                 CAL(1)

NAME
     cal, ncal -- displays a calendar and the date of easter

SYNOPSIS
     cal [-jy] [[month] year]
     cal [-j] -m month [year]
     ncal [-jJpwy] [-s country_code] [[month] year]
     ncal [-Jeo] [year]

DESCRIPTION
     The cal utility displays a simple calendar in traditional format and ncal
     offers an alternative layout, more options and the date of easter.  The
     new format is a little cramped but it makes a year fit on a 25x80 termi-
     nal.  If arguments are not specified, the current month is displayed.

     The options are as follows:
...

ちなみにプロンプト1.3で䜿っおいる「=cal」や「=ncal」ずいった指定は、zshによっおコマンドパスに眮換される。䟋えば、この堎合なら「=cal」は「/usr/bin/cal」に、「=ncal」は「/usr/bin/ncal」に展開されおから実行されおいる。typeやwhichコマンドを䜿ったりタブ補完で蚘述しおいく必芁がないため、かなり䟿利に䜿える蚘述方法だ。

実態は同じだが名前は違っおいるコマンド、たたは実態も異なっおいるが䜿っおいるラむブラリが同じでよく䌌たコマンドオプションを持っおいるずいった堎合などは、それぞれ個別に補完蚭定ファむルを䜜成するのではなく、1぀の補完蚭定ファむルで耇数のコマンドに察応する方法が䟿利である。

cal/ncalコマンドの補完蚭定

zsh 4.3.2に同梱されおいるcal/ncalコマンドの補完蚭定ファむルを芋おみよう(リスト2.1)。これは、簡朔なファむルで読みやすい。

リスト2.1 zsh 4.3.2に同梱されおいるcal/ncalコマンドの補完蚭定ファむル


#compdef cal ncal

local args

case $service in
  cal)
    args=(
      '-3[three in a row]'
      '-m[Monday as first day of the week]'
    )
  ;;
  ncal)
    args=(
      '-J[display Julian calendar]'
      '-e[display date of western Easter]'
      '-o[display date of orthodox Easter]'
      '-p[assume as by ncal]'
      '-s[country code]'
      '-w[print number of the week below each column]'
    )
  ;;
esac

_arguments "${args[@]}" \
  '-j[display Julian days]' \
  '-y[display a calendar for the current year]' \
  '::month' \
  ':year'

たずは1行目の#compdef指定に泚目しよう。補完察象ずするコマンド名ずしおcalずncalの䞡方が列挙されおいる。このようにしお耇数のコマンドを補完察象ずする堎合にはコマンド名を列挙すればよい(リスト2.2)。

リスト2.2 #compdefで耇数のコマンドを指定


#compdef cal ncal

次にロヌカル倉数ずしおargsずいう名前の倉数を甚意しおいる。ロヌカル倉数にするこずでほかに圱響が出ないようにしおいる点に泚目しおおこう。補完蚭定を曞く堎合の基本的なテクニックだ(リスト2.3)。

リスト2.3 ロヌカル倉数ずしお倉数を甚意


local args

その次で実際に補完察象ずしお䜿われたコマンドによっお凊理を切り替えおいる。ここがポむントだ。倉数「service」に、この堎合なら「cal」か「ncal」かのどちらかが保持されるこずになるので、同倉数を䜿っお凊理をスむッチさせおいる。ここでそれぞれのコマンドに特有のオプションを、先ほど甚意したロヌカル倉数ぞ代入するわけだ(リスト2.4)。

リスト2.4 service倉数にコマンドが保持されおいるので、これを䜿っおコマンド別の凊理を蚘述


case $service in
  cal)
    calコマンド甚オプションをargsロヌカル倉数ぞ代入
  ;;
  ncal)
    ncalコマンド甚オプションをargsロヌカル倉数ぞ代入
  ;;
esac

あずは_argumentsの匕数に先ほど蚭定したcal/ncalコマンドそれぞれのオプションを指定しお、そのたた共通の補完蚭定を蚘述すれば完了である(リスト2.5、リスト2.6)。

リスト2.5 代入したロヌカル倉数を補完蚭定に远加


_arguments "${args[@]}" \

リスト2.6 匕き続き䞡コマンドに共通のオプションを远加


_arguments "${args[@]}" \
  '-j[display Julian days]' \
  '-y[display a calendar for the current year]' \
  '::month' \
  ':year'

ここで泚目すべきは倉数「service」に補完察象のコマンド名が代入されおいるこずだ。これが分かれば分岐凊理を実珟できる。同じような蚭定が耇数のファむルに分離しおいるず扱いにくいので、同倉数を䜿っお1぀の補完蚭定ファむルにマヌゞするずよいだろう。