
created _filedir(), which is used by cat, less, more, ln and strip, so that tilde expansion can be performed, prior to pathname expansion
1671 lines
41 KiB
Bash
1671 lines
41 KiB
Bash
# bash_completion - some programmable completion functions for bash 2.05a
|
|
#
|
|
# <![CDATA[
|
|
#
|
|
# $Id: bash_completion,v 1.68 2002/01/24 00:36:30 ianmacd Exp $
|
|
#
|
|
# Copyright (C) Ian Macdonald <ian@caliban.org>
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2, or (at your option)
|
|
# any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software Foundation,
|
|
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
# RELEASE: 20020121
|
|
|
|
[ -n "$DEBUG" ] && set -v || set +v
|
|
# Set a couple of useful vars
|
|
#
|
|
OS=$( uname -s )
|
|
RELEASE=$( uname -r )
|
|
|
|
# Turn on extended globbing and programmable completion
|
|
shopt -s extglob progcomp
|
|
|
|
# A lot of the following one-liners were taken directly from the
|
|
# completion examples provided with the bash 2.04 source distribution
|
|
|
|
# Make directory commands see only directories
|
|
complete -d mkdir rmdir pushd
|
|
|
|
# the following section lists completions that are redefined later
|
|
# START exclude -- do NOT remove this line
|
|
#complete -f -X '*.bz2' bzip2
|
|
complete -f -X '!*.bz2' bunzip2
|
|
complete -f -X '!*.+(zip|ZIP|jar|JAR)' unzip
|
|
#complete -f -X '*.gz' gzip
|
|
complete -f -X '*.Z' compress
|
|
complete -f -X '!*.+(Z|gz|tgz|Gz)' gunzip zcat zmore
|
|
complete -f -X '!*.Z' uncompress
|
|
complete -f -X '!*.+(gif|jpg|jpeg|tif|tiff|png|GIF|JPG|TIF|TIFF|PNG|bmp)' ee xv
|
|
complete -f -X '!*.+(?(e)ps|?(E)PS|?(e)ps.gz|pdf|PDF)' gv ggv
|
|
complete -f -X '!*.+(dvi|DVI)' dvips xdvi dviselect dvitype
|
|
complete -f -X '!*.+(pdf|PDF)' acroread xpdf
|
|
complete -f -X '!*.texi*' makeinfo texi2dvi texi2html
|
|
complete -f -X '!*.+(tex|TEX)' tex latex slitex jadetex pdfjadetex
|
|
complete -f -X '!*.+(mp3|MP3)' mpg123
|
|
complete -f -X '!*.+(mpg|mpeg|avi|asf|vob|bin|vcd|ps|pes|fli|viv|rm|ram|yuv)' mplayer
|
|
complete -f -X '!*.+(avi|asf)' avifile
|
|
complete -f -X '!*.+(rm|ram)' realplay
|
|
complete -f -X '!*.+(mpg|mpeg|avi|mov)' xanim
|
|
complete -f -X '!*.+(ogg|OGG)' ogg123
|
|
complete -f -X '!*.+(mp3|MP3|ogg|OGG)' xmms gqmpeg freeamp
|
|
# FINISH exclude -- do not remove this line
|
|
|
|
# kill sees only signals
|
|
complete -A signal -P '-' kill
|
|
|
|
# user commands see only users
|
|
complete -u finger su usermod userdel passwd
|
|
|
|
# group commands see only groups
|
|
complete -g groupmod groupdel passwd
|
|
|
|
# bg completes with stopped jobs
|
|
complete -A stopped -P '%' bg
|
|
|
|
# other job commands
|
|
complete -j -P '%' fg jobs disown
|
|
|
|
# network commands complete with hostname
|
|
complete -A hostname ssh rsh telnet rlogin ftp ping fping host traceroute \
|
|
nslookup
|
|
|
|
# export and others complete with shell variables
|
|
complete -v export local readonly unset
|
|
|
|
# set completes with set options
|
|
complete -A setopt set
|
|
|
|
# shopt completes with shopt options
|
|
complete -A shopt shopt
|
|
|
|
# helptopics
|
|
complete -A helptopic help
|
|
|
|
# unalias completes with aliases
|
|
complete -a unalias
|
|
|
|
# bind completes with readline bindings (make this more intelligent)
|
|
complete -A binding bind
|
|
|
|
# Now we get to the meat of the file, the functions themselves. Some
|
|
# of these are works in progress. Most assume GNU versions of the
|
|
# tools in question and may require modifications for use on vanilla
|
|
# UNIX systems.
|
|
#
|
|
# A couple of functions may have non-portable, Linux specific code in
|
|
# them, but this will be noted where applicable
|
|
|
|
# This function is handy for checking whether we have certain programs
|
|
# on the system. No need for bulky functions in memory if we don't.
|
|
#
|
|
have()
|
|
{
|
|
unset -v have
|
|
type $1 &> /dev/null
|
|
[ $? = 0 ] && have="yes"
|
|
}
|
|
|
|
|
|
# GNU chown(1) completion. This should be expanded to allow the use of
|
|
# ':' as well as '.' as the user.group separator.
|
|
#
|
|
_chown()
|
|
{
|
|
local cur prev user group i
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
# do not attempt completion if we're specifying an option
|
|
[ "$cur" == -* ] && return 0
|
|
|
|
# first parameter on line or first since an option?
|
|
if [ $COMP_CWORD = 1 ] || [[ "$prev" == -* ]]; then
|
|
if [[ "$cur" == [a-zA-Z]*.* ]]; then
|
|
user=${cur%.*}
|
|
group=${cur#*.}
|
|
COMPREPLY=( $( compgen -g $group ) )
|
|
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
|
|
COMPREPLY[i]=$user.${COMPREPLY[i]}
|
|
done
|
|
else
|
|
COMPREPLY=( $( compgen -u $cur -S '.' ) )
|
|
fi
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
complete -F _chown -o default chown
|
|
|
|
# chgrp(1) completion
|
|
#
|
|
_chgrp()
|
|
{
|
|
local cur prev
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
# do not attempt completion if we're specifying an option
|
|
[ "$cur" == -* ] && return 0
|
|
|
|
# first parameter on line or first since an option?
|
|
if [ $COMP_CWORD = 1 ] || [[ "$prev" == -* ]]; then
|
|
COMPREPLY=( $( compgen -g $cur ) )
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
complete -F _chgrp -o default chgrp
|
|
|
|
# umount(8) completion. This relies on the mount point being the third
|
|
# space-delimited field in the output of mount(8)
|
|
#
|
|
_umount()
|
|
{
|
|
local cur
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
|
|
# could rewrite the cut | grep to be a sed command, but this is
|
|
# clearer and doesn't result in much overhead
|
|
COMPREPLY=( $( mount | cut -d' ' -f 3 | grep ^$cur) )
|
|
|
|
return 0
|
|
}
|
|
complete -F _umount -o filenames umount
|
|
|
|
# mount(8) completion. This will pull a list of possible mounts out of
|
|
# /etc/fstab, unless the word being completed contains a ':', which
|
|
# would indicate the specification of an NFS server. In that case, we
|
|
# query the server for a list of all available exports and complete on
|
|
# that instead.
|
|
#
|
|
_mount()
|
|
|
|
{ local cur i sm
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
for i in {,/usr}/sbin/showmount; do [ -x $i ] && sm=$i && break; done
|
|
|
|
if [ -n "$sm" ] && [[ "$cur" == *:* ]]; then
|
|
COMPREPLY=( $( $sm -e --no-headers ${cur%%:*} | \
|
|
grep ^${cur#*:} | awk '{print $1}' ) )
|
|
else
|
|
COMPREPLY=( $( awk '{if ($2 ~ /\//) print $2}' /etc/fstab | \
|
|
grep ^$cur ) )
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
complete -F _mount -o default mount
|
|
|
|
# Linux rmmod(1) completion. This completes on a list of all currently
|
|
# installed kernel modules.
|
|
#
|
|
[ $OS = Linux ] &&
|
|
_rmmod()
|
|
{
|
|
local cur
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
|
|
COMPREPLY=( $( /sbin/lsmod | \
|
|
awk '{if (NR != 1 && $1 ~ /^'$cur'/) print $1}' ) )
|
|
return 0
|
|
}
|
|
[ $OS = Linux ] && complete -F _rmmod rmmod
|
|
|
|
# Linux insmod(8) & modprobe(8) completion. This completes on a list of all
|
|
# available modules for the version of the kernel currently running.
|
|
#
|
|
[ $OS = Linux ] &&
|
|
_insmod()
|
|
{
|
|
local cur prev modpath
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
modpath=/lib/modules/`uname -r`
|
|
|
|
# behave like lsmod for modprobe -r
|
|
if [ ${COMP_WORDS[0]} = "modprobe" ] &&
|
|
[ "${COMP_WORDS[1]}" = "-r" ]; then
|
|
COMPREPLY=( $( /sbin/lsmod | \
|
|
awk '{if (NR != 1 && $1 ~ /^'$cur'/) print $1}' ) )
|
|
return 0
|
|
fi
|
|
|
|
# do filename completion if we're giving a path to a module
|
|
if [[ "$cur" == /* ]]; then
|
|
COMPREPLY=( $( compgen -f $cur ) )
|
|
return 0
|
|
fi
|
|
|
|
if [ $COMP_CWORD -gt 1 ]; then
|
|
# do module parameter completion
|
|
COMPREPLY=( $( /sbin/modinfo -p ${COMP_WORDS[1]} | \
|
|
awk '{if ($1 ~ /^'$cur'/) print $1}' ) )
|
|
else
|
|
# do module name completion
|
|
COMPREPLY=( $( \ls -R $modpath | \
|
|
sed -ne 's/^\('$cur'.*\)\.o$/\1/p') )
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
[ $OS = Linux ] && complete -F _insmod -o filenames insmod modprobe
|
|
|
|
# man(1) completion. This is Linux specific, in that 'man <section> <page>'
|
|
# is the expected syntax. This allows one to do something like
|
|
# 'man 3 str<tab>' to obtain a list of all string handling syscalls on
|
|
# the system.
|
|
#
|
|
[ $OS = Linux ] &&
|
|
_man()
|
|
{
|
|
local cur prev cmd
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
# default completion if parameter contains /
|
|
[[ "$cur" == */* ]] && return 0
|
|
# default to command completion if no man.config
|
|
if [ ! -f /etc/man.config ]; then
|
|
COMPREPLY=( $( compgen -c $cur ) )
|
|
return 0
|
|
fi
|
|
|
|
if [[ "$prev" == [0-9ln] ]]; then
|
|
# churn out a string of paths to search, with * appended to $cur
|
|
cmd=`awk '{if ($1 ~ /^MANPATH/) \
|
|
print $(NF)"/man'$prev'/'$cur'*"}' /etc/man.config | \
|
|
sort -u`
|
|
# strip off * from paths ending in /*
|
|
cmd=${cmd//\/\\*/\/}
|
|
# redirect stderr for when path doesn't exist
|
|
cmd="ls $cmd 2>/dev/null"
|
|
COMPREPLY=( $( eval $cmd ) )
|
|
# get basename of man pages
|
|
COMPREPLY=( ${COMPREPLY[@]##*/} )
|
|
# strip suffix from man pages
|
|
COMPREPLY=( ${COMPREPLY[@]%.gz} )
|
|
COMPREPLY=( ${COMPREPLY[@]%.*} )
|
|
else
|
|
cmd=`awk '{if ($1 ~ /^MANPATH/) \
|
|
print $(NF)"/man?/'$cur'*"}' /etc/man.config | sort -u`
|
|
cmd=${cmd//\/\\*/\/}
|
|
cmd="ls $cmd 2>/dev/null"
|
|
COMPREPLY=( $( eval $cmd ) )
|
|
COMPREPLY=( ${COMPREPLY[@]##*/} )
|
|
COMPREPLY=( ${COMPREPLY[@]%.gz} )
|
|
COMPREPLY=( ${COMPREPLY[@]%.*} $( compgen -G $cur\*.[0-9ln] ) )
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
[ $OS = Linux ] && complete -F _man -o default man
|
|
|
|
# Linux killall(1) completion. This wouldn't be much use on, say,
|
|
# Solaris, where killall does exactly that: kills ALL processes.
|
|
#
|
|
# This could be improved. For example, it currently doesn't take
|
|
# command line options into account
|
|
#
|
|
_killall()
|
|
{
|
|
local cur prev i
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
if [[ "$prev" == -[A-Z0-9]* ]]; then
|
|
# get a list of processes (the gensub() in the awk takes care
|
|
# of getting the basename of the process, the first sed
|
|
# evaluation takes care of swapped out processes, and the
|
|
# second takes care of getting the basename of the process)
|
|
COMPREPLY=( $( ps ahx | sed -e 's#[]\[()]##g' | \
|
|
awk '{if (gensub("^.*/","",1,$5) ~ /^'$cur'/) print $5}' | \
|
|
sed -e 's#^.*/##' ) )
|
|
return 0
|
|
fi
|
|
|
|
# first parameter can be either a signal or a process
|
|
if [ $COMP_CWORD = 1 ]; then
|
|
# standard signal completion is rather braindead, so we need
|
|
# to hack around to get what we want here, which is to
|
|
# complete on a dash, followed by the signal name minus
|
|
# the SIG prefix
|
|
COMPREPLY=( $( compgen -A signal SIG${cur#-} ))
|
|
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
|
|
COMPREPLY[i]=-${COMPREPLY[i]#SIG}
|
|
done
|
|
fi
|
|
|
|
# get processes, adding to signals if applicable
|
|
COMPREPLY=( ${COMPREPLY[*]} $( ps ahx | sed -e 's#[]\[()]##g' | \
|
|
awk '{if (gensub("^.*/","",1,$5) ~ /^'$cur'/) print $5}' | \
|
|
sed -e 's#^.*/##' ))
|
|
return 0
|
|
}
|
|
complete -F _killall killall
|
|
|
|
# GNU find(1) completion. This makes heavy use of ksh style extended
|
|
# globs and contains Linux specific code for completing the parameter
|
|
# to the -fstype option.
|
|
#
|
|
_find()
|
|
{
|
|
local cur prev i
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]#-}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
case "$prev" in
|
|
-@(max|min)depth)
|
|
COMPREPLY=( $( compgen -W '0 1 2 3 4 5 6 7 8 9' ) )
|
|
return 0
|
|
;;
|
|
-?(a)newer|-fls|-fprint?(0|f))
|
|
COMPREPLY=( $( compgen -f $cur ) )
|
|
return 0
|
|
;;
|
|
-fstype)
|
|
# this is highly non-portable
|
|
COMPREPLY=( $( cut -d$'\t' -f 2 /proc/filesystems | grep ^$cur ) )
|
|
return 0
|
|
;;
|
|
-gid)
|
|
COMPREPLY=( $( awk 'BEGIN {FS=":"} \
|
|
{if ($3 ~ /^'$cur'/) print $3}' /etc/group ) )
|
|
return 0
|
|
;;
|
|
-group)
|
|
COMPREPLY=( $( compgen -g $cur ) )
|
|
return 0
|
|
;;
|
|
-?(x)type)
|
|
COMPREPLY=( $( compgen -W 'b c d p f l s' $cur ) )
|
|
return 0
|
|
;;
|
|
-uid)
|
|
COMPREPLY=( $( awk 'BEGIN {FS=":"} \
|
|
{if ($3 ~ /^'$cur'/) print $3}' /etc/passwd ) )
|
|
return 0
|
|
;;
|
|
-user)
|
|
COMPREPLY=( $( compgen -u $cur ) )
|
|
return 0
|
|
;;
|
|
-[acm]min|-[acm]time|-?(i)?(l)name|-inum|-?(i)path|-?(i)regex| \
|
|
-links|-perm|-size|-used|-exec|-ok|-printf)
|
|
# do nothing, just wait for a parameter to be given
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
# complete using basic options ($cur has had its dash removed here,
|
|
# as otherwise compgen will bomb out with an error, since it thinks
|
|
# the dash is an option to itself)
|
|
COMPREPLY=( $( compgen -W 'daystart depth follow help maxdepth \
|
|
mindepth mount noleaf version xdev amin anewer atime \
|
|
cmin cnewer ctime empty false fstype gid group ilname \
|
|
iname inum ipath iregex links lname mmin mtime name \
|
|
newer nouser nogroup perm regex size true type uid \
|
|
used user xtype exec fls fprint fprint0 fprintf ok \
|
|
print print0 printf prune ls' $cur ) )
|
|
|
|
# this removes any options from the list of completions that have
|
|
# already been specified somewhere on the command line.
|
|
COMPREPLY=( $( echo "${COMP_WORDS[@]}-" | \
|
|
(while read -d '-' i; do
|
|
[ "$i" == "" ] && continue
|
|
# flatten array with spaces on either side,
|
|
# otherwise we cannot grep on word boundaries of
|
|
# first and last word
|
|
COMPREPLY=" ${COMPREPLY[@]} "
|
|
# remove word from list of completions
|
|
COMPREPLY=( ${COMPREPLY/ ${i%% *} / } )
|
|
done
|
|
echo ${COMPREPLY[@]})
|
|
) )
|
|
|
|
# put dashes back
|
|
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
|
|
COMPREPLY[i]=-${COMPREPLY[i]}
|
|
done
|
|
|
|
|
|
return 0
|
|
}
|
|
complete -F _find -o dirnames find
|
|
|
|
# Linux ifconfig(8) completion
|
|
#
|
|
[ $OS = Linux ] &&
|
|
_ifconfig()
|
|
{
|
|
local cur
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
|
|
case "${COMP_WORDS[1]}" in
|
|
-|*[0-9]*)
|
|
COMPREPLY=( $( compgen -W '-a up down arp promisc allmulti \
|
|
metric mtu dstaddr netmask add del \
|
|
tunnel irq io_addr mem_start media \
|
|
broadcast pointopoint hw multicast \
|
|
address txqueuelen' $cur ))
|
|
COMPREPLY=( $( echo " ${COMP_WORDS[@]}" | \
|
|
(while read -d ' ' i; do
|
|
[ "$i" == "" ] && continue
|
|
# flatten array with spaces on either side,
|
|
# otherwise we cannot grep on word
|
|
# boundaries of first and last word
|
|
COMPREPLY=" ${COMPREPLY[@]} "
|
|
# remove word from list of completions
|
|
COMPREPLY=( ${COMPREPLY/ $i / } )
|
|
done
|
|
echo ${COMPREPLY[@]})
|
|
) )
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
COMPREPLY=( $( ifconfig -a | sed -ne 's/^\('$cur'[^ ]*\).*$/\1/p' ))
|
|
}
|
|
[ $OS = Linux ] && complete -F _ifconfig ifconfig
|
|
|
|
# RedHat Linux if{up,down} completion by Frank Sweetser <fs@wpi.edu>
|
|
#
|
|
[ $OS = Linux ] && ( have ifup || have ifdown ) &&
|
|
_ifupdown()
|
|
{
|
|
local cur
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
|
|
if [ $COMP_CWORD = 1 ] ; then
|
|
COMPREPLY=( $( \ls /etc/sysconfig/network-scripts/ifcfg-* | sed -ne 's/.*ifcfg-\('$cur'.*\)/\1/p' ) )
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
[ $OS = Linux ] && have ifup && complete -F _ifupdown ifup ifdown
|
|
|
|
# Linux ipsec(8) completion (for FreeS/WAN). Basic.
|
|
#
|
|
[ $OS = Linux ] && have ipsec &&
|
|
_ipsec()
|
|
{
|
|
local cur
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
|
|
|
|
if [ $COMP_CWORD = 1 ]; then
|
|
COMPREPLY=( $( compgen -W 'auto barf eroute klipsdebug look manual \
|
|
pluto ranbits rsasigkey setup showdefaults \
|
|
showhostkey spi spigrp tncfg whack' $cur ))
|
|
return 0
|
|
fi
|
|
|
|
case ${COMP_WORDS[1]} in
|
|
auto)
|
|
COMPREPLY=( $( compgen -W '--asynchronous --up --add --delete \
|
|
--replace --down --route --unroute \
|
|
--ready --status --rereadsecrets' $cur ) )
|
|
return 0
|
|
;;
|
|
manual)
|
|
COMPREPLY=( $( compgen -W '--up --down --route --unroute \
|
|
--union' $cur ) )
|
|
return 0
|
|
;;
|
|
ranbits)
|
|
COMPREPLY=( $( compgen -W '--quick --continuous --bytes' $cur ) )
|
|
return 0
|
|
;;
|
|
setup)
|
|
COMPREPLY=( $( compgen -W '--start --stop --restart' $cur ) )
|
|
return 0
|
|
;;
|
|
|
|
*)
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
return 0
|
|
}
|
|
[ $OS = Linux ] && [ "$have" ] && complete -F _ipsec ipsec
|
|
|
|
# cvs(1) completion
|
|
#
|
|
_cvs()
|
|
{
|
|
local cur prev
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
if [ $COMP_CWORD = 1 ] || [[ "$prev" == -* ]]; then
|
|
COMPREPLY=( $( compgen -W 'add admin checkout commit diff \
|
|
export history import log rdiff release remove rtag status \
|
|
tag update' $cur ))
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
complete -F _cvs -o default cvs
|
|
|
|
# rpm(8) completion. This is quite comprehensive now and covers rpm 4.x
|
|
#
|
|
have rpm &&
|
|
_rpm()
|
|
{
|
|
dashify()
|
|
{
|
|
local i
|
|
|
|
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
|
|
if [ ${#COMPREPLY[i]} -le 2 ]; then
|
|
COMPREPLY[i]=-${COMPREPLY[i]}
|
|
else
|
|
COMPREPLY[i]=--${COMPREPLY[i]}
|
|
fi
|
|
done
|
|
}
|
|
|
|
add_package_list()
|
|
{
|
|
if [ -f /var/log/rpmpkgs ]; then
|
|
# using RHL 7.2 - this is quicker than querying the DB
|
|
COMPREPLY=( ${COMPREPLY[@]}
|
|
$( sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9a-z.]\+.*\.rpm$/\1/p' /var/log/rpmpkgs ) )
|
|
else
|
|
COMPREPLY=( ${COMPREPLY[@]} $( rpm -qa | \
|
|
sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9a-z.]\+$/\1/p' ) )
|
|
fi
|
|
}
|
|
|
|
file_glob()
|
|
{
|
|
local suffix
|
|
|
|
# get extension of current word, if relevant
|
|
suffix=${cur##*.}
|
|
# nullify it if it's not a substring of the extension we're
|
|
# completing on
|
|
[ "$suffix" != "${1:0:${#suffix}}" ] && suffix=""
|
|
COMPREPLY=( ${COMPREPLY[@]} $( compgen -G $cur\*${1:${#suffix}} ) )
|
|
# directory completion if all else fails and current word
|
|
# contains a slash
|
|
if [ ${#COMPREPLY[@]} = 0 ] && [[ $cur == */* ]]; then
|
|
COMPREPLY=( $( compgen -d $cur ) )
|
|
fi
|
|
}
|
|
|
|
local cur cur_nodash prev
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
cur_nodash=${cur#-}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
if [ $COMP_CWORD = 1 ]; then
|
|
# first parameter on line
|
|
case "$cur" in
|
|
-b*)
|
|
COMPREPLY=( $( compgen -W 'ba bb bc bi bl bp bs' \
|
|
$cur_nodash ) )
|
|
dashify
|
|
return 0
|
|
;;
|
|
-t*)
|
|
COMPREPLY=( $( compgen -W 'ta tb tc ti tl tp ts' \
|
|
$cur_nodash ) )
|
|
dashify
|
|
return 0
|
|
;;
|
|
--*)
|
|
COMPREPLY=( $( compgen -W 'help version initdb \
|
|
checksig recompile rebuild resign addsign rebuilddb \
|
|
showrc setperms setugids tarbuild eval install \
|
|
upgrade query freshen erase verify querytags rmsource \
|
|
rmspec' ${cur_nodash#-} ) )
|
|
dashify
|
|
return 0
|
|
;;
|
|
*)
|
|
COMPREPLY=( $( compgen -W 'b e F i q t U V' \
|
|
$cur_nodash ) )
|
|
dashify
|
|
return 0
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
case "$prev" in
|
|
--@(db|exclude)path|prefix|relocate|root)
|
|
COMPREPLY=( $( compgen -d $cur ) )
|
|
return 0
|
|
;;
|
|
--eval)
|
|
# get a list of macros
|
|
COMPREPLY=( $( sed -ne 's/^\(%'${cur#\%}'[^ '$'\t'']*\).*$/\1/p' \
|
|
/usr/lib/rpm/macros ) )
|
|
return 0
|
|
;;
|
|
--pipe)
|
|
COMPREPLY=( $( compgen -c $cur ) )
|
|
return 0
|
|
;;
|
|
--rcfile)
|
|
COMPREPLY=( $( compgen -f $cur ) )
|
|
return 0
|
|
;;
|
|
--specfile)
|
|
# complete on .spec files
|
|
file_glob spec
|
|
return 0
|
|
;;
|
|
--whatprovides)
|
|
# complete on capabilities
|
|
COMPREPLY=( $( rpm -qa --queryformat '%{providename}\n' | grep ^$cur ) )
|
|
return 0
|
|
;;
|
|
--whatrequires)
|
|
# complete on capabilities
|
|
COMPREPLY=( $( rpm -qa --queryformat '%{requirename}\n' | grep ^$cur ) )
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
case "${COMP_WORDS[1]}" in
|
|
-@([iFU]*|-install|-freshen|-upgrade))
|
|
# complete on list of relevant options
|
|
COMPREPLY=( $( compgen -W 'percent force test replacepkgs \
|
|
replacefiles root excludedocs includedocs noscripts rcfile \
|
|
ignorearch dbpath prefix ignoreos nodeps allfiles ftpproxy \
|
|
ftpport justdb httpproxy httpport noorder relocate badreloc \
|
|
notriggers excludepath ignoresize oldpackage define eval \
|
|
pipe queryformat repackage' ${cur_nodash#-} ))
|
|
dashify
|
|
# return if $cur is an option
|
|
[[ "$cur" == -* ]] && return 0
|
|
# add a list of RPMS to possible completions
|
|
file_glob rpm
|
|
return 0
|
|
;;
|
|
-q*p*)
|
|
# complete on list of relevant options
|
|
COMPREPLY=( $( compgen -W 'scripts root rcfile whatprovides \
|
|
whatrequires requires triggeredby ftpport ftpproxy httpproxy \
|
|
httpport provides triggers dump changelog dbpath filesbypkg \
|
|
define eval pipe showrc info list state docfiles \
|
|
configfiles queryformat conflicts obsoletes' ${cur_nodash#-} ) )
|
|
dashify
|
|
# return if $cur is an option
|
|
[[ "$cur" == -* ]] && return 0
|
|
# add a list of RPMS to possible completions
|
|
file_glob rpm
|
|
return 0
|
|
;;
|
|
-*f)
|
|
# standard filename completion
|
|
COMPREPLY=( $( compgen -f $cur ) )
|
|
return 0
|
|
;;
|
|
-@(e|-erase))
|
|
# complete on list of relevant options
|
|
COMPREPLY=( $( compgen -W 'allmatches noscripts notriggers \
|
|
nodeps test repackage' ${cur_nodash#-} ) )
|
|
dashify
|
|
# return if $cur is an option
|
|
[[ "$cur" == -* ]] && return 0
|
|
add_package_list
|
|
return 0
|
|
;;
|
|
-q*)
|
|
# complete on list of relevant options
|
|
COMPREPLY=( $( compgen -W 'scripts root rcfile whatprovides \
|
|
whatrequires requires triggeredby ftpport ftpproxy httpproxy \
|
|
httpport provides triggers dump changelog dbpath specfile \
|
|
querybynumber last filesbypkg define eval pipe showrc info \
|
|
list state docfiles configfiles queryformat conflicts \
|
|
obsoletes' ${cur_nodash#-} ) )
|
|
dashify
|
|
# return if $cur is an option
|
|
[[ "$cur" == -* ]] && return 0
|
|
# don't complete on packages if we are querying all packages
|
|
[[ ${COMP_WORDS[1]} == -qa* ]] && return 0
|
|
add_package_list
|
|
return 0
|
|
;;
|
|
-@(K|-checksig))
|
|
# complete on list of relevant options
|
|
COMPREPLY=( $( compgen -W 'nopgp nogpg nomd5' \
|
|
${cur_nodash#-} ) )
|
|
dashify
|
|
# return if $cur is an option
|
|
[[ "$cur" == -* ]] && return 0
|
|
# add a list of RPMS to possible completions
|
|
file_glob rpm
|
|
return 0
|
|
;;
|
|
-@([Vy]*|-verify))
|
|
# complete on list of relevant options
|
|
COMPREPLY=( $( compgen -W 'root rcfile dbpath nodeps nofiles \
|
|
noscripts nomd5' ${cur_nodash#-} ) )
|
|
dashify
|
|
# return if $cur is an option
|
|
[[ "$cur" == -* ]] && return 0
|
|
add_package_list
|
|
return 0
|
|
;;
|
|
-[bt]*)
|
|
# complete on list of relevant options
|
|
COMPREPLY=( $( compgen -W 'short-circuit timecheck clean \
|
|
rmsource rmspec test sign buildroot target buildarch buildos \
|
|
nobuild' ${cur_nodash#-} ) )
|
|
dashify
|
|
# return if $cur is an option
|
|
[[ "$cur" == -* ]] && return 0
|
|
if [[ ${COMP_WORDS[1]} == -b* ]]; then
|
|
# complete on .spec files
|
|
file_glob spec
|
|
else
|
|
# complete on .tar files
|
|
COMPREPLY=( $( compgen -G $cur\*.+(tgz|tar.+(gz|bz2)) ) )
|
|
fi
|
|
return 0
|
|
;;
|
|
--re@(build|compile))
|
|
# complete on source RPMs
|
|
COMPREPLY=( $( compgen -G $cur\*.src.rpm ) )
|
|
return 0
|
|
;;
|
|
--tarbuild)
|
|
# complete on tarred sources
|
|
COMPREPLY=( $( compgen -G $cur\*.+(tgz|tar.+(gz|bz2)) ) )
|
|
return 0
|
|
;;
|
|
--@(re|add)sign)
|
|
# complete on RPMs
|
|
file_glob rpm
|
|
return 0
|
|
;;
|
|
--set@(perms|gids))
|
|
add_package_list
|
|
return 0
|
|
;;
|
|
--rms@(ource|pec))
|
|
file_glob spec
|
|
return 0
|
|
;;
|
|
-*g)
|
|
# package group completion
|
|
local IFS=$'\t'
|
|
# remove trailing backslash, or grep will complain
|
|
cur=${cur%'\'}
|
|
COMPREPLY=( $( rpm -qa --queryformat '%{group}\n' | \
|
|
grep ^$cur ) )
|
|
# backslash escape spaces and translate newlines to tabs
|
|
COMPREPLY=( $( echo ${COMPREPLY[@]} | sed 's/ /\\ /g' | \
|
|
tr '\n' '\t' ) )
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
return 0
|
|
}
|
|
[ "$have" ] && complete -F _rpm -o filenames rpm
|
|
|
|
# Debian Linux apt-get(8) completion.
|
|
#
|
|
have apt-get &&
|
|
_apt-get()
|
|
{
|
|
local cur prev special i
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
for (( i=0; i < ${#COMP_WORDS}-1; i++ )); do
|
|
if [[ ${COMP_WORDS[i]} == @(install|remove|source) ]]; then
|
|
special=${COMP_WORDS[i]}
|
|
fi
|
|
done
|
|
if [ -n "$special" ]; then
|
|
case $special in
|
|
@(install|remove|source))
|
|
COMPREPLY=( $( apt-cache pkgnames $cur ) )
|
|
return 0
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
if [[ "$prev" == -*c ]] || [ "$prev" = --config-file ]; then
|
|
COMPREPLY=( $( compgen -f $cur ) )
|
|
else
|
|
COMPREPLY=( $( compgen -W 'update upgrade dselect-upgrade \
|
|
dist-upgrade install remove source check \
|
|
clean autoclean -d -f -h -v -m -q -s -y -u \
|
|
-b -c -o --download-only --fix-broken --help \
|
|
--version --ignore-missing --fix-missing \
|
|
--no-download --quiet --simulate \
|
|
--just-print --dry-run --recon --no-act \
|
|
--yes --assume-yes --show-upgraded \
|
|
--compile --build --ignore-hold \
|
|
--no-upgrade --force-yes --print-uris \
|
|
--purge --reinstall --list-cleanup \
|
|
--trivial-only --no-remove --diff-only \
|
|
--tar-only --config-file --option ' | \
|
|
grep ^$cur ) )
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
[ "$have" ] && complete -F _apt-get -o filenames apt-get
|
|
|
|
# Debian Linux apt-cache(8) completion.
|
|
#
|
|
have apt-cache &&
|
|
_apt-cache()
|
|
{
|
|
local cur prev special i
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
|
|
for (( i=0; i < ${#COMP_WORDS}-1; i++ )); do
|
|
if [[ ${COMP_WORDS[i]} == @(add|showpkg) ]]; then
|
|
special=${COMP_WORDS[i]}
|
|
fi
|
|
done
|
|
if [ -n "$special" ]; then
|
|
case $special in
|
|
add)
|
|
COMPREPLY=( $( compgen -f $cur ) )
|
|
return 0
|
|
;;
|
|
showpkg)
|
|
COMPREPLY=( $( apt-cache pkgnames $cur ) )
|
|
return 0
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
|
|
if [[ "$prev" == -*c ]] || [ "$prev" = --config-file ]; then
|
|
COMPREPLY=( $( compgen -f $cur ) )
|
|
else
|
|
COMPREPLY=( $( compgen -W 'add gencaches showpkg stats dump \
|
|
dumpavail unmet check search show showpkg \
|
|
depends pkgnames -h -v -p -s -q -i -f -a -g -c \
|
|
-o --help --version --pkg-cache --src-cache \
|
|
--quiet --important --full --all-versions \
|
|
--no-generate --names-only --all-names \
|
|
--config-file --option' | grep ^$cur ) )
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
[ "$have" ] && complete -F _apt-cache -o filenames apt-cache
|
|
|
|
# chsh(1) completion
|
|
#
|
|
_chsh()
|
|
{
|
|
local cur prev
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
if [ "$prev" = "-s" ]; then
|
|
COMPREPLY=( $( chsh -l | grep ^$cur ) )
|
|
else
|
|
COMPREPLY=( $( compgen -u $cur ) )
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
complete -F _chsh chsh
|
|
|
|
# chkconfig(8) completion
|
|
#
|
|
have chkconfig &&
|
|
_chkconfig()
|
|
{
|
|
local cur prev i
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
cur_nodash=${cur#--}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
if [ $COMP_CWORD = 1 ]; then
|
|
COMPREPLY=( $( compgen -W 'list add del level' $cur_nodash ) )
|
|
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
|
|
COMPREPLY[i]=--${COMPREPLY[i]}
|
|
done
|
|
return 0
|
|
fi
|
|
|
|
if [ $COMP_CWORD -eq 4 ]; then
|
|
COMPREPLY=( $( compgen -W 'on off reset' $cur ) )
|
|
return 0
|
|
fi
|
|
|
|
case "$prev" in
|
|
@([1-6]|--@(list|add|del)))
|
|
COMPREPLY=( $( compgen -W "`(cd /etc/rc.d/init.d; echo *)`" \
|
|
$cur) )
|
|
return 0
|
|
;;
|
|
--level)
|
|
COMPREPLY=( $( compgen -W '1 2 3 4 5 6' $cur ) )
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
return 0
|
|
}
|
|
[ "$have" ] && complete -F _chkconfig chkconfig
|
|
|
|
# This function performs host completion based on ssh's known_hosts files,
|
|
# defaulting to standard host completion if they don't exist.
|
|
#
|
|
_known_hosts()
|
|
{
|
|
local cur kh user
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
[[ $cur == *@* ]] && user=${cur%@*}@ && cur=${cur#*@}
|
|
kh=()
|
|
|
|
[ -r /etc/known_hosts ] && kh[0]=/etc/known_hosts
|
|
[ -r /etc/known_hosts2 ] && kh[1]=/etc/known_hosts2
|
|
[ -r ~/.ssh/known_hosts ] && kh[2]=~/.ssh/known_hosts
|
|
[ -r ~/.ssh/known_hosts2 ] && kh[3]=~/.ssh/known_hosts2
|
|
|
|
# If we have known_hosts files to use
|
|
if [ ${#kh[@]} -gt 0 ]; then
|
|
# Escape slashes and dots in paths for awk
|
|
cur=${cur//\//\\\/}
|
|
cur=${cur//\./\\\.}
|
|
if [[ "$cur" == [0-9]*.* ]]; then
|
|
# Digits followed by a dot - just search for that
|
|
cur="^$cur.*"
|
|
elif [[ "$cur" == [0-9]* ]]; then
|
|
# Digits followed by no dot - search for digits followed
|
|
# by a dot
|
|
cur="^$cur.*\."
|
|
elif [ -z "$cur" ]; then
|
|
# A blank - search for a dot or an alpha character
|
|
cur="[a-z.]"
|
|
else
|
|
cur="^$cur"
|
|
fi
|
|
# FS needs to look for a comma separated list
|
|
COMPREPLY=( $( awk 'BEGIN {FS=","}
|
|
{for (i=1; i<=2; ++i) { \
|
|
gsub(" .*$", "", $i); \
|
|
if ($i ~ /'$cur'/) {print $i} \
|
|
}}' ${kh[@]} ) )
|
|
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
|
|
COMPREPLY[i]=$user${COMPREPLY[i]}
|
|
done
|
|
else
|
|
# Just do normal hostname completion
|
|
COMPREPLY=( $( compgen -A hostname $cur ) )
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
complete -F _known_hosts traceroute ping fping telnet host nslookup
|
|
|
|
# ssh(1) completion. Should be able to improve this with user@host notation,
|
|
# but the '@' seems to trigger some kind of bug in bash's completion.
|
|
#
|
|
have ssh &&
|
|
_ssh()
|
|
{
|
|
local cur prev
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
case "$prev" in
|
|
-*c)
|
|
COMPREPLY=( $( compgen -W 'blowfish 3des 3des-cbc blowfish-cbc \
|
|
arcfour cast128-cbc' $cur ) )
|
|
;;
|
|
-*l)
|
|
COMPREPLY=( $( compgen -u $cur ) )
|
|
;;
|
|
*)
|
|
_known_hosts
|
|
[ $COMP_CWORD = 1 ] || \
|
|
COMPREPLY=( ${COMPREPLY[@]} $( compgen -c $cur ) )
|
|
esac
|
|
|
|
return 0
|
|
}
|
|
[ "$have" ] && shopt -u hostcomplete && complete -F _ssh ssh slogin sftp
|
|
|
|
have scp &&
|
|
_scp()
|
|
{
|
|
local cur
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
|
|
_known_hosts
|
|
COMPREPLY=( ${COMPREPLY[@]} $( compgen -f $cur ) )
|
|
|
|
return 0
|
|
}
|
|
[ "$have" ] && complete -o filenames -F _scp scp
|
|
|
|
|
|
# Linux route(8) completion. This could be improved by adding address family
|
|
# completion for -A, etc.
|
|
#
|
|
_route()
|
|
{
|
|
local cur prev
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
if [ "$prev" = dev ]; then
|
|
COMPREPLY=( $( ifconfig -a | sed -ne 's/^\('$cur'[^ ]*\).*$/\1/p' ))
|
|
return 0
|
|
fi
|
|
|
|
# Must use grep here, otherwise $cur will cause compgen to barf, if
|
|
# it begins with a hyphen
|
|
COMPREPLY=( $( compgen -W 'add del -host -net netmask metric mss \
|
|
window irtt reject mod dyn reinstate dev' | \
|
|
grep ^$cur ) )
|
|
|
|
COMPREPLY=( $( echo " ${COMP_WORDS[@]}" | \
|
|
(while read -d ' ' i; do
|
|
[ "$i" == "" ] && continue
|
|
# flatten array with spaces on either side,
|
|
# otherwise we cannot grep on word
|
|
# boundaries of first and last word
|
|
COMPREPLY=" ${COMPREPLY[@]} "
|
|
# remove word from list of completions
|
|
COMPREPLY=( ${COMPREPLY/ $i / } )
|
|
done
|
|
echo ${COMPREPLY[@]})
|
|
) )
|
|
return 0
|
|
}
|
|
complete -F _route route
|
|
|
|
# GNU make(1) completion (adapted from the example supplied with the bash 2.04
|
|
# source code)
|
|
#
|
|
_make()
|
|
{
|
|
local mdef makef gcmd cur prev i
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
# if prev argument is -f, return possible filename completions.
|
|
# we could be a little smarter here and return matches against
|
|
# `makefile Makefile *.mk', whatever exists
|
|
if [[ "$prev" == -*f ]]; then
|
|
COMPREPLY=( $( compgen -f $cur ) )
|
|
return 0
|
|
fi
|
|
|
|
# if we want an option, return the possible posix options
|
|
if [[ "$cur" == - ]]; then
|
|
COMPREPLY=( $( compgen -W '-e -f -i -k -n -p -q -r -S -s -t' | grep ^$cur ) )
|
|
return 0
|
|
fi
|
|
|
|
# make reads `makefile' before `Makefile'
|
|
if [ -f makefile ]; then
|
|
mdef=makefile
|
|
elif [ -f Makefile ]; then
|
|
mdef=Makefile
|
|
else
|
|
mdef=*.mk # local convention
|
|
fi
|
|
|
|
# before we scan for targets, see if a makefile name was specified
|
|
# with -f
|
|
for (( i=0; i < ${#COMP_WORDS[@]}; i++ )); do
|
|
if [[ ${COMP_WORDS[i]} == -*f ]]; then
|
|
eval makef=${COMP_WORDS[i+1]} # eval for tilde expansion
|
|
break
|
|
fi
|
|
done
|
|
|
|
[ -z "$makef" ] && makef=$mdef
|
|
|
|
# if we have a partial word to complete, restrict completions to
|
|
# matches of that word
|
|
[ -n "$2" ] && gcmd='grep "^$2"' || gcmd=cat
|
|
|
|
# if we don't want to use *.mk, we can take out the cat and use
|
|
# test -f $makef and input redirection
|
|
COMPREPLY=( $( cat $makef 2>/dev/null | \
|
|
awk 'BEGIN {FS=":"} /^[^.# ][^=]*:/ {print $1}' | \
|
|
eval $gcmd ) )
|
|
|
|
# default to filename completion if all else failed
|
|
if [ ${#COMPREPLY[@]} = 0 ]; then
|
|
COMPREPLY=( $( compgen -f $cur ) )
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
complete -F _make -X '+($*|*.[cho])' -o filenames make gmake pmake
|
|
|
|
# Red Hat Linux service completion. This completes on a list of all available
|
|
# service scripts in the SysV init.d directory, followed by that script's
|
|
# available commands
|
|
#
|
|
have service &&
|
|
_service()
|
|
{
|
|
local cur sysvdir
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
|
|
[ -d /etc/rc.d/init.d ] && sysvdir=/etc/rc.d/init.d \
|
|
|| sysvdir=/etc/init.d
|
|
|
|
#[[ "$cur" == -* ]] && return 0
|
|
if [ $COMP_CWORD = 1 ]; then
|
|
COMPREPLY=( $( compgen -W '`echo $sysvdir/!(*.rpmsave|*.rpmorig)`' ) )
|
|
COMPREPLY=( $( compgen -W '${COMPREPLY[@]#$sysvdir/}' $cur ) )
|
|
else
|
|
COMPREPLY=( $( compgen -W '`sed -ne "y/|/ /; \
|
|
s/^.*Usage.*{\(.*\)}.*$/\1/p" \
|
|
$sysvdir/${COMP_WORDS[1]}`' $cur ) )
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
[ "$have" ] && complete -F _service service
|
|
|
|
# The beginnings of a completion function for GNU tar(1)
|
|
#
|
|
_tar()
|
|
{
|
|
local cur
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
|
|
if [[ ${COMP_WORDS[1]} == c*f ]]; then
|
|
COMPREPLY=( $( compgen -f $cur ) )
|
|
elif [[ ${COMP_WORDS[1]} == +([^zj])f ]]; then
|
|
COMPREPLY=( $( compgen -G $cur\*.tar ) )
|
|
elif [[ ${COMP_WORDS[1]} == *z*f ]]; then
|
|
COMPREPLY=( $( compgen -G $cur\*.t?(ar.)gz ) )
|
|
elif [[ ${COMP_WORDS[1]} == *j*f ]]; then
|
|
COMPREPLY=( $( compgen -G $cur\*.tar.bz2 ) )
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
complete -F _tar -o default tar
|
|
|
|
# Linux iptables(8) completion
|
|
#
|
|
have iptables &&
|
|
_iptables()
|
|
{
|
|
local cur prev table chain
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
chain='s/^Chain \([^ ]\+\).*$/\1/p'
|
|
|
|
if [[ $COMP_LINE == *-t\ *filter* ]]; then
|
|
table="-t filter"
|
|
elif [[ $COMP_LINE == *-t\ *nat* ]]; then
|
|
table="-t nat"
|
|
elif [[ $COMP_LINE == *-t\ *mangle* ]]; then
|
|
table="-t mangle"
|
|
fi
|
|
|
|
case "$prev" in
|
|
-*[AIDPFXL])
|
|
COMPREPLY=( $( compgen -W '`iptables $table -nL | sed -ne "s/^Chain \([^ ]\+\).*$/\1/p"`' $cur ) )
|
|
;;
|
|
-*t)
|
|
COMPREPLY=( $( compgen -W 'nat filter mangle' $cur ) )
|
|
;;
|
|
-j)
|
|
if [ "$table" = "-t filter" -o "$table" = "" ]; then
|
|
COMPREPLY=( $( compgen -W 'ACCEPT DROP LOG ULOG REJECT \
|
|
`iptables $table -nL | sed -ne "$chain" \
|
|
-e "s/INPUT|OUTPUT|FORWARD|PREROUTING|POSTROUTING//"`' \
|
|
$cur ) )
|
|
elif [ "$table" = "-t nat" ]; then
|
|
COMPREPLY=( $( compgen -W 'ACCEPT DROP LOG ULOG REJECT \
|
|
MIRROR SNAT DNAT MASQUERADE `iptables $table -nL | \
|
|
sed -ne "$chain" -e "s/OUTPUT|PREROUTING|POSTROUTING//"`' \
|
|
$cur ) )
|
|
elif [ "$table" = "-t mangle" ]; then
|
|
COMPREPLY=( $( compgen -W 'ACCEPT DROP LOG ULOG REJECT \
|
|
MARK TOS `iptables $table -nL | sed -ne "$chain" \
|
|
-e "s/INPUT|OUTPUT|FORWARD|PREROUTING|POSTROUTING//"`' \
|
|
$cur ) )
|
|
fi
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
|
|
}
|
|
[ "$have" ] && complete -F _iptables iptables
|
|
|
|
# tcpdump(8) completion
|
|
#
|
|
have tcpdump &&
|
|
_tcpdump()
|
|
{
|
|
local cur
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
|
|
COMPREPLY=( $( compgen -W 'host net port src dst ether gateway
|
|
less greater' $cur ) )
|
|
|
|
}
|
|
[ "$have" ] && complete -F _tcpdump tcpdump
|
|
|
|
# This meta-cd function observes the CDPATH variable, so that cd additionally
|
|
# completes on directories under those specified in CDPATH.
|
|
#
|
|
_cd()
|
|
{
|
|
local IFS=$'\t\n' cur=${COMP_WORDS[COMP_CWORD]} dirs=() i
|
|
|
|
_expand || return 0
|
|
|
|
# standard dir completion if parameter starts with /, ./ or ../
|
|
if [[ "$cur" == ?(.)?(.)/* ]]; then
|
|
COMPREPLY=( $( compgen -d $cur ) )
|
|
return 0
|
|
fi
|
|
if [ -n "$CDPATH" ]; then
|
|
# we have a CDPATH, so loop on its contents
|
|
for i in ${CDPATH//:/ }; do
|
|
# create an array of matched subdirs
|
|
dirs=( $( compgen -d $i/$cur ) )
|
|
# add subdirs to list of completions as necessary
|
|
[ ${#dirs[@]} ] && COMPREPLY=( ${COMPREPLY[@]} ${dirs[@]#$i/})
|
|
done
|
|
fi
|
|
COMPREPLY=( ${COMPREPLY[@]} $( compgen -d $cur ) )
|
|
|
|
return 0
|
|
}
|
|
complete -F _cd -o filenames cd
|
|
|
|
# A meta-command completion function for commands like sudo(8), which need to
|
|
# first complete on a command, then complete according to that command's own
|
|
# completion definition - currently not quite foolproof (e.g. mount and umount
|
|
# don't work properly), but still quite useful
|
|
#
|
|
_command()
|
|
{
|
|
local cur func cline cspec
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
|
|
if [ $COMP_CWORD = 1 ]; then
|
|
COMPREPLY=( $( compgen -c $cur ) )
|
|
elif complete -p ${COMP_WORDS[1]} &>/dev/null; then
|
|
cspec=$( complete -p ${COMP_WORDS[1]} )
|
|
if [ "${cspec#*-F }" != "$cspec" ]; then
|
|
# complete -F <function>
|
|
#
|
|
# COMP_CWORD and COMP_WORDS() are not read-only,
|
|
# so we can set them before handing off to regular
|
|
# completion routine
|
|
|
|
# set current token number to 1 less than now
|
|
COMP_CWORD=$(( $COMP_CWORD - 1 ))
|
|
# get function name
|
|
func=${cspec#*-F }
|
|
func=${func%% *}
|
|
# get current command line minus initial command
|
|
cline="${COMP_LINE#$1 }"
|
|
# split current command line tokens into array
|
|
COMP_WORDS=( $cline )
|
|
$func $cline
|
|
elif [ "${cspec#*-[abcdefgjkvu]}" != "$cspec" ]; then
|
|
# complete -[abcdefgjkvu]
|
|
func=$( echo $cspec | \
|
|
sed -e 's/^.*\(-[abcdefgjkvu]\).*$/\1/' )
|
|
COMPREPLY=( $( compgen $func $cur ) )
|
|
elif [ "${cspec#*-A}" != "$cspec" ]; then
|
|
# complete -A <type>
|
|
func=${cspec#*-A }
|
|
func=${func%% *}
|
|
COMPREPLY=( $( compgen -A $func $cur ) )
|
|
fi
|
|
else
|
|
COMPREPLY=( $( compgen -f $cur ) )
|
|
fi
|
|
}
|
|
complete -F _command -o filenames type nohup exec nice eval strace sudo gdb
|
|
|
|
# Basic Perforce completion by Frank Cusack (frank@google.com)
|
|
#
|
|
have p4 &&
|
|
_p4()
|
|
{
|
|
local cur prev prev2 p4commands p4filetypes
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
# rename isn't really a command
|
|
p4commands="add admin branch branches change changes client \
|
|
clients counter counters delete depot depots describe \
|
|
diff diff2 dirs edit filelog files fix fixes flush \
|
|
fstat group groups have help info integrate integrated \
|
|
job jobs jobspec label labels labelsync lock obliterate \
|
|
opened passwd print protect rename reopen resolve \
|
|
resolved revert review reviews set submit sync triggers \
|
|
typemap unlock user users verify where"
|
|
p4filetypes="ctext cxtext ktext kxtext ltext tempobj ubinary \
|
|
uresource uxbinary xbinary xltext xtempobj xtext \
|
|
text binary resource"
|
|
|
|
if [ $COMP_CWORD = 1 ]; then
|
|
COMPREPLY=( $( compgen -W "$p4commands" $cur ) )
|
|
elif [ $COMP_CWORD -eq 2 ]; then
|
|
case "$prev" in
|
|
help)
|
|
COMPREPLY=( $( compgen -W "simple commands \
|
|
environment filetypes jobview revisions \
|
|
usage views $p4commands" $cur ) )
|
|
;;
|
|
admin)
|
|
COMPREPLY=( $( compgen -W "checkpoint stop" $cur ) )
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
elif [ $COMP_CWORD -gt 2 ]; then
|
|
prev2=${COMP_WORDS[COMP_CWORD-2]}
|
|
case "$prev" in
|
|
-t)
|
|
case "$prev2" in
|
|
add|edit|reopen)
|
|
COMPREPLY=( $(compgen -W "$p4filetypes" $cur) )
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
[ "$have" ] && complete -F _p4 -o default p4 g4
|
|
|
|
# ant completion is modified from the original submitted by
|
|
# Claus-Peter Klas <peter.klas@uni-dortmund.de>
|
|
#
|
|
have ant &&
|
|
_ant_targets()
|
|
{
|
|
COMPREPLY=()
|
|
local gcmd
|
|
|
|
# if we have a partial word to complete, restrict completions to
|
|
# matches of that word
|
|
[ ! -f build.xml ] && return 0
|
|
|
|
[ -n "$2" ] && gcmd='grep "^$2"' || gcmd=cat
|
|
|
|
COMPREPLY=( $( awk 'BEGIN {FS="\""} /\<target/ {print $2}' < build.xml \
|
|
| tr -s ' ' '\012' | sort -u | eval $gcmd ) )
|
|
}
|
|
[ "$have" ] && complete -F _ant_targets ant
|
|
|
|
have nslookup &&
|
|
_nslookup()
|
|
{
|
|
local cur
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]#-}
|
|
|
|
COMPREPLY=( $( compgen -P '-' -W 'all class= debug d2 domain= \
|
|
srchlist= defname search port= querytype= \
|
|
type= recurse retry root timeout vc \
|
|
ignoretc' $cur ) )
|
|
}
|
|
[ "$have" ] && complete -F _nslookup nslookup
|
|
|
|
# mysqladmin(1) completion
|
|
#
|
|
have mysqladmin &&
|
|
_mysqladmin()
|
|
{
|
|
local cur prev
|
|
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
case "$prev" in
|
|
-u)
|
|
COMPREPLY=( $( compgen -u $cur ) )
|
|
return 0
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
|
|
COMPREPLY=( $( compgen -P '-' -W '# f ? C h p P i r E s S t u \
|
|
v V w' ${cur#-} ) )
|
|
|
|
COMPREPLY=( ${COMPREPLY[@]} \
|
|
$( compgen -W 'create drop extended-status flush-hosts \
|
|
flush-logs flush-status flush-tables \
|
|
flush-threads flush-privileges kill \
|
|
password ping processlist reload refresh \
|
|
shutdown status variables version' $cur ) )
|
|
}
|
|
[ "$have" ] && complete -F _mysqladmin mysqladmin
|
|
|
|
# gzip(1) and bzip2(1) completion
|
|
#
|
|
have gzip &&
|
|
_zip()
|
|
{
|
|
local IFS cur prev xspec
|
|
|
|
IFS=$'\t\n'
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
|
|
[ ${COMP_WORDS[0]} = "gzip" ] && xspec="*.gz"
|
|
[ ${COMP_WORDS[0]} = "bzip2" ] && xspec="*.bz2"
|
|
[[ "$prev" == -*d* ]] && xspec="!"$xspec
|
|
|
|
_expand || return 0
|
|
|
|
COMPREPLY=( $( compgen -f -X $xspec $cur ) $( compgen -d $cur ) )
|
|
}
|
|
[ "$have" ] && complete -F _zip -o filenames gzip bzip2
|
|
|
|
_expand()
|
|
{
|
|
# expand ~username type directory specifications
|
|
if [[ "$cur" == \~*/* ]]; then
|
|
eval cur=$cur
|
|
elif [[ "$cur" == \~* ]]; then
|
|
cur=${cur#\~}
|
|
COMPREPLY=( $( compgen -P '~' -u $cur ) )
|
|
return ${#COMPREPLY[@]}
|
|
fi
|
|
}
|
|
|
|
# Return 1 if $1 appears to contain a redirection operator. Handles backslash
|
|
# quoting (barely).
|
|
#
|
|
_redir_op()
|
|
{
|
|
case "$1" in
|
|
*\\'[\<\>]'*) return 1;;
|
|
*[\<\>]*) return 0;;
|
|
*) return 1;;
|
|
esac
|
|
}
|
|
|
|
|
|
# _redir_test tests the current word ($1) and the previous word ($2) for
|
|
# redirection operators and does filename completion on the current word
|
|
# if either one contains a redirection operator
|
|
_redir_test()
|
|
{
|
|
if _redir_op "$1" ; then
|
|
COMPREPLY=( $( compgen -f "$1" ) )
|
|
return 0
|
|
elif _redir_op "$2" ; then
|
|
COMPREPLY=( $( compgen -f "$1" ) )
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
_configure_func ()
|
|
{
|
|
case "$2" in
|
|
-*) ;;
|
|
*) return ;;
|
|
esac
|
|
|
|
case "$1" in
|
|
\~*) eval cmd=$1 ;;
|
|
*) cmd="$1" ;;
|
|
esac
|
|
|
|
COMPREPLY=( $( "$cmd" --help | sed -ne 's/^ *\('$2'[^ '$'\t'',[]\+\).*$/\1/p' ) )
|
|
}
|
|
complete -F _configure_func configure
|
|
|
|
_filedir()
|
|
{
|
|
local IFS cur
|
|
|
|
IFS=$'\t\n'
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
|
|
_expand || return 0
|
|
|
|
COMPREPLY=( $( eval compgen -f $cur ) $( compgen -d $cur ) )
|
|
}
|
|
complete -F _filedir -o filenames cat less more ln strip
|
|
|
|
_filedir_xspec()
|
|
{
|
|
local IFS cur xspec
|
|
|
|
IFS=$'\t\n'
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
|
|
_expand || return 0
|
|
|
|
# get first exclusion compspec that matches this command
|
|
xspec=$( sed -ne '/ '$1'/{p;q;}' /etc/bash_completion )
|
|
# prune to leave nothing but the -X spec
|
|
xspec=${xspec#*-X }
|
|
xspec=${xspec%% *}
|
|
|
|
COMPREPLY=( $( eval compgen -f -X "$xspec" $cur ) $( compgen -d $cur ) )
|
|
}
|
|
list=( $( sed -ne '/^# START exclude/,/^# FINISH exclude/p' \
|
|
/etc/bash_completion | \
|
|
# read exclusion compspecs
|
|
(
|
|
while read line
|
|
do
|
|
# ignore compspecs that are commented out
|
|
if [ "${line#\#}" != "$line" ]; then continue; fi
|
|
line=${line%# START exclude*}
|
|
line=${line%# FINISH exclude*}
|
|
line=${line##*\'}
|
|
list=( ${list[@]} $line )
|
|
done
|
|
echo ${list[@]}
|
|
)
|
|
) )
|
|
# remove previous compspecs
|
|
if [ ${#list[@]} -gt 0 ]; then
|
|
eval complete -r ${list[@]}
|
|
# install new compspecs
|
|
eval complete -F _filedir_xspec -o filenames ${list[@]}
|
|
fi
|
|
unset list[@]
|
|
|
|
# source user completion file
|
|
[ -f ~/.bash_completion ] && . ~/.bash_completion
|
|
unset -f have
|
|
unset OS RELEASE have
|