書式
complete 多数のオプション

complete ( -c | --command | -p | --path ) COMMAND
        [( -c | --command | -p | --path ) COMMAND]...
        [( -e | --erase )]
        [( -s | --short-option ) SHORT_OPTION]...
        [( -l | --long-option | -o | --old-option ) LONG_OPTION]...
        [( -a | --arguments ) OPTION_ARGUMENTS]
        [( -f | --no-files )]
        [( -r | --require-parameter )]
        [( -x | --exclusive )]
        [( -w | --wraps ) WRAPPED_COMMAND]...
        [( -n | --condition ) CONDITION]
        [( -d | --description ) DESCRIPTION]

書式
complete ( -C[STRING] | --do-complete[=STRING] )

概要

補完設定については、はじめに
自分独自の補完を記述する
参照してください。

詳しく書いてあります。

本ページでは
complete コマンドの全体を述べます。

本ページにおいては理解を助けるために
以下の用語を使い分けます。

オプション
補完対象のコマンドに対するオプション
スイッチ
complete コマンドのオプション

自分で補完設定を書くのは
fish上級者向けトピック です。

多くのコマンドでは
すでに補完設定が用意されていますし、
manページからも自動生成されます。

本ページを見ても決して
「fishは難しい」
と思わないでくださいね。

パラメータ

COMMAND
補完設定を定義するコマンド名。
SHORT_OPTION
1文字のオプションの定義
(短いオプション)。
LONG_OPTION
2文字以上のオプションの定義
(長いオプション)。
OPTION_ARGUMENTS
スペース区切りのオプション引数の
リストを含むパラメータ。
コマンド置換 を含めることができる。
DESCRIPTION
オプション・引数の説明文。

スイッチ

-c COMMAND / --command COMMAND
COMMAND (補完設定を定義するコマンド名)を指定。
-p COMMAND / --path COMMAND
COMMAND が絶対パスであることを宣言(ワイルドカード可)。
-e / --erase
補完設定を削除。
-s SHORT_OPTION / --short-option=SHORT_OPTION
補完リストに短いオプションを加える。
-l LONG_OPTION / --long-option=LONG_OPTION
GNUスタイルの長いオプション(ハイフン2つから始まる)
を補完リストに加える。
-o LONG_OPTION / --old-option=LONG_OPTION
古いスタイルの長いオプション(ハイフン1つから始まる)
を補完リストに加える。
-a OPTION_ARGUMENTS / --arguments=OPTION_ARGUMENTS
オプション引数を補完リストに加える。
-f / --no-files
この補完設定で指定されたオプションの
後ろにファイル名が続かないことを宣言。
-r / --require-parameter
オプション引数を必ず取ることを宣言。
つまり、他のオプションは続かない。
-x / --exclusive
-r-f の双方を含む。
(訳注: -a と併用して独自の集合を補完候補とする)
-w WRAPPED_COMMAND / --wraps=WRAPPED_COMMAND
ラップされたコマンドの補完設定を受け継ぐ
(詳細は後述。訳注: git をラップした hub コマンドの例あり)
-n / --condition
補完されたときに必ず0を返すシェルコマンドを指定。
特定の条件でのみ使われる補完設定を記述できる。
(訳注:後述する rpm の実例参照)
-d DESCRIPTION / --description=DESCRIPTION
説明文を記述する
(訳注:抜けているので追加)
-CSTRING / --do-complete=STRING
指定された文字列から全補完候補を出力する
(訳注:実例は後述)
-C / --do-complete
現在のコマンドラインから全補完候補を
探し出すよう設定する。
シェルが対話モードではないとき、
エラーになる。(訳注:実例は後述)

3種類のオプションと引数

fishにおけるコマンド独自のTAB補完は
「オプション」と「引数」という概念が
基本になっています。

オプションとはハイフンから始まるパラメータ
( -h, -help, --help など)です。

引数とはハイフンから始まらないパラメータです。

fishはGNUバージョンのgetoptライブラリと
同じスタイルの3種類のオプションを認識します。

