独自の補完を作成する

補完を指定するには、 complete コマンドを使用します。 complete はパラメータとして、補完を設定したいコマンドの名前を受け取ります。例えば、プログラム myprog (または Cygwin/MSYS2 上の myprog.exe )に補完を追加するには、補完コマンドを complete -c myprog ... のように書き始めます。

complete コマンドで利用可能な各種スイッチの詳細については、組み込みコマンドの complete ドキュメントを参照するか、 fish シェル内で complete --help と入力してください。

myprog の補完候補リストを提供するには、 -a スイッチを使用します。もし myprog が 引数として start と stop を受け取るなら、 complete -c myprog -a 'start stop' のように指定できます。 -a スイッチへの引数は常に単一の文字列です。補完の実行時に、この文字列はスペースやタブでトークン化され、変数展開、コマンド置換、およびその他の形式のパラメータ展開が行われます。

# If myprog can list the valid outputs with the list-outputs subcommand:
complete -c myprog -l output -a '(myprog list-outputs)'

fish には、コマンドが受け付けるスイッチ(オプション)を指定するための特別な構文があります。スイッチ -s-l-o はそれぞれ、短縮スイッチ( -l のような1文字)、GNU形式のロングスイッチ( --color など)、および旧形式のロングスイッチ( -shuffle のように - が1つ)を指定するために使用されます。コマンド 'myprog' に -o--output と記述できるオプションがある場合は、以下のようになります。

complete -c myprog -s o -l output

このオプションが任意(オプション)の引数を取る場合は、 --argument-a を追加し、候補となる引数を与えます。

complete -c myprog -s o -l output -a "yes no"

これにより、以下の場合に引数として "yes" と "no" が提案されます。

> myprog -o<TAB>
> myprog --output=<TAB>

デフォルトでは、オプションの引数は*任意*であるため、候補は上記のように直接連結された場合にのみ提示されます。したがって、次のケースでは提示されません。

> myprog -o <TAB>

通常、オプションにはパラメータが*必須*であるため、 --require-parameter-r を指定します。

complete -c myprog -s o -l output -ra "yes no"

これにより、以下のケースで yes/no が提案されます。

> myprog -o<TAB>
> myprog --output=<TAB>
> myprog -o <TAB>
> myprog --output <TAB>

fishはデフォルトで、指定された引数に加えてファイル名も候補として提示します。特定のオプションに対してファイル補完を抑制するには、次のようにします。

complete -c myprog -s o -l output --no-files -ra "yes no"

または、特定の条件を指定します。

complete -c myprog -f --condition '__fish_seen_subcommand_from somesubcommand'

あるいは、そのコマンドに対してグローバルにファイル補完を無効にすることもできます。

complete -c myprog -f

グローバルに無効化した後でも、 --force-files-F オプションを使用すれば、特定の条件やオプションに対してのみファイル補完を有効にできます。

# Disable files by default
complete -c myprog -f
# but reenable them for --config-file
complete -c myprog -l config-file --force-files -r

より包括的な例として、systemd の timedatectl 用の補完から、コメント付きの抜粋を紹介します。

# All subcommands that timedatectl knows - this is useful for later.
set -l commands status set-time set-timezone list-timezones set-local-rtc set-ntp

# Disable file completions for the entire command
# because it does not take files anywhere
# Note that this can be undone by using "-F".
#
# File completions also need to be disabled
# if you want to have more control over what files are offered
# (e.g. just directories, or just files ending in ".mp3").
complete -c timedatectl -f

# This line offers the subcommands
# -"status",
# -"set-timezone",
# -"set-time"
# -"list-timezones"
# if no subcommand has been given so far.
#
# The `-n`/`--condition` option takes script as a string, which it executes.
# If it returns true, the completion is offered.
# Here the condition is the `__fish_seen_subcommand_from` helper function.
# It returns true if any of the given commands is used on the commandline,
# as determined by a simple heuristic.
# For more complex uses, you can write your own function.
# See e.g. the git completions for an example.
#
complete -c timedatectl -n "not __fish_seen_subcommand_from $commands" \
    -a "status set-time set-timezone list-timezones"

# If the "set-timezone" subcommand is used,
# offer the output of `timedatectl list-timezones` as completions.
# Each line of output is used as a separate candidate,
# and anything after a tab is taken as the description.
# It's often useful to transform command output with `string` into that form.
complete -c timedatectl -n "__fish_seen_subcommand_from set-timezone" \
    -a "(timedatectl list-timezones)"

# Completion candidates can also be described via `-d`,
# which is useful if the description is constant.
# Try to keep these short, because that means the user gets to see more at once.
complete -c timedatectl -n "not __fish_seen_subcommand_from $commands" \
    -a "set-local-rtc" -d "Maintain RTC in local time"

