困っていること
Macのzsh 5.9で
$ ssh <Tab>
とすると、~/.ssh/configに書かれているホスト名を補完してくれない。
ホスト名の一部を入力してからタブを押すと補完してくれる:
$ ssh a<Tab>
→aで始まるホスト名が補完される
この事象はMacでのみ再現し、Linuxのzsh 5.9では再現しない。
zshの補完関数 _ssh
_ssh_hosts
は双方同一であることを確認済み。
ワークアラウンド1
~/.zshrcに
typeset -gUa _cache_hosts
# sshホスト名のリスト
_cache_hosts=(
host1
host2
...
)
のようにキャッシュをベタ書きすることで補完されるようになった。
$_cache_hosts
は補完関数_hosts
で参照される変数。
ワークアラウンド2
トレースに
+_description:109> zstyle -a :completion::complete:ssh:argument-1:hosts fake match
と出力されているのを発見。_descriptionはfake
スタイルに対応しているようだ。
もしやと思い、下記を書いてみたらできた(これも~/.zshrcにベタ書き)。
zstyle :completion::complete:ssh:argument-1:hosts fake \
host1 \
host2
ワークアラウンド3
~/.ssh/configからホスト名を抜き出すだけの機能の関数を自作。
_ssh_hosts
という名前にしておけばシステムの_ssh_hostsファイルは読み込まれない。
_ssh_hosts() {
local -a _hosts
_hosts=($(command sed -ne '/^\s*Host\s*/{ s/^\s*Host\s*//; p; }' ~/.ssh/config))
_describe -t hosts 'Remote Hosts' _hosts
}
原因調査
_complete_debug
ウィジェットでトレースを出力したところ、ssh <Tab>
の場合は_ssh_hosts
の11-12行目:
_combination -s '[:@]' my-accounts users-hosts \
${opt_args[-l]:+"users=${opt_args[-l]:q}"} hosts "$@" && return
でreturnしており、その後の~/.ssh/config読み込み処理が実行されていなかった。
しかし_combinationが何をしているのか分からず、その先までは追えていない。