short(短いオプション (-a など))
- から続く1文字のオプション。
(-l -a-la のように)まとめることができる。
オプション引数は続くパラメータとして指定する (-w 32) か、
オプションと連結 (-w32) する。
old(古いスタイルの長いオプション (-Wall など))
- から続く2文字以上のオプション。
まとめることはできない。
オプション引数は続くパラメータとして指定する (-ao null)。
gnu(GNUスタイルの長いオプション (--colors など))
-- から続く2文字以上のオプション。
まとめることはできない。
オプション引数は続くパラメータとして指定する (--quoting-style shell) か、
間に「=」を狭む (--quoting-style=shell)。
GNUスタイルの長いオプションは
1つに特定されるまで縮めることができる。
たとえば、hから始まるオプションが
--help だけの場合、 --h と指定できる。

細かい説明

コマンド名とコマンドのパスを
指定する以下のスイッチ

  • -c / --command
  • -p / --path
  • -w / --wrap

は、複数のコマンドが同じ補完設定を
定義できるようにするため、
複数回使われる場合があります。

コマンドのオプションを
指定する以下のスイッチ

  • -s / --short-option
  • -l / --long-option
  • -o / --old-option

とラップされたコマンドは、
一度に複数のコマンドの補完設定を
定義できるようにするため、
複数回使われる場合があります。

同じコマンドに対して複数回
complete コマンドを呼び出すと、
すでに定義された補完設定に
新たな定義を加えます。

(訳注:それが当たり前です。
complete コマンドは
あくまでも1つのオプション
を指定するものです。

同じ働きをする短いオプションと
長いオプションを同時に
指定することはできます。)

-a OPTION_ARGUMENTS / --arguments OPTION_ARGUMENTS
3種のオプション(short/old/gnu)設定と併用したとき、

OPTION_ARGUMENTS は、
指定されたオプションのどれかから
補完を試みようとしたときのみ
使われます。

-a OPTION_ARGUMENTS / --arguments OPTION_ARGUMENTS
いかなるオプションも指定されなかったとき、
OPTION_ARGUMENTS はコマンドへの
あらゆる引数を補完するときに使われます。

(ただし、 -r / --require-parameter
(訳注:これを含む -x / --exclusive も)
によって OPTION_ARGUMENTS
補完するときは除きます。)

OPTION_ARGUMENTS 上の コマンド置換
スペースではなくて改行で区切られた
引数リストを出力しなけばなりません。

それぞれの引数(出力)は
タブ区切りで引数の説明文を
続けることができます。

この方法によって提供された説明文は、
-d / --description による
説明文より優先します。

-w WRAPPED_COMMAND / --wraps WRAPPED_COMMAND
COMMAND に対して WRAPPED_COMMAND の補完を
受け継ぎます。

補完設定を継承することを
WRAPPED_COMMAND を「ラップする」
といいます。

COMMAND は、
WRAPPED_COMMAND の補完設定に加えて
独自の補完設定を持つことができます。

コマンドは複数のコマンドをラップでき、
また、ラップすることは推移的です。
(訳注:推移律を満たす)

AB をラップし、
BC をラップしたとき、
A は自動的に C の補完設定
すべてを受け継ぐことになります。

ラップ設定は
e / --erase で削除できます。

注意してほしいことは、
ラップ設定は
-c / --command
指定された補完設定のみ働き、

-p / --path
指定された補完設定は
無視されることです。

補完設定を削除するには、

complete -c COMMAND -e

によって=COMMAND= の
すべての補完設定を削除するか、

特定の補完オプションを指定することで
3種のオプション(short/old/gnu)設定を
個別に削除するかです。

補完設定の実例

gcc コマンドの短いオプション
-o はファイル名を引数にとります。

次のように記述できます。

complete -c gcc -s o -r

grep コマンドの短いオプション -d
以下のどれか1つを必要とします。

  • read
  • skip
  • recurse

(訳注: -x-f (ファイル名が続かない) と
-r (オプション引数を取る) の両方を含み、
-a で取り得るオプション引数を
明示的に指定します。

-x-a を組み合わせることで、
独自のオプション引数を指定することができます。)

complete -c grep -s d -x -a 'read skip recurse'

su コマンドは引数に
ユーザ名を取ります。

ユーザ名は /etc/passwd
コロン区切りのフィールドの
最初から得られます。

complete -x -c su -d 'Username' -a '(cat /etc/passwd | cut -d : -f 1)'

