Added -h HOST option to _known_hosts_real

Modified call to _known_hosts_real in ssh, vncviewer and xhost completions.
This commit is contained in:
Freddy Vulto 2009-06-13 08:38:52 +02:00
parent 8c24c1429a
commit 0b19577ed9
5 changed files with 156 additions and 59 deletions

View File

@ -1045,13 +1045,7 @@ _user_at_host() {
} }
shopt -u hostcomplete && complete -F _user_at_host $nospace talk ytalk finger shopt -u hostcomplete && complete -F _user_at_host $nospace talk ytalk finger
# This function performs host completion based on ssh's known_hosts files, # See: _known_hosts_real()
# defaulting to standard host completion if they don't exist.
#
# Arguments: -a Use aliases
# -c Use `:' suffix
# -F configfile Use `configfile' for configuration settings
# -h host Complete on given host
_known_hosts() _known_hosts()
{ {
local cur local cur
@ -1062,19 +1056,30 @@ _known_hosts()
_known_hosts_real "$@" _known_hosts_real "$@"
} }
# Helper function for completing _known_hosts.
# This function performs host completion based on ssh's known_hosts files,
# defaulting to standard host completion if they don't exist.
# Arguments: -a Use aliases
# -c Use `:' suffix
# -F configfile Use `configfile' for configuration settings
# -h hostname Use hostname to complete on
# -p PREFIX Use PREFIX
# Return: Completions are added to COMPREPLY[]
_known_hosts_real() _known_hosts_real()
{ {
local configfile flag local configfile flag prefix
local curd ocur user suffix aliases global_kh user_kh hosts i host local cur curd ocur user suffix aliases global_kh user_kh hosts i host
local -a kh khd config local -a kh khd config
local IFS=$'\n' local IFS=$'\n'
local OPTIND=1 local OPTIND=1
while getopts "acF:" flag "$@"; do while getopts "acF:h:p:" flag "$@"; do
case $flag in case $flag in
a) aliases='yes' ;; a) aliases='yes' ;;
c) suffix=':' ;; c) suffix=':' ;;
F) configfile="$OPTARG" ;; F) configfile=$OPTARG ;;
h) cur=$OPTARG ;;
p) prefix=$OPTARG ;;
esac esac
done done
@ -1190,17 +1195,15 @@ _known_hosts_real()
# Now add results of normal hostname completion # Now add results of normal hostname completion
COMPREPLY=( "${COMPREPLY[@]}" $( compgen -A hostname -- $ocur ) ) COMPREPLY=( "${COMPREPLY[@]}" $( compgen -A hostname -- $ocur ) )
# apply suffix # apply suffix and prefix
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
COMPREPLY[i]=$user${COMPREPLY[i]}$suffix COMPREPLY[i]=$prefix$user${COMPREPLY[i]}$suffix
done done
elif [ -z "$configfile" ]; then elif [ -z "$configfile" ]; then
# Just do normal hostname completion # Just do normal hostname completion
COMPREPLY=( $( compgen -A hostname -S "$suffix" -- $cur ) ) COMPREPLY=( $( compgen -A hostname -S "$suffix" -- $cur ) )
fi fi
[ $ocur ] && cur=$ocur || unset -v cur
return 0 return 0
} }
complete -F _known_hosts traceroute traceroute6 tracepath tracepath6 \ complete -F _known_hosts traceroute traceroute6 tracepath tracepath6 \

View File

