summaryrefslogtreecommitdiff
path: root/bash_completion
diff options
context:
space:
mode:
authorDavid Paleino <dapal@debian.org>2012-01-08 00:19:18 +0100
committerDavid Paleino <dapal@debian.org>2012-01-08 00:19:18 +0100
commitc3d398fcc6e400be546c28eb1fc25abfa5816eac (patch)
tree3266a00f1037eb5522f1f8bf1a73e443ab2c26c4 /bash_completion
parent2c8171c38d87ddef31c92a76547d3fdf773a1337 (diff)
downloadbash-completion-c3d398fcc6e400be546c28eb1fc25abfa5816eac.tar.gz
Imported Upstream version 1.99upstream/1.99
Diffstat (limited to 'bash_completion')
-rw-r--r--bash_completion360
1 files changed, 217 insertions, 143 deletions
diff --git a/bash_completion b/bash_completion
index 62ef87ed..374e20c3 100644
--- a/bash_completion
+++ b/bash_completion
@@ -24,7 +24,7 @@
#
# http://bash-completion.alioth.debian.org/
#
-# RELEASE: 1.90
+# RELEASE: 1.99
if [[ $- == *v* ]]; then
BASH_COMPLETION_ORIGINAL_V_VALUE="-v"
@@ -32,15 +32,15 @@ else
BASH_COMPLETION_ORIGINAL_V_VALUE="+v"
fi
-if [[ -n $BASH_COMPLETION_DEBUG ]]; then
+if [[ ${BASH_COMPLETION_DEBUG-} ]]; then
set -v
else
set +v
fi
-# Alter the following to reflect the location of this file.
+# Set the following to the location of the backwards compat completion dir.
#
-[ -n "$BASH_COMPLETION_COMPAT_DIR" ] || BASH_COMPLETION_COMPAT_DIR=/etc/bash_completion.d
+: ${BASH_COMPLETION_COMPAT_DIR:=/etc/bash_completion.d}
readonly BASH_COMPLETION_COMPAT_DIR
# Blacklisted completions, causing problems with our code.
@@ -102,6 +102,17 @@ _userland()
[[ $userland == $1 ]]
}
+# This function sets correct SysV init directories
+#
+_sysvdirs()
+{
+ sysvdirs=( )
+ [[ -d /etc/rc.d/init.d ]] && sysvdirs+=( /etc/rc.d/init.d )
+ [[ -d /etc/init.d ]] && sysvdirs+=( /etc/init.d )
+ # Slackware uses /etc/rc.d
+ [[ -f /etc/slackware-version ]] && sysvdirs=( /etc/rc.d )
+}
+
# This function checks whether we have a given program on the system.
#
_have()
@@ -131,7 +142,8 @@ _rl_enabled()
# This function shell-quotes the argument
quote()
{
- echo \'${1//\'/\'\\\'\'}\' #'# Help vim syntax highlighting
+ local quoted=${1//\'/\'\\\'\'}
+ printf "'%s'" "$quoted"
}
# @see _quote_readline_by_ref()
@@ -146,7 +158,7 @@ quote_readline()
# This function shell-dequotes the argument
dequote()
{
- eval echo "$1" 2> /dev/null
+ eval printf %s "$1" 2> /dev/null
}
@@ -245,24 +257,21 @@ __reassemble_comp_words_by_ref()
# empty and is word made up of just word separator characters to
# be excluded and is current word not preceded by whitespace in
# original line?
- while [[ $i -gt 0 && ${COMP_WORDS[$i]} &&
- ${COMP_WORDS[$i]//[^$exclude]} == ${COMP_WORDS[$i]}
- ]]; do
+ while [[ $i -gt 0 && ${COMP_WORDS[$i]} == +([$exclude]) ]]; do
# Is word separator not preceded by whitespace in original line
# and are we not going to append to word 0 (the command
# itself), then append to current word.
- [[ ${line:0:1} != ' ' && ${line:0:1} != $'\t' ]] &&
- (( j >= 2 )) && ((j--))
+ [[ $line != [$' \t']* ]] && (( j >= 2 )) && ((j--))
# Append word separator to current or new word
ref="$2[$j]"
eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
# Indicate new cword
- [ $i = $COMP_CWORD ] && eval $3=$j
+ [[ $i == $COMP_CWORD ]] && eval $3=$j
# Remove optional whitespace + word separator from line copy
line=${line#*"${COMP_WORDS[$i]}"}
# Start new word if word separator in original line is
# followed by whitespace.
- [[ ${line:0:1} == ' ' || ${line:0:1} == $'\t' ]] && ((j++))
+ [[ $line == [$' \t']* ]] && ((j++))
# Indicate next word if available, else end *both* while and
# for loop
(( $i < ${#COMP_WORDS[@]} - 1)) && ((i++)) || break 2
@@ -295,14 +304,14 @@ __get_cword_at_cursor_by_ref()
local cword words=()
__reassemble_comp_words_by_ref "$1" words cword
- local i cur cur2 index=$COMP_POINT lead=${COMP_LINE:0:$COMP_POINT}
+ local i cur index=$COMP_POINT lead=${COMP_LINE:0:$COMP_POINT}
# Cursor not at position 0 and not leaded by just space(s)?
if [[ $index -gt 0 && ( $lead && ${lead//[[:space:]]} ) ]]; then
cur=$COMP_LINE
for (( i = 0; i <= cword; ++i )); do
while [[
# Current word fits in $cur?
- "${#cur}" -ge ${#words[i]} &&
+ ${#cur} -ge ${#words[i]} &&
# $cur doesn't match cword?
"${cur:0:${#words[i]}}" != "${words[i]}"
]]; do
@@ -313,11 +322,11 @@ __get_cword_at_cursor_by_ref()
done
# Does found word match cword?
- if [[ "$i" -lt "$cword" ]]; then
+ if [[ $i -lt $cword ]]; then
# No, cword lies further;
- local old_size="${#cur}"
- cur="${cur#${words[i]}}"
- local new_size="${#cur}"
+ local old_size=${#cur}
+ cur="${cur#"${words[i]}"}"
+ local new_size=${#cur}
index=$(( index - old_size + new_size ))
fi
done
@@ -472,7 +481,7 @@ _get_cword()
#
_get_pword()
{
- if [ $COMP_CWORD -ge 1 ]; then
+ if [[ $COMP_CWORD -ge 1 ]]; then
_get_cword "${@:-}" 1
fi
}
@@ -501,7 +510,7 @@ __ltrim_colon_completions()
# Remove colon-word prefix from COMPREPLY items
local colon_word=${1%${1##*:}}
local i=${#COMPREPLY[*]}
- while [ $((--i)) -ge 0 ]; do
+ while [[ $((--i)) -ge 0 ]]; do
COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
done
fi
@@ -526,7 +535,7 @@ __ltrim_colon_completions()
# @param $2 Name of variable to return result to
_quote_readline_by_ref()
{
- if [[ ${1:0:1} == "'" ]]; then
+ if [[ $1 == \'* ]]; then
# Leave out first character
printf -v $2 %s "${1:1}"
else
@@ -536,7 +545,7 @@ _quote_readline_by_ref()
# If result becomes quoted like this: $'string', re-evaluate in order to
# drop the additional quoting. See also: http://www.mail-archive.com/
# bash-completion-devel@lists.alioth.debian.org/msg01942.html
- [[ ${!2:0:1} == '$' ]] && eval $2=${!2}
+ [[ ${!2} == \$* ]] && eval $2=${!2}
} # _quote_readline_by_ref()
@@ -581,9 +590,11 @@ _filedir()
-n "$1" && "$1" != -d && ${#toks[@]} -lt 1 ]] && \
toks+=( $( compgen -f -- $quoted ) )
- [ ${#toks[@]} -ne 0 ] && compopt -o filenames 2>/dev/null
-
- COMPREPLY+=( "${toks[@]}" )
+ if [[ ${#toks[@]} -ne 0 ]]; then
+ # 2>/dev/null for direct invocation, e.g. in the _filedir unit test
+ compopt -o filenames 2>/dev/null
+ COMPREPLY+=( "${toks[@]}" )
+ fi
} # _filedir()
@@ -606,6 +617,20 @@ _split_longopt()
return 1
}
+# Complete variables.
+# @return True (0) if variables were completed,
+# False (> 0) if not.
+_variables()
+{
+ if [[ $cur =~ ^(\$\{?)([A-Za-z0-9_]*)$ ]]; then
+ [[ $cur == *{* ]] && local suffix=} || local suffix=
+ COMPREPLY+=( $( compgen -P ${BASH_REMATCH[1]} -S "$suffix" -v -- \
+ "${BASH_REMATCH[2]}" ) )
+ return 0
+ fi
+ return 1
+}
+
# Initialize completion and deal with various general things: do file
# and variable completion where appropriate, and adjust prev, words,
# and cword as if no redirections exist so that completions do not
@@ -623,7 +648,7 @@ _split_longopt()
#
_init_completion()
{
- local exclude flag outx errx inx OPTIND=1
+ local exclude= flag outx errx inx OPTIND=1
while getopts "n:e:o:i:s" flag "$@"; do
case $flag in
@@ -646,12 +671,7 @@ _init_completion()
_get_comp_words_by_ref -n "$exclude<>&" cur prev words cword
# Complete variable names.
- if [[ $cur =~ ^(\$\{?)([A-Za-z0-9_]*)$ ]]; then
- [[ $cur == *{* ]] && local suffix=} || local suffix=
- COMPREPLY=( $( compgen -P ${BASH_REMATCH[1]} -S "$suffix" -v -- \
- "${BASH_REMATCH[2]}" ) )
- return 1
- fi
+ _variables && return 1
# Complete on files if current is a redirect possibly followed by a
# filename, e.g. ">foo", or previous is a "bare" redirect, e.g. ">".
@@ -690,7 +710,7 @@ _init_completion()
[[ $cword -eq 0 ]] && return 1
prev=${words[cword-1]}
- [[ $split ]] && _split_longopt && split=true
+ [[ ${split-} ]] && _split_longopt && split=true
return 0
}
@@ -727,14 +747,18 @@ __parse_options()
}
# Parse GNU style help output of the given command.
-# @param $1 command
+# @param $1 command; if "-", read from stdin and ignore rest of args
# @param $2 command options (default: --help)
#
_parse_help()
{
- eval local cmd=$1
+ eval local cmd=$( quote "$1" )
local line
- "$cmd" ${2:---help} 2>&1 | while read -r line; do
+ { case $cmd in
+ -) cat ;;
+ *) "$( dequote "$cmd" )" ${2:---help} 2>&1 ;;
+ esac } \
+ | while read -r line; do
[[ $line == *([ $'\t'])-* ]] || continue
# transform "-f FOO, --foo=FOO" to "-f , --foo=FOO" etc
@@ -748,14 +772,18 @@ _parse_help()
}
# Parse BSD style usage output (options in brackets) of the given command.
-# @param $1 command
+# @param $1 command; if "-", read from stdin and ignore rest of args
# @param $2 command options (default: --usage)
#
_parse_usage()
{
- eval local cmd=$1
+ eval local cmd=$( quote "$1" )
local line match option i char
- "$cmd" ${2:---usage} 2>&1 | while read -r line; do
+ { case $cmd in
+ -) cat ;;
+ *) "$( dequote "$cmd" )" ${2:---usage} 2>&1 ;;
+ esac } \
+ | while read -r line; do
while [[ $line =~ \[[[:space:]]*(-[^]]+)[[:space:]]*\] ]]; do
match=${BASH_REMATCH[0]}
@@ -793,9 +821,11 @@ _mac_addresses()
local re='\([A-Fa-f0-9]\{2\}:\)\{5\}[A-Fa-f0-9]\{2\}'
local PATH="$PATH:/sbin:/usr/sbin"
- # Local interfaces (Linux only?)
+ # Local interfaces (Linux: HWAddr, FreeBSD: ether)
COMPREPLY+=( $( ifconfig -a 2>/dev/null | sed -ne \
- "s/.*[[:space:]]HWaddr[[:space:]]\{1,\}\($re\)[[:space:]]*$/\1/p" ) )
+ "s/.*[[:space:]]HWaddr[[:space:]]\{1,\}\($re\)[[:space:]]*$/\1/p" -ne \
+ "s/^[[:space:]]\{1,\}ether[[:space:]]\{1,\}\($re\)[[:space:]]*$/\1/p" \
+ ) )
# ARP cache
COMPREPLY+=( $( arp -an 2>/dev/null | sed -ne \
@@ -814,16 +844,16 @@ _mac_addresses()
#
_configured_interfaces()
{
- if [ -f /etc/debian_version ]; then
+ if [[ -f /etc/debian_version ]]; then
# Debian system
COMPREPLY=( $( compgen -W "$( sed -ne 's|^iface \([^ ]\{1,\}\).*$|\1|p'\
/etc/network/interfaces )" -- "$cur" ) )
- elif [ -f /etc/SuSE-release ]; then
+ elif [[ -f /etc/SuSE-release ]]; then
# SuSE system
COMPREPLY=( $( compgen -W "$( printf '%s\n' \
/etc/sysconfig/network/ifcfg-* | \
sed -ne 's|.*ifcfg-\(.*\)|\1|p' )" -- "$cur" ) )
- elif [ -f /etc/pld-release ]; then
+ elif [[ -f /etc/pld-release ]]; then
# PLD Linux
COMPREPLY=( $( compgen -W "$( command ls -B \
/etc/sysconfig/interfaces | \
@@ -841,7 +871,7 @@ _configured_interfaces()
_ip_addresses()
{
COMPREPLY+=( $( compgen -W \
- "$( PATH="$PATH:/sbin" ifconfig -a |
+ "$( PATH="$PATH:/sbin" LC_ALL=C ifconfig -a |
sed -ne 's/.*addr:\([^[:space:]]*\).*/\1/p' \
-ne 's/.*inet[[:space:]]\{1,\}\([^[:space:]]*\).*/\1/p' )" \
-- "$cur" ) )
@@ -862,9 +892,9 @@ _available_interfaces()
{
local cmd
- if [ "${1:-}" = -w ]; then
+ if [[ ${1:-} == -w ]]; then
cmd="iwconfig"
- elif [ "${1:-}" = -a ]; then
+ elif [[ ${1:-} == -a ]]; then
cmd="ifconfig"
else
cmd="ifconfig -a"
@@ -875,6 +905,14 @@ _available_interfaces()
COMPREPLY=( $( compgen -W '${COMPREPLY[@]/%[[:punct:]]/}' -- "$cur" ) )
}
+# Echo number of CPUs, falling back to 1 on failure.
+_ncpus()
+{
+ local var=NPROCESSORS_ONLN
+ [[ $OSTYPE == *linux* ]] && var=_$var
+ local n=$( getconf $var 2>/dev/null )
+ printf %s ${n:-1}
+}
# Perform tilde (~) completion
# @return True (0) if completion needs further processing,
@@ -887,7 +925,8 @@ _tilde()
# Try generate ~username completions
COMPREPLY=( $( compgen -P '~' -u "${1#\~}" ) )
result=${#COMPREPLY[@]}
- [ $result -gt 0 ] && compopt -o filenames 2>/dev/null
+ # 2>/dev/null for direct invocation, e.g. in the _tilde unit test
+ [[ $result -gt 0 ]] && compopt -o filenames 2>/dev/null
fi
return $result
}
@@ -918,9 +957,9 @@ _tilde()
__expand_tilde_by_ref()
{
# Does $1 start with tilde (~)?
- if [ "${!1:0:1}" = "~" ]; then
+ if [[ ${!1} == ~* ]]; then
# Does $1 contain slash (/)?
- if [ "${!1}" != "${!1//\/}" ]; then
+ if [[ ${!1} == */* ]]; then
# Yes, $1 contains slash;
# 1: Remove * including and after first slash (/), i.e. "~a/b"
# becomes "~a". Double quotes allow eval.
@@ -952,7 +991,7 @@ _expand()
elif [[ "$cur" == \~* ]]; then
cur=${cur#\~}
COMPREPLY=( $( compgen -P '~' -u "$cur" ) )
- [ ${#COMPREPLY[@]} -eq 1 ] && eval COMPREPLY[0]=${COMPREPLY[0]}
+ [[ ${#COMPREPLY[@]} -eq 1 ]] && eval COMPREPLY[0]=${COMPREPLY[0]}
return ${#COMPREPLY[@]}
fi
}
@@ -1037,37 +1076,75 @@ _gids()
#
_backup_glob='@(#*#|*@(~|.@(bak|orig|rej|swp|dpkg*|rpm@(orig|new|save))))'
+# Complete on xinetd services
+#
+_xinetd_services()
+{
+ local xinetddir=/etc/xinetd.d
+ if [[ -d $xinetddir ]]; then
+ local restore_nullglob=$(shopt -p nullglob); shopt -s nullglob
+ local -a svcs=( $( printf '%s\n' $xinetddir/!($_backup_glob) ) )
+ $restore_nullglob
+ COMPREPLY+=( $( compgen -W '${svcs[@]#$xinetddir/}' -- "$cur" ) )
+ fi
+}
+
# This function completes on services
#
_services()
{
- local sysvdir famdir
- [ -d /etc/rc.d/init.d ] && sysvdir=/etc/rc.d/init.d || sysvdir=/etc/init.d
- famdir=/etc/xinetd.d
+ local sysvdirs
+ _sysvdirs
local restore_nullglob=$(shopt -p nullglob); shopt -s nullglob
-
- COMPREPLY=( $( printf '%s\n' $sysvdir/!($_backup_glob|functions) ) )
-
- if [ -d $famdir ]; then
- COMPREPLY+=( $( printf '%s\n' $famdir/!($_backup_glob) ) )
- fi
-
+ COMPREPLY=( $( printf '%s\n' ${sysvdirs[0]}/!($_backup_glob|functions) ) )
$restore_nullglob
COMPREPLY+=( $( systemctl list-units --full --all 2>/dev/null | \
awk '$1 ~ /\.service$/ { sub("\\.service$", "", $1); print $1 }' ) )
- COMPREPLY=( $( compgen -W '${COMPREPLY[@]#@($sysvdir|$famdir)/}' -- "$cur" ) )
+ COMPREPLY=( $( compgen -W '${COMPREPLY[@]#${sysvdirs[0]}/}' -- "$cur" ) )
}
+# This completes on a list of all available service scripts for the
+# 'service' command and/or the SysV init.d directory, followed by
+# that script's available commands
+#
+_service()
+{
+ local cur prev words cword
+ _init_completion || return
+
+ # don't complete past 2nd token
+ [[ $cword -gt 2 ]] && return 0
+
+ if [[ $cword -eq 1 && $prev == ?(*/)service ]]; then
+ _services
+ [[ -e /etc/mandrake-release ]] && _xinetd_services
+ else
+ local sysvdirs
+ _sysvdirs
+ COMPREPLY=( $( compgen -W '`sed -e "y/|/ /" \
+ -ne "s/^.*\(U\|msg_u\)sage.*{\(.*\)}.*$/\2/p" \
+ ${sysvdirs[0]}/${prev##*/} 2>/dev/null` start stop' -- "$cur" ) )
+ fi
+} &&
+complete -F _service service
+_sysvdirs
+for svcdir in ${sysvdirs[@]}; do
+ for svc in $svcdir/!($_backup_glob); do
+ [[ -x $svc ]] && complete -F _service $svc
+ done
+done
+unset svc svcdir sysvdirs
+
# This function completes on modules
#
_modules()
{
local modpath
modpath=/lib/modules/$1
- COMPREPLY=( $( compgen -W "$( command ls -R $modpath | \
+ COMPREPLY=( $( compgen -W "$( command ls -RL $modpath | \
sed -ne 's/^\(.*\)\.k\{0,1\}o\(\.gz\)\{0,1\}$/\1/p' )" -- "$cur" ) )
}
@@ -1172,7 +1249,7 @@ _fstypes()
{
local fss
- if [ -e /proc/filesystems ] ; then
+ if [[ -e /proc/filesystems ]]; then
# Linux
fss="$( cut -d$'\t' -f2 /proc/filesystems )
$( awk '! /\*/ { print $NF }' /etc/filesystems 2>/dev/null )"
@@ -1182,11 +1259,10 @@ _fstypes()
$( awk '/^[ \t]*[^#]/ { print $3 }' /etc/mnttab 2>/dev/null )
$( awk '/^[ \t]*[^#]/ { print $4 }' /etc/vfstab 2>/dev/null )
$( awk '{ print $1 }' /etc/dfs/fstypes 2>/dev/null )
- $( [ -d /etc/fs ] && command ls /etc/fs )"
+ $( [[ -d /etc/fs ]] && command ls /etc/fs )"
fi
- [ -n "$fss" ] && \
- COMPREPLY+=( $( compgen -W "$fss" -- "$cur" ) )
+ [[ -n $fss ]] && COMPREPLY+=( $( compgen -W "$fss" -- "$cur" ) )
}
# Get real command.
@@ -1340,53 +1416,58 @@ _known_hosts_real()
p) prefix=$OPTARG ;;
esac
done
- [ $# -lt $OPTIND ] && echo "error: $FUNCNAME: missing mandatory argument CWORD"
+ [[ $# -lt $OPTIND ]] && echo "error: $FUNCNAME: missing mandatory argument CWORD"
cur=${!OPTIND}; let "OPTIND += 1"
- [ $# -ge $OPTIND ] && echo "error: $FUNCNAME("$@"): unprocessed arguments:"\
- $(while [ $# -ge $OPTIND ]; do printf '%s\n' ${!OPTIND}; shift; done)
+ [[ $# -ge $OPTIND ]] && echo "error: $FUNCNAME("$@"): unprocessed arguments:"\
+ $(while [[ $# -ge $OPTIND ]]; do printf '%s\n' ${!OPTIND}; shift; done)
[[ $cur == *@* ]] && user=${cur%@*}@ && cur=${cur#*@}
kh=()
# ssh config files
- if [ -n "$configfile" ]; then
- [ -r "$configfile" ] &&
- config+=( "$configfile" )
+ if [[ -n $configfile ]]; then
+ [[ -r $configfile ]] && config+=( "$configfile" )
else
- for i in /etc/ssh/ssh_config "${HOME}/.ssh/config" \
- "${HOME}/.ssh2/config"; do
- [ -r $i ] && config+=( "$i" )
+ for i in /etc/ssh/ssh_config ~/.ssh/config ~/.ssh2/config; do
+ [[ -r $i ]] && config+=( "$i" )
done
fi
# Known hosts files from configs
- if [ ${#config[@]} -gt 0 ]; then
- local OIFS=$IFS IFS=$'\n'
+ if [[ ${#config[@]} -gt 0 ]]; then
+ local OIFS=$IFS IFS=$'\n' j
local -a tmpkh
# expand paths (if present) to global and user known hosts files
# TODO(?): try to make known hosts files with more than one consecutive
# spaces in their name work (watch out for ~ expansion
# breakage! Alioth#311595)
tmpkh=( $( awk 'sub("^[ \t]*([Gg][Ll][Oo][Bb][Aa][Ll]|[Uu][Ss][Ee][Rr])[Kk][Nn][Oo][Ww][Nn][Hh][Oo][Ss][Tt][Ss][Ff][Ii][Ll][Ee][ \t]+", "") { print $0 }' "${config[@]}" | sort -u ) )
+ IFS=$OIFS
for i in "${tmpkh[@]}"; do
- # Remove possible quotes
- i=${i//\"}
- # Eval/expand possible `~' or `~user'
- __expand_tilde_by_ref i
- [ -r "$i" ] && kh+=( "$i" )
+ # First deal with quoted entries...
+ while [[ $i =~ ^([^\"]*)\"([^\"]*)\"(.*)$ ]]; do
+ i=${BASH_REMATCH[1]}${BASH_REMATCH[3]}
+ j=${BASH_REMATCH[2]}
+ __expand_tilde_by_ref j # Eval/expand possible `~' or `~user'
+ [[ -r $j ]] && kh+=( "$j" )
+ done
+ # ...and then the rest.
+ for j in $i; do
+ __expand_tilde_by_ref j # Eval/expand possible `~' or `~user'
+ [[ -r $j ]] && kh+=( "$j" )
+ done
done
- IFS=$OIFS
fi
- if [ -z "$configfile" ]; then
+ if [[ -z $configfile ]]; then
# Global and user known_hosts files
for i in /etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2 \
/etc/known_hosts /etc/known_hosts2 ~/.ssh/known_hosts \
~/.ssh/known_hosts2; do
- [ -r $i ] && kh+=( $i )
+ [[ -r $i ]] && kh+=( "$i" )
done
for i in /etc/ssh2/knownhosts ~/.ssh2/hostkeys; do
- [ -d $i ] && khd+=( $i/*pub )
+ [[ -d $i ]] && khd+=( "$i"/*pub )
done
fi
@@ -1404,23 +1485,25 @@ _known_hosts_real()
# Digits followed by no dot or colon - search for digits followed
# by a dot or a colon
awkcur="^$awkcur.*[.:]"
- elif [ -z "$awkcur" ]; then
+ elif [[ -z $awkcur ]]; then
# A blank - search for a dot, a colon, or an alpha character
awkcur="[a-z.:]"
else
awkcur="^$awkcur"
fi
- if [ ${#kh[@]} -gt 0 ]; then
+ if [[ ${#kh[@]} -gt 0 ]]; then
# FS needs to look for a comma separated list
COMPREPLY+=( $( awk 'BEGIN {FS=","}
- /^\s*[^|\#]/ {for (i=1; i<=2; ++i) { \
- sub(" .*$", "", $i); \
+ /^\s*[^|\#]/ {
+ sub("^@[^ ]+ +", ""); \
+ sub(" .*$", ""); \
+ for (i=1; i<=NF; ++i) { \
sub("^\\[", "", $i); sub("\\](:[0-9]+)?$", "", $i); \
- if ($i ~ /'"$awkcur"'/) {print $i} \
+ if ($i !~ /[*?]/ && $i ~ /'"$awkcur"'/) {print $i} \
}}' "${kh[@]}" 2>/dev/null ) )
fi
- if [ ${#khd[@]} -gt 0 ]; then
+ if [[ ${#khd[@]} -gt 0 ]]; then
# Needs to look for files called
# .../.ssh2/key_22_<hostname>.pub
# dont fork any processes, because in a cluster environment,
@@ -1460,9 +1543,13 @@ _known_hosts_real()
awk -F';' '/^=/ { print $7 }' | sort -u )" -- "$cur" ) )
fi
+ # Add hosts reported by ruptime.
+ COMPREPLY+=( $( compgen -W \
+ "$( ruptime 2>/dev/null | awk '{ print $1 }' )" -- "$cur" ) )
+
# Add results of normal hostname completion, unless
# `COMP_KNOWN_HOSTS_WITH_HOSTFILE' is set to an empty value.
- if [ -n "${COMP_KNOWN_HOSTS_WITH_HOSTFILE-1}" ]; then
+ if [[ -n ${COMP_KNOWN_HOSTS_WITH_HOSTFILE-1} ]]; then
COMPREPLY+=(
$( compgen -A hostname -P "$prefix$user" -S "$suffix" -- "$cur" ) )
fi
@@ -1483,11 +1570,6 @@ _cd()
_init_completion || return
local IFS=$'\n' i j k
- # try to allow variable completion
- if [[ "$cur" == ?(\\)\$* ]]; then
- COMPREPLY=( $( compgen -v -P '$' -- "${cur#?(\\)$}" ) )
- return 0
- fi
compopt -o filenames
@@ -1557,16 +1639,16 @@ _command_offset()
# find new first word position, then
# rewrite COMP_LINE and adjust COMP_POINT
- local word_offset=$1
- local first_word=${COMP_WORDS[$word_offset]} char_offset i
- for (( i=0; i <= ${#COMP_LINE}; i++ )); do
- if [[ "${COMP_LINE:$i:${#first_word}}" == "$first_word" ]]; then
- char_offset=$i
- break
- fi
+ local word_offset=$1 i j
+ for (( i=0; i < $word_offset; i++ )); do
+ for (( j=0; j <= ${#COMP_LINE}; j++ )); do
+ [[ "$COMP_LINE" == "${COMP_WORDS[i]}"* ]] && break
+ COMP_LINE=${COMP_LINE:1}
+ ((COMP_POINT--))
+ done
+ COMP_LINE=${COMP_LINE#"${COMP_WORDS[i]}"}
+ ((COMP_POINT-=${#COMP_WORDS[i]}))
done
- COMP_LINE=${COMP_LINE:$char_offset}
- COMP_POINT=$(( COMP_POINT - $char_offset ))
# shift COMP_WORDS elements and adjust COMP_CWORD
for (( i=0; i <= COMP_CWORD - $word_offset; i++ )); do
@@ -1575,7 +1657,7 @@ _command_offset()
for (( i; i <= COMP_CWORD; i++ )); do
unset COMP_WORDS[i]
done
- COMP_CWORD=$(( $COMP_CWORD - $word_offset ))
+ ((COMP_CWORD -= $word_offset))
COMPREPLY=()
local cur
@@ -1588,28 +1670,21 @@ _command_offset()
else
local cmd=${COMP_WORDS[0]} compcmd=${COMP_WORDS[0]}
local cspec=$( complete -p $cmd 2>/dev/null )
+
+ # If we have no completion for $cmd yet, see if we have for basename
+ if [[ ! $cspec && $cmd == */* ]]; then
+ cspec=$( complete -p ${cmd##*/} 2>/dev/null )
+ [[ $cspec ]] && compcmd=${cmd##*/}
+ fi
+ # If still nothing, just load it for the basename
if [[ ! $cspec ]]; then
- if [[ $cmd == */* ]]; then
- # Load completion for full path
- _completion_loader $cmd
- if [[ $? -eq 124 ]]; then
- # Success, but we may now have the full path completion...
- cspec=$( complete -p $cmd 2>/dev/null )
- if [[ ! $cspec ]]; then
- # ...or just the basename one.
- compcmd=${cmd##*/}
- cspec=$( complete -p $compcmd 2>/dev/null )
- fi
- fi
- else
- # Simple, non-full path case.
- _completion_loader $cmd
- [[ $? -eq 124 ]] && cspec=$( complete -p $cmd 2>/dev/null )
- fi
+ compcmd=${cmd##*/}
+ _completion_loader $compcmd
+ cspec=$( complete -p $compcmd 2>/dev/null )
fi
if [[ -n $cspec ]]; then
- if [ "${cspec#* -F }" != "$cspec" ]; then
+ if [[ ${cspec#* -F } != $cspec ]]; then
# complete -F <function>
# get function name
@@ -1627,7 +1702,7 @@ _command_offset()
while true; do
# FIXME: should we take "+o opt" into account?
t=${cspec#*-o }
- if [ "$t" == "$cspec" ]; then
+ if [[ $t == $cspec ]]; then
break
fi
opt=${t%% *}
@@ -1639,7 +1714,9 @@ _command_offset()
cspec=${cspec%%$compcmd}
COMPREPLY=( $( eval compgen "$cspec" -- "$cur" ) )
fi
- elif [ ${#COMPREPLY[@]} -eq 0 ]; then
+ elif [[ ${#COMPREPLY[@]} -eq 0 ]]; then
+ # XXX will probably never happen as long as completion loader loads
+ # *something* for every command thrown at it ($cspec != empty)
_minimal
fi
fi
@@ -1651,7 +1728,7 @@ _root_command()
{
local PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin
local root_command=$1
- _command $1 $2 $3
+ _command
}
complete -F _root_command fakeroot gksu gksudo kdesudo really sudo
@@ -1748,13 +1825,15 @@ _filedir_xspec()
toks+=( $(
eval compgen -f -X "!$xspec" -- "\$(quote_readline "\$cur")" | {
while read -r tmp; do
- [ -n $tmp ] && printf '%s\n' $tmp
+ [[ -n $tmp ]] && printf '%s\n' $tmp
done
}
))
- [ ${#toks[@]} -ne 0 ] && compopt -o filenames
- COMPREPLY=( "${toks[@]}" )
+ if [[ ${#toks[@]} -ne 0 ]]; then
+ compopt -o filenames
+ COMPREPLY=( "${toks[@]}" )
+ fi
}
_install_xspec()
@@ -1778,7 +1857,8 @@ _install_xspec '!*.@(tlz|lzma)' lzcat lzegrep lzfgrep lzgrep lzless lzmore unlzm
_install_xspec '!*.@(?(t)xz|tlz|lzma)' unxz xzcat
_install_xspec '!*.lrz' lrunzip
_install_xspec '!*.@(gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx)' ee
-_install_xspec '!*.@(gif|jp?(e)g|tif?(f)|png|p[bgp]m|bmp|x[bp]m|rle|rgb|pcx|fits|pm)' xv qiv
+_install_xspec '!*.@(gif|jp?(e)g|tif?(f)|png|p[bgp]m|bmp|x[bp]m|rle|rgb|pcx|fits|pm)' qiv
+_install_xspec '!*.@(gif|jp?(e)g|tif?(f)|png|p[bgp]m|bmp|x[bp]m|rle|rgb|pcx|fits|pm|?(e)ps)' xv
_install_xspec '!*.@(@(?(e)ps|?(E)PS|pdf|PDF)?(.gz|.GZ|.bz2|.BZ2|.Z))' gv ggv kghostview
_install_xspec '!*.@(dvi|DVI)?(.@(gz|Z|bz2))' xdvi kdvi
_install_xspec '!*.dvi' dvips dviselect dvitype dvipdf advi dvipdfm dvipdfmx
@@ -1801,8 +1881,7 @@ _install_xspec '!*.fig' xfig
_install_xspec '!*.@(mid?(i)|cmf)' playmidi
_install_xspec '!*.@(mid?(i)|rmi|rcp|[gr]36|g18|mod|xm|it|x3m|s[3t]m|kar)' timidity
_install_xspec '!*.@(669|abc|am[fs]|d[bs]m|dmf|far|it|mdl|m[eo]d|mid?(i)|mt[2m]|okta|p[st]m|s[3t]m|ult|umx|wav|xm)' modplugplay modplug123
-_install_xspec '*.@(o|so|so.!(conf)|a|[rs]pm|gif|jp?(e)g|mp3|mp?(e)g|avi|asf|ogg|class)' vi vim gvim rvim view rview rgvim rgview gview emacs xemacs sxemacs kate kwrite
-_install_xspec '!*.@([eE][xX][eE]?(.[sS][oO])|[cC][oO][mM]|[sS][cC][rR])' wine
+_install_xspec '*.@(o|so|so.!(conf|*/*)|a|[rs]pm|gif|jp?(e)g|mp3|mp?(e)g|avi|asf|ogg|class)' vi vim gvim rvim view rview rgvim rgview gview emacs xemacs sxemacs kate kwrite
_install_xspec '!*.@(zip|z|gz|tgz)' bzme
# konqueror not here on purpose, it's more than a web/html browser
_install_xspec '!*.@(?([xX]|[sS])[hH][tT][mM]?([lL]))' netscape mozilla lynx opera galeon dillo elinks amaya firefox mozilla-firefox iceweasel google-chrome chromium-browser epiphany
@@ -1839,11 +1918,6 @@ _completion_loader()
local compdir=./completions
[[ $BASH_SOURCE == */* ]] && compdir="${BASH_SOURCE%/*}/completions"
- # Special case for init.d scripts.
- if [[ $1 == /etc?(/rc.d)/init.d/* ]]; then
- . "$compdir/service" &>/dev/null && return 124 || return 1
- fi
-
# Try basename.
. "$compdir/${1##*/}" &>/dev/null && return 124
@@ -1878,7 +1952,7 @@ if [[ -d $BASH_COMPLETION_COMPAT_DIR && -r $BASH_COMPLETION_COMPAT_DIR && \
&& -f $i && -r $i ]] && . "$i"
done
fi
-unset i
+unset i _blacklist_glob
# source user completion file
[[ ${BASH_SOURCE[0]} != ~/.bash_completion && -r ~/.bash_completion ]] \