This commit is contained in:
Roeniss Moon 2026-05-18 10:08:37 +02:00 committed by GitHub
commit f6d00f5928
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 49 additions and 15 deletions

View file

@ -1,7 +1,8 @@
# ssh plugin # ssh plugin
This plugin provides host completion based off of your `~/.ssh/config` file, and adds This plugin provides host completion based off of your `~/.ssh/config` file,
some utility functions to work with SSH keys. and adds some utility functions to work with SSH keys. If the `~/.ssh/config`
contains `Include` directives, the plugin also parse hosts in related files.
To use it, add `ssh` to the plugins array in your zshrc file: To use it, add `ssh` to the plugins array in your zshrc file:

View file

@ -2,20 +2,53 @@
# Take all host sections in .ssh/config and offer them for # Take all host sections in .ssh/config and offer them for
# completion as hosts (e.g. for ssh, rsync, scp and the like) # completion as hosts (e.g. for ssh, rsync, scp and the like)
# Filter out wildcard host sections. # Filter out wildcard host sections.
_ssh_configfile="$HOME/.ssh/config" # If the .ssh/config has Include directives, load them too.
if [[ -f "$_ssh_configfile" ]]; then function _load_ssh_hosts {
_ssh_hosts=($( local conf="$1"
grep -E '^Host.*' "$_ssh_configfile" |\ if [[ -f "$conf" ]]; then
local _ssh_hosts=($(
grep -E '^Host[[:space:]]' "$conf" |\
awk '{for (i=2; i<=NF; i++) print $i}' |\ awk '{for (i=2; i<=NF; i++) print $i}' |\
sort |\ sort |\
uniq |\ uniq |\
grep -v '^*' |\ grep -v '^*' |\
sed -e 's/\.*\*$//' sed -e 's/\.*\*$//'
)) ))
zstyle ':completion:*:hosts' hosts $_ssh_hosts echo "${_ssh_hosts[@]}"
unset _ssh_hosts fi
fi }
unset _ssh_configfile
# XXX: We could make it recursive but won't implement for now
function _find_include_files {
local conf="$1"
if [[ -f "$conf" ]]; then
grep -E '^Include[[:space:]]' "$conf" |\
awk '{for (i=2; i<=NF; i++) print $i}' |\
sed -e 's/^"\(.*\)"$/\1/' -e "s/^'\(.*\)'\$/\\1/"
fi
}
all_hosts=($(_load_ssh_hosts "$HOME/.ssh/config"))
_find_include_files "$HOME/.ssh/config" | while read include_file; do
# omz doesn't know "~" directory
if [[ "$include_file" == ~* ]]; then
include_file="${HOME}${include_file:1}"
# Per ssh_config(5), relative paths are resolved against ~/.ssh
elif [[ "$include_file" != /* ]]; then
include_file="$HOME/.ssh/$include_file"
fi
if [[ -f "$include_file" ]]; then
hosts=($(_load_ssh_hosts "$include_file"))
all_hosts+=("${hosts[@]}")
fi
done
zstyle ':completion:*:hosts' hosts "${all_hosts[@]}"
unset -f _load_ssh_hosts
unset -f _find_include_files
unset all_hosts
############################################################ ############################################################
# Remove host key from known hosts based on a host section # Remove host key from known hosts based on a host section