@ -80,7 +80,6 @@ _ssh()
-N -n -q -s -T -t -V -v -X -v -Y -y -b -b -c -D -e -F \ -N -n -q -s -T -t -V -v -X -v -Y -y -b -b -c -D -e -F \
-i -L -l -m -O -o -p -R -S -w' -- $cur ) ) -i -L -l -m -O -o -p -R -S -w' -- $cur ) )
else else
#if [ $COMP_CWORD -eq 1 ]; then
# Search COMP_WORDS for '-F configfile' argument # Search COMP_WORDS for '-F configfile' argument
set -- "${COMP_WORDS[@]}" set -- "${COMP_WORDS[@]}"
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
@ -95,10 +94,8 @@ _ssh()
fi fi
shift shift
done done
_known_hosts_real -a "$optconfigfile" _known_hosts_real -a "$optconfigfile" -h "$cur"
#else
COMPREPLY=( "${COMPREPLY[@]}" $( compgen -c -- $cur ) ) COMPREPLY=( "${COMPREPLY[@]}" $( compgen -c -- $cur ) )
#fi
fi fi
return 0 return 0
@ -145,7 +142,7 @@ _sftp()
fi fi
shift shift
done done
_known_hosts_real -a "$optconfigfile" _known_hosts_real -a "$optconfigfile" -h "$cur"
fi fi
return 0 return 0
@ -201,7 +198,7 @@ _scp()
shift shift
done done
[[ "$cur" == */* ]] || _known_hosts_real -c -a "$optconfigfile" [[ "$cur" == */* ]] || _known_hosts_real -c -a "$optconfigfile" -h "$cur"
# This approach is used instead of _filedir to get a space appended # This approach is used instead of _filedir to get a space appended
# after local file/dir completions, and $nospace retained for others. # after local file/dir completions, and $nospace retained for others.
@ -234,7 +231,7 @@ _ssh_copy_id() {
if [[ "$cur" == -* ]]; then if [[ "$cur" == -* ]]; then
COMPREPLY=( $( compgen -W '-i' -- $cur ) ) COMPREPLY=( $( compgen -W '-i' -- $cur ) )
else else
_known_hosts_real -a _known_hosts_real -a -h "$cur"
fi fi
return 0 return 0

View File

@ -41,7 +41,7 @@ _tightvncviewer()
return 0 return 0
;; ;;
-via) -via)
_known_hosts _known_hosts_real -h "$cur"
return 0 return 0
;; ;;
esac esac
@ -54,7 +54,7 @@ _tightvncviewer()
-compresslevel -quality -nojpeg -nocursorshape \ -compresslevel -quality -nojpeg -nocursorshape \
-x11cursor' -- $cur ) ) -x11cursor' -- $cur ) )
else else
_known_hosts _known_hosts_real -h "$cur"
fi fi
} && } &&
complete -F _tightvncviewer tightvncviewer complete -F _tightvncviewer tightvncviewer
@ -85,7 +85,7 @@ _xvnc4viewer()
;; ;;
# -via # -via
-[vV][iI][aA]) -[vV][iI][aA])
_known_hosts _known_hosts_real -h "$cur"
return 0 return 0
;; ;;
esac esac
@ -121,7 +121,7 @@ _xvnc4viewer()
)" -- "$(echo "$cur" | tr [:upper:] [:lower:])" ) ) )" -- "$(echo "$cur" | tr [:upper:] [:lower:])" ) )
fi fi
else else
_known_hosts _known_hosts_real -h "$cur"
fi fi
} && } &&
complete -F _xvnc4viewer xvnc4viewer complete -F _xvnc4viewer xvnc4viewer

View File

@ -6,27 +6,12 @@
have xhost && have xhost &&
_xhost () _xhost ()
{ {
local cur i local cur=`_get_cword`
cur=`_get_cword`
case "$cur" in case "$cur" in
+*) +*) _known_hosts_real -h "${cur:1}" -p+ ;;
cur=${cur:1} -*) _known_hosts_real -h "${cur:1}" -p- ;;
_known_hosts_real *) _known_hosts_real -h "$cur" ;;
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
COMPREPLY[i]=+${COMPREPLY[i]}
done
;;
-*)
cur=${cur:1}
_known_hosts_real
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
COMPREPLY[i]=-${COMPREPLY[i]}
done
;;
*)
_known_hosts_real
;;
esac esac
return 0 return 0

View File

