Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: _hosts



I've just run (for the second time) across
  zstyle -e '*' hosts 'reply=($hosts)'
not working because the variable hosts is used locally in the _hosts
function.  This converts it to _hosts.  We need to watch out for more
like this.

Even more, we need namespaces:  I run across problems like this again
and again when writing functions for TCP handling, which I use
frequently.  It's compounded by the inability to pass back values from
shell functions in postional parameters.  Hmm, we could think of a
syntax for the latter...  Hmmhmm, being able to insert a parameter into
the enclosing scope regardless of values in the current scope would fix
it, but it's just the sort of feature that makes the already horrific
parameter code even worse.  We've been talking about proper namespaces
for ages.

I've also made the function search ~/.ssh/known_hosts for host names
(and strip out IPv4 dot addresses).

I've also converted a conditional array assignment into an unconditional
one since I didn't see why the former was necessary, but maybe someone
can explain.

Index: Completion/Unix/Type/_hosts
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Unix/Type/_hosts,v
retrieving revision 1.5
diff -u -r1.5 _hosts
--- Completion/Unix/Type/_hosts	24 Oct 2005 17:09:11 -0000	1.5
+++ Completion/Unix/Type/_hosts	3 Feb 2006 15:36:42 -0000
@@ -1,21 +1,34 @@
 #compdef ftp rwho rup xping traceroute host aaaa zone mx ns soa txt
 
-local expl hosts tmp
+# avoid calling variable "hosts", it's an obvious candidate for use in
+#  zstyle -e '*' hosts 'reply=($hosts)'
+local expl _hosts tmp
 
-if ! zstyle -a ":completion:${curcontext}:hosts" hosts hosts; then
-  (( $+_cache_hosts )) ||
-      if (( ${+commands[getent]} )); then
-	: ${(A)_cache_hosts:=${(s: :)${(ps:\t:)${(f)~~"$(_call_program hosts getent hosts 2>/dev/null)"}##[:blank:]#[^[:blank:]]#}}}
-      else
-        : ${(A)_cache_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}}
-	if (( ${+commands[ypcat]} )) &&
-	    tmp=$(_call_program hosts ypcat hosts.byname 2>/dev/null); then
-          _cache_hosts+=( ${=${(f)tmp}##[:blank:]#[^[:blank:]]#} ) # If you use YP
-	fi
+if ! zstyle -a ":completion:${curcontext}:hosts" hosts _hosts; then
+  if (( $+_cache_hosts == 0 )); then
+    # uniquify
+    typeset -gUa _cache_hosts
+    if (( ${+commands[getent]} )); then
+      # pws: we were using the horrible ": ${(A)...:=}" syntax to assign
+      # to _cache_hosts, overriding the typeset as well as being unreadable
+      # and having obscure splitting behaviour.  Why?  We've just
+      # tested _cache_hosts doesn't exist.
+      _cache_hosts=(${(s: :)${(ps:\t:)${(f)~~"$(_call_program hosts getent hosts 2>/dev/null)"}##[:blank:]#[^[:blank:]]#}})
+    else
+      _cache_hosts=(${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}})
+      if (( ${+commands[ypcat]} )) &&
+    	tmp=$(_call_program hosts ypcat hosts.byname 2>/dev/null); then
+        _cache_hosts+=( ${=${(f)tmp}##[:blank:]#[^[:blank:]]#} ) # If you use YP
       fi
+    fi
 
-  hosts=( "$_cache_hosts[@]" )
+    if [[ -r ~/.ssh/known_hosts ]]; then
+      _cache_hosts+=( $(sed -e '/^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]/d' -e 's/[ ,].*//p' ~/.ssh/known_hosts) )
+    fi
+  fi
+
+  _hosts=( "$_cache_hosts[@]" )
 fi
 
 _wanted hosts expl host \
-    compadd -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' -a "$@" - hosts
+    compadd -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' -a "$@" - _hosts

-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


To access the latest news from CSR copy this link into a web browser:  http://www.csr.com/email_sig.php



Messages sorted by: Reverse Date, Date, Thread, Author