summaryrefslogtreecommitdiffstats
path: root/completions/ssh
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 01:03:18 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 01:03:18 +0000
commitf2621414ee5f2f601424c22f00e207903e3b6104 (patch)
tree56a856dafd1ca684bb23263cacaa723ee4f404fc /completions/ssh
parentAdding debian version 1:2.11-8. (diff)
downloadbash-completion-f2621414ee5f2f601424c22f00e207903e3b6104.tar.xz
bash-completion-f2621414ee5f2f601424c22f00e207903e3b6104.zip
Merging upstream version 1:2.12.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'completions/ssh')
-rw-r--r--completions/ssh514
1 files changed, 297 insertions, 217 deletions
diff --git a/completions/ssh b/completions/ssh
index 907c039..386fd25 100644
--- a/completions/ssh
+++ b/completions/ssh
@@ -1,195 +1,229 @@
# ssh(1) completion -*- shell-script -*-
-_ssh_queries()
+_comp_cmd_ssh__compgen_queries()
{
- COMPREPLY+=($(compgen -W \
- "cipher cipher-auth help mac kex key key-cert key-plain key-sig
- protocol-version compression sig
- ciphers macs kexalgorithms pubkeyacceptedkeytypes
- hostkeyalgorithms hostbasedkeytypes hostbasedacceptedkeytypes" \
- -- "${cur,,}"))
+ local -a queries
+ _comp_compgen -v queries -i ssh query "$1" help ||
+ queries=(cipher cipher-auth mac kex key key-cert key-plain key-sig
+ protocol-version compression sig ciphers macs kexalgorithms
+ pubkeyacceptedkeytypes hostkeyalgorithms hostbasedkeytypes
+ hostbasedacceptedkeytypes)
+ _comp_compgen -c "${cur,,}" -U queries -- -W '"${queries[@]}" help'
}
+# @since 2.12
+_comp_xfunc_ssh_compgen_query()
+{
+ _comp_cmd_ssh__compgen_query ssh "$1"
+}
+
+# @deprecated 2.12 use _comp_xfunc_ssh_compgen_query
_ssh_query()
{
- ${1:-ssh} -Q $2 2>/dev/null
+ local -a queries=()
+ _comp_compgen -v queries -i ssh query "${1:-ssh}" "$2" &&
+ printf "%s\n" "${queries[@]}"
}
-_ssh_ciphers()
+_comp_cmd_ssh__compgen_query()
{
- local ciphers='$(_ssh_query "$1" cipher)'
- [[ $ciphers ]] || ciphers="3des-cbc aes128-cbc aes192-cbc aes256-cbc
- aes128-ctr aes192-ctr aes256-ctr arcfour128 arcfour256 arcfour
- blowfish-cbc cast128-cbc"
- COMPREPLY+=($(compgen -W "$ciphers" -- "$cur"))
+ _comp_compgen_split -- "$("$1" -Q "$2" 2>/dev/null)"
}
-_ssh_macs()
+_comp_cmd_ssh__compgen_ciphers()
{
- local macs='$(_ssh_query "$1" mac)'
- [[ $macs ]] || macs="hmac-md5 hmac-sha1 umac-64@openssh.com hmac-ripemd160
- hmac-sha1-96 hmac-md5-96"
- COMPREPLY+=($(compgen -W "$macs" -- "$cur"))
+ local -a queries
+ _comp_compgen -v queries -i ssh query "$1" cipher ||
+ queries=(3des-cbc aes128-cbc aes192-cbc aes256-cbc aes128-ctr
+ aes192-ctr aes256-ctr arcfour128 arcfour256 arcfour blowfish-cbc
+ cast128-cbc)
+ _comp_compgen -U queries -- -W '"${queries[@]}"'
}
-_ssh_options()
+_comp_cmd_ssh__compgen_macs()
{
- local opts=(
- AddKeysToAgent AddressFamily BatchMode BindAddress CanonicalDomains
- CanonicalizeFallbackLocal CanonicalizeHostname CanonicalizeMaxDots
- CanonicalizePermittedCNAMEs CASignatureAlgorithms CertificateFile
- ChallengeResponseAuthentication CheckHostIP Ciphers ClearAllForwardings
- Compression ConnectionAttempts ConnectTimeout ControlMaster ControlPath
- ControlPersist DynamicForward EnableSSHKeysign EscapeChar
- ExitOnForwardFailure FingerprintHash ForwardAgent ForwardX11
- ForwardX11Timeout ForwardX11Trusted GatewayPorts GlobalKnownHostsFile
- GSSAPIAuthentication GSSAPIClientIdentity GSSAPIDelegateCredentials
- GSSAPIKeyExchange GSSAPIRenewalForcesRekey GSSAPIServerIdentity
- GSSAPITrustDns HashKnownHosts Host HostbasedAuthentication
- HostbasedKeyTypes HostKeyAlgorithms HostKeyAlias HostName
+ local -a queries
+ _comp_compgen -v queries -i ssh query "$1" mac ||
+ queries=(hmac-md5 hmac-sha1 umac-64@openssh.com hmac-ripemd160
+ hmac-sha1-96 hmac-md5-96)
+ _comp_compgen -U queries -- -W '"${queries[@]}"'
+}
+
+# @since 2.12
+_comp_xfunc_ssh_compgen_options()
+{
+ # curl --silent https://raw.githubusercontent.com/openssh/openssh-portable/master/ssh_config.5 | _comp_awk '$1==".It" && $2=="Cm" && $3!="Host" && $3!="Match" {print " "$3}' | sort
+ local _opts=(
+ AddKeysToAgent AddressFamily BatchMode BindAddress BindInterface
+ CanonicalDomains CanonicalizeFallbackLocal CanonicalizeHostname
+ CanonicalizeMaxDots CanonicalizePermittedCNAMEs CASignatureAlgorithms
+ CertificateFile ChallengeResponseAuthentication CheckHostIP Ciphers
+ ClearAllForwardings Compression ConnectionAttempts ConnectTimeout
+ ControlMaster ControlPath ControlPersist DynamicForward
+ EnableSSHKeysign EscapeChar ExitOnForwardFailure FingerprintHash
+ ForwardAgent ForwardX11 ForwardX11Timeout ForwardX11Trusted
+ GatewayPorts GlobalKnownHostsFile GSSAPIAuthentication
+ GSSAPIDelegateCredentials HashKnownHosts HostbasedAuthentication
+ HostbasedKeyTypes HostKeyAlgorithms HostKeyAlias Hostname
IdentitiesOnly IdentityAgent IdentityFile IgnoreUnknown Include IPQoS
KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms
LocalCommand LocalForward LogLevel MACs
NoHostAuthenticationForLocalhost NumberOfPasswordPrompts
PasswordAuthentication PermitLocalCommand PKCS11Provider Port
PreferredAuthentications ProxyCommand ProxyJump ProxyUseFdpass
- PubkeyAcceptedKeyTypes PubkeyAuthentication RekeyLimit RemoteCommand
- RemoteForward RequestTTY RevokedHostKeys SendEnv ServerAliveCountMax
- ServerAliveInterval SmartcardDevice StreamLocalBindMask
- StreamLocalBindUnlink StrictHostKeyChecking SyslogFacility TCPKeepAlive
- Tunnel TunnelDevice UpdateHostKeys UsePrivilegedPort User
- UserKnownHostsFile VerifyHostKeyDNS VisualHostKey XAuthLocation)
- local protocols=$(_ssh_query "$1" protocol-version)
- if [[ -z $protocols || $protocols == *1* ]]; then
- opts+=(Cipher CompressionLevel Protocol RhostsRSAAuthentication
+ PubkeyAcceptedAlgorithms PubkeyAuthentication RekeyLimit RemoteCommand
+ RemoteForward RequestTTY RequiredRSASize RevokedHostKeys
+ SecurityKeyProvider SendEnv ServerAliveCountMax ServerAliveInterval
+ SetEnv StreamLocalBindMask StreamLocalBindUnlink StrictHostKeyChecking
+ SyslogFacility TCPKeepAlive Tunnel TunnelDevice UpdateHostKeys User
+ UserKnownHostsFile VerifyHostKeyDNS VisualHostKey XAuthLocation
+ )
+ # Selected old ones
+ _opts+=(
+ GSSAPIKeyExchange GSSAPIRenewalForcesRekey GSSAPIServerIdentity
+ GSSAPITrustDns PubkeyAcceptedKeyTypes SmartcardDevice UsePrivilegedPort
+ )
+ local -a protocols
+ _comp_compgen -v protocols -i ssh query ssh protocol-version
+ if [[ ${protocols[*]-} == *1* ]]; then
+ _opts+=(Cipher CompressionLevel Protocol RhostsRSAAuthentication
RSAAuthentication)
fi
+ _comp_unlocal protocols
compopt -o nospace
- local IFS=$' \t\n' reset=$(shopt -p nocasematch)
- shopt -s nocasematch
- local option
- COMPREPLY=($(for option in "${opts[@]}"; do
- [[ $option == "$cur"* ]] && printf '%s=\n' "$option"
- done))
- $reset
+ _comp_compgen_split -l -- "$(
+ shopt -s nocasematch
+ local option
+ for option in "${_opts[@]}"; do
+ [[ $option == "$cur"* ]] && printf '%s=\n' "$option"
+ done
+ )"
}
+_comp_deprecate_func 2.12 _ssh_options _comp_xfunc_ssh_compgen_options
+
# Complete a ssh suboption (like ForwardAgent=y<tab>)
-# Two parameters: the string to complete including the equal sign, and
-# the ssh executable to invoke (optional).
+# @param $1 the ssh executable to invoke
+# @param $2 the string to complete including the equal sign
# Not all suboptions are completed.
# Doesn't handle comma-separated lists.
-_ssh_suboption()
+_comp_cmd_ssh__compgen_suboption()
{
# Split into subopt and subval
- local prev=${1%%=*} cur=${1#*=}
+ local _prev=${2%%=*} cur=${2#*=}
- case ${prev,,} in
+ case ${_prev,,} in
batchmode | canonicaldomains | canonicalizefallbacklocal | \
challengeresponseauthentication | checkhostip | \
- clearallforwardings | controlpersist | compression | enablesshkeysign | \
- exitonforwardfailure | forwardagent | forwardx11 | forwardx11trusted | \
- gatewayports | gssapiauthentication | gssapikeyexchange | \
- gssapidelegatecredentials | gssapirenewalforcesrekey | gssapitrustdns | \
- hashknownhosts | hostbasedauthentication | identitiesonly | \
- kbdinteractiveauthentication | kbdinteractivedevices | \
- nohostauthenticationforlocalhost | passwordauthentication | permitlocalcommand | \
- proxyusefdpass | pubkeyauthentication | rhostsrsaauthentication | \
+ clearallforwardings | controlpersist | compression | \
+ enablesshkeysign | exitonforwardfailure | forwardagent | \
+ forwardx11 | forwardx11trusted | gatewayports | \
+ gssapiauthentication | gssapikeyexchange | \
+ gssapidelegatecredentials | gssapirenewalforcesrekey | \
+ gssapitrustdns | hashknownhosts | hostbasedauthentication | \
+ identitiesonly | kbdinteractiveauthentication | \
+ kbdinteractivedevices | nohostauthenticationforlocalhost | \
+ passwordauthentication | permitlocalcommand | proxyusefdpass | \
+ pubkeyauthentication | rhostsrsaauthentication | \
rsaauthentication | streamlocalbindunlink | \
tcpkeepalive | useprivilegedport | visualhostkey)
- COMPREPLY=($(compgen -W 'yes no' -- "$cur"))
+ _comp_compgen -- -W 'yes no'
;;
addkeystoagent)
- COMPREPLY=($(compgen -W 'yes ask confirm no' -- "$cur"))
+ _comp_compgen -- -W 'yes ask confirm no'
;;
addressfamily)
- COMPREPLY=($(compgen -W 'any inet inet6' -- "$cur"))
+ _comp_compgen -- -W 'any inet inet6'
;;
bindaddress)
- _ip_addresses
+ _comp_compgen_ip_addresses
;;
canonicalizehostname)
- COMPREPLY=($(compgen -W 'yes no always' -- "$cur"))
+ _comp_compgen -- -W 'yes no always'
;;
identityfile)
- _ssh_identityfile
+ _comp_xfunc_ssh_compgen_identityfile
;;
- *file | identityagent | include | controlpath | revokedhostkeys | xauthlocation)
- _filedir
+ *file | identityagent | include | controlpath | revokedhostkeys | \
+ xauthlocation)
+ _comp_compgen_filedir
;;
casignaturealgorithms)
- COMPREPLY=($(compgen -W '$(_ssh_query "$2" sig)' -- "$cur"))
+ _comp_cmd_ssh__compgen_query "$1" sig
;;
cipher)
- COMPREPLY=($(compgen -W 'blowfish des 3des' -- "$cur"))
+ _comp_compgen -- -W 'blowfish des 3des'
;;
ciphers)
- _ssh_ciphers "$2"
+ _comp_cmd_ssh__compgen_ciphers "$1"
;;
controlmaster)
- COMPREPLY=($(compgen -W 'yes ask auto autoask no' -- "$cur"))
+ _comp_compgen -- -W 'yes ask auto autoask no'
;;
compressionlevel)
- COMPREPLY=($(compgen -W '{1..9}' -- "$cur"))
+ _comp_compgen -- -W '{1..9}'
;;
fingerprinthash)
- COMPREPLY=($(compgen -W 'md5 sha256' -- "$cur"))
+ _comp_compgen -- -W 'md5 sha256'
;;
ipqos)
- COMPREPLY=($(compgen -W 'af1{1..4} af2{2..3} af3{1..3} af4{1..3}
- cs{0..7} ef lowdelay throughput reliability' -- "$cur"))
+ _comp_compgen -- -W 'af1{1..4} af2{2..3} af3{1..3} af4{1..3}
+ cs{0..7} ef lowdelay throughput reliability'
;;
hostbasedkeytypes | hostkeyalgorithms)
- COMPREPLY=($(compgen -W '$(_ssh_query "$2" key)' -- "$cur"))
+ _comp_cmd_ssh__compgen_query "$1" key
;;
kexalgorithms)
- COMPREPLY=($(compgen -W '$(_ssh_query "$2" kex)' -- "$cur"))
+ _comp_cmd_ssh__compgen_query "$1" kex
;;
loglevel)
- COMPREPLY=($(compgen -W 'QUIET FATAL ERROR INFO VERBOSE DEBUG{,1,2,3}' -- "$cur"))
+ _comp_compgen -- -W 'QUIET FATAL ERROR INFO VERBOSE DEBUG{,1,2,3}'
;;
macs)
- _ssh_macs "$2"
+ _comp_cmd_ssh__compgen_macs "$1"
;;
pkcs11provider)
- _filedir so
+ _comp_compgen_filedir so
;;
preferredauthentications)
- COMPREPLY=($(compgen -W 'gssapi-with-mic host-based publickey
- keyboard-interactive password' -- "$cur"))
+ _comp_compgen -- -W 'gssapi-with-mic host-based publickey
+ keyboard-interactive password'
;;
protocol)
- local protocols=($(_ssh_query "$2" protocol-version))
- [[ $protocols ]] || protocols=(1 2)
+ local -a protocols
+ _comp_compgen -v protocols -i ssh query "$1" protocol-version
+ [[ ${protocols-} ]] || protocols=(1 2)
if ((${#protocols[@]} > 1)); then
- COMPREPLY=($(compgen -W '${protocols[@]}' -- "$cur"))
+ _comp_compgen -- -W '"${protocols[@]}"'
fi
;;
proxyjump)
- _known_hosts_real -a ${configfile:+-F "$configfile"} -- "$cur"
+ _comp_compgen_known_hosts -a ${configfile:+-F "$configfile"} -- "$cur"
;;
proxycommand | remotecommand | localcommand)
- COMPREPLY=($(compgen -c -- "$cur"))
+ _comp_compgen_commands
;;
- pubkeyacceptedkeytypes)
- COMPREPLY=($(compgen -W '$(_ssh_query "$2" key)' -- "$cur"))
+ pubkeyacceptedalgorithms | pubkeyacceptedkeytypes)
+ _comp_cmd_ssh__compgen_query "$1" key
;;
requesttty)
- COMPREPLY=($(compgen -W 'no yes force auto' -- "$cur"))
+ _comp_compgen -- -W 'no yes force auto'
+ ;;
+ requiredrsasize)
+ _comp_compgen -- -W '1024 2048 3072 4096 7680 15360'
;;
stricthostkeychecking)
- COMPREPLY=($(compgen -W 'accept-new ask no off' -- "$cur"))
+ _comp_compgen -- -W 'accept-new ask no off'
;;
syslogfacility)
- COMPREPLY=($(compgen -W 'DAEMON USER AUTH LOCAL{0..7}' -- "$cur"))
+ _comp_compgen -- -W 'DAEMON USER AUTH LOCAL{0..7}'
;;
tunnel)
- COMPREPLY=($(compgen -W 'yes no point-to-point ethernet' \
- -- "$cur"))
+ _comp_compgen -- -W 'yes no point-to-point ethernet'
;;
updatehostkeys | verifyhostkeydns)
- COMPREPLY=($(compgen -W 'yes no ask' -- "$cur"))
+ _comp_compgen -- -W 'yes no ask'
;;
esac
return 0
@@ -198,28 +232,46 @@ _ssh_suboption()
# Try to complete -o SubOptions=
#
# Returns 0 if the completion was handled or non-zero otherwise.
-_ssh_suboption_check()
+# @since 2.12
+_comp_xfunc_ssh_compgen_suboption_check()
+{
+ _comp_cmd_ssh__compgen_suboption_check ssh
+}
+
+# @param $1 the ssh executable to invoke
+_comp_cmd_ssh__compgen_suboption_check()
{
# Get prev and cur words without splitting on =
- local cureq=$(_get_cword :=) preveq=$(_get_pword :=)
- if [[ $cureq == *=* && $preveq == -*o ]]; then
- _ssh_suboption $cureq "$1"
+ local cur prev
+ _comp_get_words -n := cur prev
+ if [[ $cur == *=* && $prev == -*o ]]; then
+ _comp_unlocal prev
+ _comp_cmd_ssh__compgen_suboption "$1" "$cur"
return $?
fi
return 1
}
+# @deprecated 2.12 use `_comp_xfunc_ssh_compgen_suboption_check` instead
+_ssh_suboption_check()
+{
+ _comp_cmd_ssh__compgen_suboption_check "${1:-ssh}"
+}
+
# Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument
-_ssh_configfile()
+# @var[out] configfile Found configfile, if any
+_comp_cmd_ssh__configfile()
{
+ configfile=""
set -- "${words[@]}"
while (($# > 0)); do
if [[ $1 == -F* ]]; then
+ local REPLY
if ((${#1} > 2)); then
- configfile="$(dequote "${1:2}")"
+ _comp_dequote "${1:2}" && configfile=$REPLY
else
shift
- [[ ${1-} ]] && configfile="$(dequote "$1")"
+ [[ ${1-} ]] && _comp_dequote "$1" && configfile=$REPLY
fi
break
fi
@@ -228,79 +280,86 @@ _ssh_configfile()
}
# With $1 set, look for public key files, else private
+# @since 2.12
# shellcheck disable=SC2120
-_ssh_identityfile()
+_comp_xfunc_ssh_compgen_identityfile()
{
- [[ -z $cur && -d ~/.ssh ]] && cur=~/.ssh/id
- _filedir
- if ((${#COMPREPLY[@]} > 0)); then
- COMPREPLY=($(compgen -W '${COMPREPLY[@]}' \
- -X "${1:+!}*.pub" -- "$cur"))
- fi
+ local cur=$cur tmp
+ [[ ! $cur && -d ~/.ssh ]] && cur=~/.ssh/id
+ _comp_compgen -v tmp -c "$cur" filedir &&
+ _comp_compgen -U tmp -- -W '"${tmp[@]}"' -X "${1:+!}*.pub"
}
-_ssh()
+_comp_deprecate_func 2.12 _ssh_identityfile _comp_xfunc_ssh_compgen_identityfile
+
+_comp_cmd_ssh()
{
- local cur prev words cword
- _init_completion -n : || return
+ local cur prev words cword comp_args
+ _comp_initialize -n : -- "$@" || return
local configfile
- _ssh_configfile
+ _comp_cmd_ssh__configfile
- _ssh_suboption_check "$1" && return
+ _comp_cmd_ssh__compgen_suboption_check "$1" && return
local ipvx
+ # Keep cases sorted the same they're in ssh's usage message
+ # (but do group ones with same arg completion)
case $prev in
+ -*B)
+ _comp_compgen_available_interfaces -a
+ return
+ ;;
-*b)
- _ip_addresses
+ _comp_compgen_ip_addresses
return
;;
-*c)
- _ssh_ciphers "$1"
+ _comp_cmd_ssh__compgen_ciphers "$1"
return
;;
-*[DeLpRW])
return
;;
-*[EFS])
- _filedir
+ _comp_compgen_filedir
return
;;
- -*i)
- _ssh_identityfile
+ -*I)
+ _comp_compgen_filedir so
return
;;
- -*I)
- _filedir so
+ -*i)
+ _comp_xfunc_ssh_compgen_identityfile
return
;;
-*J)
- _known_hosts_real -a ${configfile:+-F "$configfile"} -- "$cur"
+ _comp_compgen_known_hosts -a ${configfile:+-F "$configfile"} -- "$cur"
return
;;
-*l)
- COMPREPLY=($(compgen -u -- "$cur"))
+ _comp_compgen -- -u
return
;;
-*m)
- _ssh_macs "$1"
+ _comp_cmd_ssh__compgen_macs "$1"
return
;;
-*O)
- COMPREPLY=($(compgen -W 'check forward cancel exit stop' -- "$cur"))
+ _comp_compgen -- -W 'check forward cancel exit stop'
return
;;
-*o)
- _ssh_options "$1"
+ _comp_xfunc_ssh_compgen_options "$1"
return
;;
-*Q)
- _ssh_queries "$1"
+ _comp_cmd_ssh__compgen_queries "$1"
return
;;
-*w)
- _available_interfaces
+ _comp_compgen_available_interfaces
return
;;
-*4*)
@@ -312,67 +371,71 @@ _ssh()
esac
if [[ $cur == -F* ]]; then
- cur=${cur#-F}
- _filedir
+ _comp_compgen -c "${cur#-F}" filedir
# Prefix completions with '-F'
COMPREPLY=("${COMPREPLY[@]/#/-F}")
- cur=-F$cur # Restore cur
elif [[ $cur == -* ]]; then
- COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur"))
+ _comp_compgen_usage
else
- _known_hosts_real ${ipvx-} -a ${configfile:+-F "$configfile"} -- "$cur"
-
- local args
- _count_args
- if ((args > 1)); then
+ local REPLY
+ # Keep glob sort in sync with cases above
+ _comp_count_args -n "=" -a "-*[BbcDeLpRWEFSIiJlmOoQw]"
+ if ((REPLY > 1)); then
compopt -o filenames
- COMPREPLY+=($(compgen -c -- "$cur"))
+ _comp_compgen_commands
+ else
+ _comp_compgen_known_hosts ${ipvx-} -a ${configfile:+-F "$configfile"} \
+ -- "$cur"
fi
fi
} &&
- shopt -u hostcomplete && complete -F _ssh ssh slogin autossh sidedoor
+ shopt -u hostcomplete &&
+ complete -F _comp_cmd_ssh ssh slogin autossh sidedoor
# sftp(1) completion
#
-_sftp()
+_comp_cmd_sftp()
{
- local cur prev words cword
- _init_completion || return
+ local cur prev words cword comp_args
+ _comp_initialize -- "$@" || return
local configfile
- _ssh_configfile
+ _comp_cmd_ssh__configfile
- _ssh_suboption_check && return
+ # Prefer `ssh` from same dir for resolving options, etc
+ local pathcmd
+ pathcmd=$(type -P "$1") && local PATH=${pathcmd%/*}:$PATH
- local ipvx
+ _comp_xfunc_ssh_compgen_suboption_check && return
+
+ local ipvx=
case $prev in
-*[BDlPRs])
return
;;
-*[bF])
- _filedir
+ _comp_compgen_filedir
return
;;
-*i)
- _ssh_identityfile
+ _comp_xfunc_ssh_compgen_identityfile
return
;;
-*c)
- _ssh_ciphers
+ _comp_cmd_ssh__compgen_ciphers
return
;;
-*J)
- _known_hosts_real -a ${configfile:+-F "$configfile"} -- "$cur"
+ _comp_compgen_known_hosts -a ${configfile:+-F "$configfile"} -- "$cur"
return
;;
-*o)
- _ssh_options
+ _comp_xfunc_ssh_compgen_options
return
;;
-*S)
- compopt -o filenames
- COMPREPLY=($(compgen -c -- "$cur"))
+ _comp_compgen_commands
return
;;
-*4*)
@@ -384,100 +447,119 @@ _sftp()
esac
if [[ $cur == -F* ]]; then
- cur=${cur#-F}
- _filedir
+ _comp_compgen -c "${cur#-F}" filedir
# Prefix completions with '-F'
COMPREPLY=("${COMPREPLY[@]/#/-F}")
- cur=-F$cur # Restore cur
elif [[ $cur == -* ]]; then
- COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur"))
+ _comp_compgen_usage
else
- _known_hosts_real ${ipvx-} -a ${configfile:+-F "$configfile"} -- "$cur"
+ _comp_compgen_known_hosts ${ipvx:+"$ipvx"} -a ${configfile:+-F "$configfile"} -- "$cur"
fi
} &&
- shopt -u hostcomplete && complete -F _sftp sftp
+ shopt -u hostcomplete && complete -F _comp_cmd_sftp sftp
# things we want to backslash escape in scp paths
# shellcheck disable=SC2089
-_scp_path_esc='[][(){}<>"'"'"',:;^&!$=?`\\|[:space:]]'
+_comp_cmd_scp__path_esc='[][(){}<>"'"'"',:;^&!$=?`\\|[:space:]]'
# Complete remote files with ssh. If the first arg is -d, complete on dirs
# only. Returns paths escaped with three backslashes.
+# @since 2.12
# shellcheck disable=SC2120
-_scp_remote_files()
+_comp_xfunc_scp_compgen_remote_files()
{
- local IFS=$'\n'
-
# remove backslash escape from the first colon
cur=${cur/\\:/:}
- local userhost=${cur%%?(\\):*}
- local path=${cur#*:}
+ local _userhost=${cur%%?(\\):*}
+ local _path=${cur#*:}
# unescape (3 backslashes to 1 for chars we escaped)
# shellcheck disable=SC2090
- path=$(command sed -e 's/\\\\\\\('$_scp_path_esc'\)/\\\1/g' <<<"$path")
+ _path=$(command sed -e 's/\\\\\\\('"$_comp_cmd_scp__path_esc"'\)/\\\1/g' <<<"$_path")
# default to home dir of specified user on remote host
- if [[ -z $path ]]; then
- path=$(ssh -o 'Batchmode yes' $userhost pwd 2>/dev/null)
+ if [[ ! $_path ]]; then
+ _path=$(ssh -o 'Batchmode yes' "$_userhost" pwd 2>/dev/null)
fi
- local files
- if [[ $1 == -d ]]; then
+ local _files
+ if [[ ${1-} == -d ]]; then
# escape problematic characters; remove non-dirs
# shellcheck disable=SC2090
- files=$(ssh -o 'Batchmode yes' $userhost \
- command ls -aF1dL "$path*" 2>/dev/null |
- command sed -e 's/'$_scp_path_esc'/\\\\\\&/g' -e '/[^\/]$/d')
+ _files=$(ssh -o 'Batchmode yes' "$_userhost" \
+ command ls -aF1dL "$_path*" 2>/dev/null |
+ command sed -e 's/'"$_comp_cmd_scp__path_esc"'/\\\\\\&/g' -e '/[^\/]$/d')
else
# escape problematic characters; remove executables, aliases, pipes
# and sockets; add space at end of file names
# shellcheck disable=SC2090
- files=$(ssh -o 'Batchmode yes' $userhost \
- command ls -aF1dL "$path*" 2>/dev/null |
- command sed -e 's/'$_scp_path_esc'/\\\\\\&/g' -e 's/[*@|=]$//g' \
+ _files=$(ssh -o 'Batchmode yes' "$_userhost" \
+ command ls -aF1dL "$_path*" 2>/dev/null |
+ command sed -e 's/'"$_comp_cmd_scp__path_esc"'/\\\\\\&/g' -e 's/[*@|=]$//g' \
-e 's/[^\/]$/& /g')
fi
- COMPREPLY+=($files)
+ _comp_compgen_split -l -- "$_files"
}
-# This approach is used instead of _filedir to get a space appended
-# after local file/dir completions, and -o nospace retained for others.
-# If first arg is -d, complete on directory names only. The next arg is
-# an optional prefix to add to returned completions.
-_scp_local_files()
+# @deprecated 2.12 use `_comp_compgen -ax ssh remote_files` instead
+_scp_remote_files()
{
- local IFS=$'\n'
+ _comp_compgen -ax scp remote_files
+}
- local dirsonly=false
+# This approach is used instead of _comp_compgen_filedir to get a space
+# appended after local file/dir completions, and -o nospace retained for
+# others. If first arg is -d, complete on directory names only. The next arg
+# is an optional prefix to add to returned completions.
+# @since 2.12
+_comp_xfunc_scp_compgen_local_files()
+{
+ local _dirsonly=""
if [[ ${1-} == -d ]]; then
- dirsonly=true
+ _dirsonly=set
shift
fi
- if $dirsonly; then
- COMPREPLY+=($(command ls -aF1dL $cur* 2>/dev/null |
- command sed -e "s/$_scp_path_esc/\\\\&/g" -e '/[^\/]$/d' -e "s/^/${1-}/"))
+ local files
+ _comp_expand_glob files '"$cur"*' || return 0
+ if [[ $_dirsonly ]]; then
+ _comp_compgen -U files split -l -- "$(
+ command ls -aF1dL "${files[@]}" 2>/dev/null |
+ command sed -e "s/$_comp_cmd_scp__path_esc/\\\\&/g" \
+ -e '/[^\/]$/d' -e "s/^/${1-}/"
+ )"
else
- COMPREPLY+=($(command ls -aF1dL $cur* 2>/dev/null |
- command sed -e "s/$_scp_path_esc/\\\\&/g" -e 's/[*@|=]$//g' \
- -e 's/[^\/]$/& /g' -e "s/^/${1-}/"))
+ _comp_compgen -U files split -l -- "$(
+ command ls -aF1dL "${files[@]}" 2>/dev/null |
+ command sed -e "s/$_comp_cmd_scp__path_esc/\\\\&/g" \
+ -e 's/[*@|=]$//g' -e 's/[^\/]$/& /g' -e "s/^/${1-}/"
+ )"
fi
}
+# @deprecated 2.12
+_scp_local_files()
+{
+ _comp_compgen -ax scp local_files "$@"
+}
+
# scp(1) completion
#
-_scp()
+_comp_cmd_scp()
{
- local cur prev words cword
- _init_completion -n : || return
+ local cur prev words cword comp_args
+ _comp_initialize -n : -- "$@" || return
local configfile
- _ssh_configfile
+ _comp_cmd_ssh__configfile
- _ssh_suboption_check && {
- COMPREPLY=("${COMPREPLY[@]/%/ }")
+ # Prefer `ssh` from same dir for resolving options, remote files, etc
+ local pathcmd
+ pathcmd=$(type -P "$1") && local PATH=${pathcmd%/*}:$PATH
+
+ _comp_xfunc_ssh_compgen_suboption_check && {
+ ((${#COMPREPLY[@]})) && COMPREPLY=("${COMPREPLY[@]/%/ }")
return
}
@@ -485,34 +567,34 @@ _scp()
case $prev in
-*c)
- _ssh_ciphers
+ _comp_cmd_ssh__compgen_ciphers
COMPREPLY=("${COMPREPLY[@]/%/ }")
return
;;
-*F)
- _filedir
+ _comp_compgen_filedir
compopt +o nospace
return
;;
-*i)
- _ssh_identityfile
+ _comp_xfunc_ssh_compgen_identityfile
compopt +o nospace
return
;;
-*J)
- _known_hosts_real -a ${configfile:+-F "$configfile"} -- "$cur"
+ _comp_compgen_known_hosts -a ${configfile:+-F "$configfile"} -- "$cur"
return
;;
-*[lP])
return
;;
-*o)
- _ssh_options
+ _comp_xfunc_ssh_compgen_options
return
;;
-*S)
- compopt +o nospace -o filenames
- COMPREPLY=($(compgen -c -- "$cur"))
+ compopt +o nospace
+ _comp_compgen_commands
return
;;
-*4*)
@@ -523,12 +605,12 @@ _scp()
;;
esac
- _expand || return
+ _comp_expand || return
case $cur in
!(*:*)/* | [.~]*) ;; # looks like a path
*:*)
- _scp_remote_files
+ _comp_xfunc_scp_compgen_remote_files
return
;;
esac
@@ -541,23 +623,21 @@ _scp()
else
case $cur in
-*)
- COMPREPLY=($(compgen -W '$(_parse_usage "${words[0]}")' \
- -- "$cur"))
+ _comp_compgen_usage
COMPREPLY=("${COMPREPLY[@]/%/ }")
return
;;
- */* | [.~]*)
- # not a known host, pass through
- ;;
*)
- _known_hosts_real ${ipvx-} -c -a \
- ${configfile:+-F "$configfile"} -- "$cur"
+ if ! _comp_looks_like_path "$cur"; then
+ _comp_compgen_known_hosts ${ipvx-} -c -a \
+ ${configfile:+-F "$configfile"} -- "$cur"
+ fi
;;
esac
fi
- _scp_local_files "${prefix-}"
+ _comp_compgen -ax scp local_files "${prefix-}"
} &&
- complete -F _scp -o nospace scp
+ complete -F _comp_cmd_scp -o nospace scp
# ex: filetype=sh