summary refs log tree commit diff
path: root/Completion/Unix/Type/_ssh_hosts
diff options
context:
space:
mode:
Diffstat (limited to 'Completion/Unix/Type/_ssh_hosts')
-rw-r--r--Completion/Unix/Type/_ssh_hosts41
1 files changed, 41 insertions, 0 deletions
diff --git a/Completion/Unix/Type/_ssh_hosts b/Completion/Unix/Type/_ssh_hosts
new file mode 100644
index 000000000..e20142cfd
--- /dev/null
+++ b/Completion/Unix/Type/_ssh_hosts
@@ -0,0 +1,41 @@
+#autoload
+
+local -a config_hosts
+local config
+integer ind
+
+# If users-hosts matches, we shouldn't complete anything else.
+if [[ "$IPREFIX" == *@ ]]; then
+  _combination -s '[:@]' my-accounts users-hosts "users=${IPREFIX/@}" hosts "$@" && return
+else
+  _combination -s '[:@]' my-accounts users-hosts \
+    ${opt_args[-l]:+"users=${opt_args[-l]:q}"} hosts "$@" && return
+fi
+if (( ind = ${words[(I)-F]} )); then
+  config=${~words[ind+1]} 2>/dev/null
+else
+  config="$HOME/.ssh/config"
+fi
+if [[ -r $config ]]; then
+  local key line host
+  local -a lines=("${(@f)$(<"$config")}") 2>/dev/null
+  while (($#lines)); do
+    IFS=$'=\t ' read -r key line <<<"${lines[1]}"
+    case "$key" in
+    ((#i)include)
+      lines[1]=("${(@f)$(cd $HOME/.ssh; cat ${(z)~line})}") 2>/dev/null;;
+    ((#i)host(|name))
+      for host in ${(z)line}; do
+	case $host in
+	(*[*?]*) ;;
+	(*) config_hosts+=("$host") ;;
+	esac
+      done ;&
+    (*) shift lines;;
+    esac
+  done
+  if (( ${#config_hosts} )); then
+    _wanted hosts expl 'remote host name' \
+      compadd -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' "$@" $config_hosts
+  fi
+fi