Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
[PATCH] _hosts: use separate cache for known-hosts
- X-seq: zsh-workers 50408
- From: ronan@xxxxxx
- To: zsh-workers@xxxxxxx
- Cc: Ronan Pigott <ronan@xxxxxx>
- Subject: [PATCH] _hosts: use separate cache for known-hosts
- Date: Sun, 10 Jul 2022 17:08:42 -0700
- Archived-at: <https://zsh.org/workers/50408>
- List-id: <zsh-workers.zsh.org>
From: Ronan Pigott <ronan@xxxxxx>
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
Messages sorted by:
Reverse Date,
Date,
Thread,
Author