# We can also limit options to certain subcommands by using conditions.
complete -c timedatectl -n "__fish_seen_subcommand_from set-local-rtc" \
    -l adjust-system-clock -d 'Synchronize system clock from the RTC'

# These are simple options that can be used everywhere.
complete -c timedatectl -s h -l help -d 'Print a short help text and exit'
complete -c timedatectl -l version -d 'Print a short version string and exit'
complete -c timedatectl -l no-pager -d 'Do not pipe output into a pager'

複雑な補完を自分で作成する方法の例については、 /usr/share/fish/completions にある補完ファイルを調べてみてください。(正確なパスは、選択したインストールプレフィックスによって異なり、わずかに違う場合があります)

補完作成に便利な関数

fish には、特定のコマンド用補完を作成する際に便利な関数がいくつか同梱されています。これらの関数のほとんどは __fish_ という文字列で始まります。これらは fish の内部関数であり、将来のfishバージョンで名前やインターフェースが変更される可能性があります。ここでは、そのうちのいくつかを紹介します。

__fish_print_ で始まる関数は、改行で区切られた文字列のリストを出力します。例えば、 __fish_print_filesystems は既知のすべてのファイルシステムのリストを出力します。__fish_complete_ で始まる関数は、説明(ディスクリプション)付きの補完候補を改行区切りで出力します。説明は、補完候補からタブ文字で区切られます。

  • __fish_complete_directories STRING DESCRIPTION は、STRING に対してパス補完を実行します。ディレクトリのみを許可し、それらに DESCRIPTION という説明を付加します。

  • __fish_complete_path STRING DESCRIPTION は、STRING に対してパス補完を実行し、説明 DESCRIPTION を付加します。

  • __fish_complete_groups は、すべてのユーザグループの一覧を、グループメンバを説明として表示します。

  • __fish_complete_pids は、すべてのプロセスIDの一覧を、コマンド名を説明として表示します。

  • __fish_complete_suffix SUFFIX は、ファイル補完を実行しますが、SUFFIX で終わるファイルを優先してソートします。これは complete --keep-order と組み合わせて使用すると便利です。

  • __fish_complete_users は、すべてのユーザの一覧を、フルネームを説明として表示します。

  • __fish_print_filesystems は、既知のすべてのファイルシステムのリストを表示します。現在は静的なリストであり、ホストOSが実際に認識しているファイルシステムには依存しません。

  • __fish_print_hostnames は、既知のすべてのホスト名のリストを表示します。この関数は fstab から NFS サーバを、ssh から既知のホストを検索し、 /etc/hosts ファイルを確認します。

  • __fish_print_interfaces は、既知のすべてのネットワークインターフェースのリストを表示します。

補完の配置場所

補完はコマンドラインや設定ファイルで定義できますが、自動的にロードすることも可能です。fish はリスト変数 $fish_complete_path に含まれるすべてのディレクトリを自動的に検索し、定義された補完は必要に応じて自動的にロードされます。補完ファイルの名前は、補完対象のコマンド名にサフィックス(拡張子) .fish を付けたものである必要があります。

デフォルトでは、fish は以下の場所を検索し、最初に見つかった補完ファイルを使用します。

  • エンドユーザが独自の補完を保持するためのディレクトリ。通常は ~/.config/fish/completions です( XDG_CONFIG_HOME 環境変数で制御されます)。

  • システム管理者がシステム上の全ユーザ向けに補完をインストールするためのディレクトリ。通常は /etc/fish/completions です。

  • ユーザが指定したサードパーティベンダーの補完用ディレクトリ。通常は ~/.local/share/fish/vendor_completions.d です( XDG_DATA_HOME 環境変数で制御されます)。

  • サードパーティのソフトウェアベンダーが自社ソフトウェア用の補完を同梱するためのディレクトリ。通常は /usr/share/fish/vendor_completions.d です。

  • fish に同梱されている補完。通常は /usr/share/fish/completions にインストールされます。

  • OSのマニュアルから自動生成された補完。通常は ~/.cache/fish/generated_completions に保存されます( XDG_CACHE_HOME 環境変数で制御されます)。

これらのパスは、ビルド時、インストール時、または実行時に設定されるパラメータによって制御されており、上記のデフォルト値とは異なる場合があります。

この広範な検索は混乱を招くかもしれません。迷った場合は、おそらく ~/.config/fish/completions に配置するのが適切です。

一般的な Unix コマンドの新しい補完を作成した場合は、 Further help and development の手順に従って提出し、成果を共有することを検討してください。

別のプログラムを開発しており、そのプログラムに補完を同梱したい場合は、"vendor" 補完ディレクトリにインストールしてください。このパスはシステムごとに異なる可能性があるため、 pkgconfig フレームワークを使用し、 pkg-config --variable completionsdir fish の出力を用いてこのパスを特定すべきです。