概要
Fishシェルの補完システムは非常に強力で柔軟性がある。
Fishの補完システムを理解するには、これらの概念を理解して、実際に補完スクリプトを記述することが重要である。
また、既存の補完スクリプト (~/.config/fish/completionsディレクトリ) を参考にする。
補完システムの詳細を知りたい場合は、Fishの公式サイトにあるWriting your own completionsを参照すること。
補完関数
completeコマンドを使用して、補完関数を定義する。
# 基本構文
complete -c <コマンド> <オプション> -a '<補完候補>' -d '<補完候補の説明>'
- -c <コマンド>
- 補完を定義するコマンドを指定する。
- -a '<補完候補>' または -a "<補完候補>"
- 補完候補を指定する。
- -d '<補完候補の説明>' または -d "<補完候補の説明>"
- 補完候補の説明を提供する。
オプションの補完
コマンドのオプションを補完する場合は、-s (短いオプション)、または、-l (長いオプション) を使用する。
complete -c cat -s n -l number -d "Enumerate lines"
条件付き補完
Fishでは、条件に基づいて異なる補完を定義することができる。
if command -q gcc
complete -c gcc -s O -a "0 1 2 3" -d "Optimization level"
end
また、-n "<条件>"オプションを使用して、特定の条件下でのみ補完を行うことができる。
以下の例では、変数$commandsに含まれるサブコマンドがまだ入力されていない場合にのみ、それらのサブコマンドを補完候補として提示する。
complete -c systemctl -n "not __fish_seen_subcommand_from $commands" -a "$commands"
動的補完
補完候補を動的に生成する場合は、コマンド置換を使用して動的に補完候補を生成する。
complete -c ssh -a "(command cat ~/.ssh/config | string match -r '^Host\s+(\S+)' | string replace -r '^Host\s+' '')" -d "Known host"
以下の例では、systemctl --state=helpの出力を動的に処理して、補完候補を生成している。
complete -c systemctl -l state -d 'List of unit states' -xa '(systemctl --state=help --no-legend --no-pager | string match -v "*:")'
補完スクリプト
複雑な補完ロジックは、別のファイルに記述して、sourceコマンドで読み込むことができる。
source ~/.config/fish/completions/mycommand.fish
補完の優先順位
-nオプションを使用して、特定の状況下でのみ補完を適用できる。
complete -c git -n "__fish_use_subcommand" -a clone -d "Clone a repository"
サブコマンドの補完
多くのコマンドはサブコマンドを持つ。
これらは、一般的に、__fish_use_subcommand関数を使用して処理する。
complete -c git -f -n "__fish_use_subcommand" -a "clone" -d "Clone a repository"
complete -c git -f -n "__fish_use_subcommand" -a "commit" -d "Record changes to the repository"
サブコマンドのオプション補完
サブコマンドのオプション補完を行う場合は、以下に示すような手順を行う。
- メインコマンドの補完を定義する。
- サブコマンドの補完を定義する。
- サブコマンドのオプション補完を定義する。
以下に示す関数およびオプションを使用して、サブコマンドとそのオプションの補完を細かく制御できる。
- __fish_use_subcommand関数
- Fishの組み込み関数であり、現在のコマンドラインにサブコマンドがまだ入力されていない場合に真を返す。
- これにより、サブコマンドの補完を適切なタイミングで提供することができる。
- __fish_git_using_command clone関数
- Fishの補完ファイル (completionsディレクトリ) で定義される関数である。
- この関数は、現在のコマンドラインでサブコマンドが使用されている場合に真を返す。
- -nオプション
- これは、conditionオプションであり、指定された条件が真の場合にのみ補完を適用する。
- -fオプション
- これは、no-filesオプションであり、ファイル名の補完を無効にする。
- -xオプション
- これは、requires-parameterオプションであり、このオプションが値を取ることを示す。
- -aオプション
- これは、argumentsオプションであり、補完の候補を指定する。
- -dオプション
- これは、descriptionオプションであり、補完候補の説明を提供する。
サブコマンドのオプションの補完を効果的に実装するには、以下に示す事柄を考慮する。
- 補完関数を作成して、現在のコマンドラインの状態を判断する。
- 条件付き補完を使用して、適切なコンテキストで正しい補完を提供する。
- 可能な場合は、動的補完を使用して、実行時に補完候補を生成する。
以下の例では、git cloneコマンドのオプション補完を示している。
完全なgitコマンドの補完スクリプトは、Fishのインストールディレクトリ内にあるcompletionsディレクトリのgit.fishファイルで確認できる。
function __fish_git_needs_command
# Figure out if the current invocation already has a command.
#
# This is called hundreds of times and the argparse is kinda slow,
# so we cache it as long as the commandline doesn't change.
set -l cmdline "$(commandline -c)"
if set -q __fish_git_cmdline; and test "$cmdline" = "$__fish_git_cmdline"
if set -q __fish_git_cmd[1]
echo -- $__fish_git_cmd
return 1
end
return 0
end
set -g __fish_git_cmdline $cmdline
set -l cmd (commandline -opc)
set -e cmd[1]
argparse -s (__fish_git_global_optspecs) -- $cmd 2>/dev/null
or return 0
# These flags function as commands, effectively.
set -q _flag_version; and return 1
set -q _flag_html_path; and return 1
set -q _flag_man_path; and return 1
set -q _flag_info_path; and return 1
if set -q argv[1]
# Also print the command, so this can be used to figure out what it is.
set -g __fish_git_cmd $argv[1]
echo $argv[1]
return 1
end
set -g __fish_git_cmd
return 0
end
function __fish_git_using_command
set -l cmd (__fish_git_needs_command)
test -z "$cmd"
and return 1
contains -- $cmd $argv
and return 0
# Check aliases.
set -l varname __fish_git_alias_(string escape --style=var -- $cmd)
set -q $varname
and contains -- $$varname[1][1] $argv
and return 0
return 1
end
# 1. git コマンドの補完を定義
complete -f -c git -n __fish_use_subcommand -a clone -d "Clone a repository into a new directory"
# 2. git clone サブコマンドの補完を定義
complete -f -c git -n '__fish_git_using_command clone'
# 3. git clone のオプション補完を定義
complete -f -c git -n '__fish_git_using_command clone' -l recursive -d "Initialize submodules in the clone"
complete -f -c git -n '__fish_git_using_command clone' -s q -l quiet -d "Operate quietly"
complete -f -c git -n '__fish_git_using_command clone' -s v -l verbose -d "Run verbosely"
complete -f -c git -n '__fish_git_using_command clone' -l progress -d "Force progress reporting"
complete -f -c git -n '__fish_git_using_command clone' -s n -l no-checkout -d "No checkout of HEAD is performed after clone is complete"
complete -f -c git -n '__fish_git_using_command clone' -l bare -d "Make a bare Git repository"
complete -f -c git -n '__fish_git_using_command clone' -l mirror -d "Set up a mirror of the source repository"
complete -f -c git -n '__fish_git_using_command clone' -s o -l origin -x -d "Use <name> instead of 'origin' to track upstream"
complete -f -c git -n '__fish_git_using_command clone' -s b -l branch -x -d "Checkout <branch> instead of the remote's HEAD"
complete -f -c git -n '__fish_git_using_command clone' -l depth -x -d "Create a shallow clone of that depth"
組み込み関数
Fishには補完を支援するための多くの組み込み関数がある。
__fish_complete_directories- ディレクトリの補完
__fish_complete_path- ファイルパスの補完
__fish_complete_groups- グループ名の補完
型付き引数
以下に示すオプションを使用して、引数の型を指定することができる。
- -r
- ファイルパス
- -x
- 排他的
- -f
- ファイル
カスタム関数
補完システムをより柔軟にするために、カスタム関数を定義することができる。
以下の例では、systemctlコマンドの--propertyオプションの補完候補を生成する。
function __fish_systemd_properties
# プロパティのリストを生成するロジック
end
補完の削除
特定のコマンドの全ての補完を削除することができる。
complete -c <コマンド> -e
補完と関数の組み合わせ
以下の例では、Systemdバージョンに応じて、異なる補完を提供している。
set -l systemd_version (systemctl --version | string match "systemd*" | string replace -r "\D*(\d+)\D.*" '$1')
if test $systemd_version -gt 208 2>/dev/null
set commands $commands cat
if test $systemd_version -gt 217 2>/dev/null
set commands $commands edit
end
end
外部コマンドの使用
/<Fishのインストールディレクトリ>/share/fish/functionsディレクトリに定義した関数を使用して、動的に補完候補を生成することができる。
補完のテスト
特定のコマンドの補完をテストできる。
fish_complete_path <コマンド>