rpm コマンドはいくつかの
異なるモードがあります。

-e / --erase オプションが指定されると、
パッケージ削除に関係するいくつかのオプション
(--nodeps など)が正しいときに
rpm は1つ以上のパッケージを削除します。

complete -c rpm -n '__fish_contains_opt -s e erase' -l nodeps -d 'Don't check dependencies'

(訳注:原文が間違ってるようだ)

__fish_contains_opt はコマンドラインに
指定されたオプションが含まれているか
チェックする関数です。

別名を実装する場合、
-w / --wrap スイッチを使います。

complete -c hub -w git

hubgit の補完設定すべてを継承します。
-w--wrap スイッチは
function コマンドによる
関数定義においても指定できます。

訳注:さらなる実例

一般に、以下の場合を除いて
たった1つの complete コマンドで
完結することはありません。

  • コマンドの補完はラップする場合
  • オプションが1つの場合

コマンドのオプションごとに
個別に complete
呼び出すことになります。

実際、fish最大の補完設定は gcc であり、
1400もの complete で設定されています。

/usr/share/fish/completions/ の中から
比較的小さめな zcat の補完設定
(/usr/share/fish/completions/zcat.fish)
はこうなっています。

# -aの引数文字列の中にfishのコマンド置換が記述されていて、
# *.gz と *.tgz の集合を得ている。
complete -c zcat -x -a "(
	__fish_complete_suffix .gz
	__fish_complete_suffix .tgz
)
"
# -f, --force
complete -c zcat -s f -l force --description "Overwrite"
# -h, --help
complete -c zcat -s h -l help --description "Display help and exit"
# -L --license
complete -c zcat -s L -l license --description "Print license"
# -V --version
complete -c zcat -s V -l version --description "Display version and exit"

他にも complete の実例が知りたければ、
grep など慣れ親しんでいるコマンドの
補完設定を見ればいいです。

それを参考に自分なりに
組み立てていけばいいです。

fishはmanページから
自動的に complete コマンドによる
補完設定を生成しますので、

自分で書かなくても
すでに補完設定ができてる場合が多いです。

訳注:-Cスイッチの実例

-C / --do-complete スイッチの
実例がなかったので追記します。

このスイッチは
他の complete コマンドのスイッチとは異なり、
補完候補を出力するものです。

たとえば、
5つのHTMLファイルがある
ディレクトリを想定します。

$ ls
commands.html  design.html  documentation.html  faq.html  tutorial.html

ここで complete -C を実行すると、
全ファイルが補完候補として出力されます。

$ complete -C
commands.html
design.html
documentation.html
faq.html
tutorial.html

-C に引数 ls ./d を指定すると、
d の後ろにカーソルがあるときの
補完候補が出力されます。

つまり、dから始まる
ファイル名が2つ出力されます。

$ complete -C'ls ./d'
./design.html
./documentation.html

以下の例は
cpから始まるコマンド名が
補完候補となります。

$ complete -Ccp
cp      Executable, 127kB
cpack   Executable, 4.9MB
cpan    Executable, 7.4kB
cpan5.24-x86_64-linux-gnu       Executable, 7.4kB
cpd     Executable, 55B
cpgr    Executable link, 51kB
cpio    Executable, 142kB
cpp     Executable link, 926kB
cpp-4.4 Executable, 245kB
cpp-4.6 Executable, 345kB
cpp-4.7 Executable, 561kB
cpp-4.8 Executable, 754kB
cpp-4.9 Executable, 814kB
cpp-5   Executable, 898kB
cpp-6   Executable link, 926kB
cppw    Executable, 51kB
cpubuild        Executable, 137B
cpufreq-aperf   Executable, 9.3kB
cpufreq-info    Executable, 17kB
cpufreq-set     Executable, 11kB
cpufreqd        Executable, 47kB
cpufreqd-get    Executable, 7.3kB
cpufreqd-set    Executable, 6.8kB
$ complete --do-complete=cp
同様

なお、 -C--do-complete の後に
スペースを付けると正しく動作しません。

おそらく
fish内部で使われることを
意図したものなので
修正されていないのかもしれません。

最後までお読みいただき、ありがとうございました。参考になれば嬉しいです。