@ -38,6 +38,44 @@ expect {
sync_after_int sync_after_int
set test "Tab should complete partial hostname"
# Build string list of hostnames, separated by regexp whitespace (\s+)
# Example string: host1\s+host2\s+host3
set hosts {}
set char ""
foreach h [exec bash -c "compgen -A hostname"] {
if {$char == ""} {set char [string range $h 0 0]}
# Only append hostname if starting with $char
if {[string range $h 0 0] == "$char"} {
# Escape special regexp characters (+) in hostname
regsub -all {([\+])} $h {\\\1} h
lappend hosts $h
}; # if
}; # foreach
# Try completion
set cmd "xhost $char"
send "$cmd\t"
# Escape possible special regexp characters (+) in cmd
regsub -all {([\+])} $cmd {\\\1} cmd
if {[llength $hosts] == 1} {
set expected "^xhost $hosts "
} else {
set hosts [lsort -ascii $hosts]
set hosts [join $hosts "\\s+"]
set expected "^$cmd\r\n$hosts\r\n/@$cmd$"
}; # if
expect {
-re $expected { pass "$test" }
-re /@ { unresolved "$test at prompt" }
default { unresolved "$test" }
}; # expect
sync_after_int
set test "Tab should complete hostnames prefixed with +" set test "Tab should complete hostnames prefixed with +"
# Build string list of hostnames, separated by regexp whitespace (\s+) and # Build string list of hostnames, separated by regexp whitespace (\s+) and
@ -68,6 +106,44 @@ expect {
sync_after_int sync_after_int
set test "Tab should complete partial hostname prefixed with +"
# Build string list of hostnames, starting with the character of the first
# host. Separate hostnames by regexp whitespace (\s+) and 'plus' (+)
# prefix. Example string: \+host1\s+\+host2\s+\+host3
set hosts {}
foreach h [exec bash -c "compgen -A hostname"] {
if {$char == ""} {set char [string range $h 0 0]}
# Only append hostname if starting with $char
if {[string range $h 0 0] == "$char"} {
# Escape special regexp characters (+) in hostname
regsub -all {([\+])} $h {\\\1} h
lappend hosts $h
}; # if
}; # foreach
# Try completion
set cmd "xhost +$char"
send "$cmd\t"
if {[llength $hosts] == 1} {
set expected "^xhost \\+$hosts "
} else {
# Escape special regexp characters (+) in cmd
regsub -all {([\+])} $cmd {\\\1} cmd
set hosts [lsort -ascii $hosts]
set hosts [join $hosts "\\s+"]
set expected "^$cmd\r\n$hosts\r\n/@$cmd$"
}; # if
expect {
-re $expected { pass "$test" }
-re /@ { unresolved "$test at prompt" }
default { unresolved "$test" }
}; # expect
sync_after_int
set test "Tab should complete hostnames prefixed with -" set test "Tab should complete hostnames prefixed with -"
# Build string list of hostnames, separated by regexp whitespace (\s+) and # Build string list of hostnames, separated by regexp whitespace (\s+) and
@ -96,4 +172,40 @@ expect {
sync_after_int sync_after_int
set test "Tab should complete partial hostname prefixed with -"
# Build string list of hostnames, starting with the character of the first
# host. Separate hostnames by regexp whitespace (\s+) and 'minus' (-)
# prefix. Example string: -host1\s+-host2\s+-host3
set hosts {}
foreach h [exec bash -c "compgen -A hostname"] {
if {$char == ""} {set char [string range $h 0 0]}
# Only append hostname if starting with $char
if {[string range $h 0 0] == "$char"} {
# Escape special regexp characters (+) in hostname
regsub -all {([\+])} $h {\\\1} h
lappend hosts $h
}; # if
}; # foreach
# Try completion
set cmd "xhost -$char"
send "$cmd\t"
if {[llength $hosts] == 1} {
set expected "^xhost -$hosts "
} else {
set hosts [lsort -ascii $hosts]
set hosts "-[join $hosts "\\s+-"]"
set expected "^$cmd\r\n$hosts\r\n/@$cmd$"
}; # if
expect {
-re $expected { pass "$test" }
-re /@ { unresolved "$test at prompt" }
default { unresolved "$test" }
}; # expect
sync_after_int
teardown teardown