From: Ronan Pigott <ronan@rjp.ie> The goal of this patch is to enable using different known-hosts sources with different commands. The current _hosts cache doesn't allow this because it relies on a single global cache that is used as long as the shell is alive. Consider the following: $ setopt completealias $ alias myssh='ssh -o UserKnownHostsFile=$HOME/myhosts' $ zstyle ':completion:*:complete:myssh:*' known-hosts-files ~/myhosts In the status quo, myssh picks up the usual hosts from ~/.ssh/known_hosts that are stored in _cache_hosts, but with this change it will now correctly use the specified hosts file(s) for completion. The new cache for known-hosts uses an associative array with known-host files as keys and hosts as the values. We could also consider just not caching these values altogether, since the known-hosts files are relatively quick to parse. --- Completion/Unix/Type/_hosts | 59 ++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/Completion/Unix/Type/_hosts b/Completion/Unix/Type/_hosts index 4057fee10..e08337876 100644 --- a/Completion/Unix/Type/_hosts +++ b/Completion/Unix/Type/_hosts @@ -5,7 +5,7 @@ local expl _hosts tmp useip if ! zstyle -a ":completion:${curcontext}:hosts" hosts _hosts; then - if (( $+_cache_hosts == 0 )); then + if (( $+_cache_hosts == 0 )) || ! zstyle -t ":completion:${curcontext}:hosts" use-cache; then # uniquify typeset -gUa _cache_hosts local ipstrip='[:blank:]#[^[:blank:]]#' @@ -23,23 +23,40 @@ if ! zstyle -a ":completion:${curcontext}:hosts" hosts _hosts; then else _cache_hosts=(${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##${~ipstrip}}}) if (( ${+commands[ypcat]} )) && - tmp=$(_call_program hosts ypcat hosts.byname 2>/dev/null); then + tmp=$(_call_program hosts ypcat hosts.byname 2>/dev/null); then _cache_hosts+=( ${=${(f)tmp}##${~ipstrip}} ) # If you use YP fi fi + fi - local khostfile - typeset -Ua khostfiles + local khostfile + typeset -Ua khostfiles - # This style specifies a list of files to look up for host names and IP - # addresses, if asked to. The files can contain comma separated host names - # and IP's, and any text on a line after the first whitespace,| or # is - # discarded. ssh's known_hosts files are thus supported. This style defaults - # to the list /etc/ssh/ssh_known_hosts, ~/.ssh/known_hosts - zstyle -a ":completion:${curcontext}:hosts" known-hosts-files khostfiles || - khostfiles=(/etc/ssh/ssh_known_hosts ~/.ssh/known_hosts) + # This style specifies a list of files to look up for host names and IP + # addresses, if asked to. The files can contain comma separated host names + # and IP's, and any text on a line after the first whitespace,| or # is + # discarded. ssh's known_hosts files are thus supported. This style defaults + # to the list /etc/ssh/ssh_known_hosts, ~/.ssh/known_hosts + zstyle -a ":completion:${curcontext}:hosts" known-hosts-files khostfiles || + khostfiles=(/etc/ssh/ssh_known_hosts ~/.ssh/known_hosts) + _hosts_default_cache_policy() { for khostfile in $khostfiles; do + [[ $1 -ot $khostfile ]] && return 0 + done + return 1 + } + + zstyle -s ":completion:$curcontext:hosts" cache-policy user_policy + if [[ -z "$user_policy" ]]; then + zstyle ":completion:$curcontext:" cache-policy _hosts_default_cache_policy + fi + + typeset -A khostcache + _cache_invalid khostcache || _retrieve_cache khostcache + + for khostfile in $khostfiles; do + if ! (( $+khostcache[$khostfile] )); then if [[ -r $khostfile ]]; then khosts=(${(s/,/j/,/u)${(f)"$(<$khostfile)"}%%[ |#]*}) @@ -62,16 +79,22 @@ if ! zstyle -a ":completion:${curcontext}:hosts" hosts _hosts; then fi done } "$khosts[@]" - - if [[ -z $useip ]]; then - khosts=(${${khosts:#(#s)[0-9]##.[0-9]##.[0-9]##.[0-9]##(#e)}:#(#s)[0-9a-f:]##(#e)}) + if [[ -n "$khosts" ]]; then + khostcache[$khostfile]=${(j. .)khosts} fi - _cache_hosts+=($khosts) fi - done - fi + fi + done + _store_cache khostcache khostcache - _hosts=( "$_cache_hosts[@]" ) + local -a khosts=() + for khostfile in $khostfiles; do + khosts+=($=khostcache[$khostfile]) + done + if [[ -z $useip ]]; then + khosts=(${${khosts:#(#s)[0-9]##.[0-9]##.[0-9]##.[0-9]##(#e)}:#(#s)[0-9a-f:]##(#e)}) + fi + _hosts=( "$_cache_hosts[@]" "$khosts[@]" ) fi _wanted hosts expl host \ -- 2.37.0