bash-completion/bash_completion

1227 lines
32 KiB
Bash
Raw Normal View History

# bash_completion - some programmable completion functions for bash 2.04
#
# <![CDATA[
#
# $Id: bash_completion,v 1.18 2001/05/21 22:10:29 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.
# 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 cd mkdir rmdir pushd
# Make file commands see only files
complete -f cat less more ln strip
complete -f -X '*.bz2' bzip2
complete -f -X '!*.bz2' bunzip2
complete -f -X '!*.zip' 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 zmore zcat
complete -f -X '!*.+(gif|jpg|jpeg|GIF|JPG|bmp)' ee xv
complete -f -X '!*.+(ps|PS|ps.gz)' gv
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
# kill sees only signals
complete -A signal kill -P '%'
# user commands see only users
complete -u finger su usermod userdel 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
# various commands complete with commands
complete -c command type nohup exec nice eval strace gdb sudo
# 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
# 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
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 -eq 1 ] || [[ "$prev" == -* ]]; then
if [[ "$cur" == [a-zA-Z]*.* ]]; then
user=${cur%.*}
group=${cur#*.}
COMPREPLY=( $( awk 'BEGIN {FS=":"} \
{if ($1 ~ /^'$group'/) print $1}' \
/etc/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
# 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 umount
# GID completion. This will get a list of all valid group names from
# /etc/group and should work anywhere.
#
_gid_func()
{
local cur
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $( awk 'BEGIN {FS=":"} {if ($1 ~ /^'$cur'/) print $1}' \
/etc/group ) )
return 0
}
complete -F _gid_func groupdel groupmod
# 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
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
if [ -x /usr/sbin/showmount ] && [[ "$cur" == *:* ]]; then
COMPREPLY=( $( /usr/sbin/showmount -e --no-headers ${cur%%:*} |\
grep ^${cur#*:} | awk '{print $1}' ) )
else
COMPREPLY=( $( awk '{if ($2 ~ /\//) print $2}' /etc/fstab | \
grep ^$cur ) )
# default to filename completion if all else failed
if [ ${#COMPREPLY[@]} = 0 ]; then
COMPREPLY=( $( compgen -f $cur ) )
fi
fi
return 0
}
complete -F _mount mount
# Linux rmmod(1) completion. This completes on a list of all currently
# installed kernel modules.
#
_rmmod()
{
local cur
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $( /sbin/lsmod | \
awk '{if (NR != 1 && $1 ~ /^'$cur'/) print $1}' ) )
return 0
}
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.
#
_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
}
complete -F _insmod insmod modprobe
# man(1) completion. This relies on the security enhanced version of
# GNU locate(1). UNIX variants having non-numeric man page sections
# other than l, m and n should add the appropriate sections to the
# first clause of the case statement.
#
# 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.
#
_man()
{
local cur prev cmd
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
prev=${COMP_WORDS[COMP_CWORD-1]}
# default completion if parameter contains / or we have no man.config
if [[ "$cur" == /* ]] || [ ! -f /etc/man.config ]; then return 0; fi
if [[ "$prev" == [0-9n] ]]; 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-9n] ) )
fi
return 0
}
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
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 -eq 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
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 (the option to -d is a tab)
COMPREPLY=( $( cut -d' ' -f 2 /proc/filesystems | grep ^$cur ) )
return 0
;;
-gid)
COMPREPLY=( $( awk 'BEGIN {FS=":"} \
{if ($3 ~ /^'$cur'/) print $3}' /etc/group ) )
return 0
;;
-group)
COMPREPLY=( $( awk 'BEGIN {FS=":"} \
{if ($1 ~ /^'$cur'/) print $1}' /etc/group ) )
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 default find
# Linux ifconfig(8) completion
#
_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' ))
}
complete -F _ifconfig ifconfig
# Linux ipsec(8) completion (for FreeS/WAN). Basic.
#
_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
}
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 -eq 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
#
_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()
{
COMPREPLY=( ${COMPREPLY[@]} $( rpm -qa | \
sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9a-z.]\+$/\1/p' ) )
}
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 \
2001-03-21 15:33:02 -08:00
showrc setperms setugids tarbuild eval install \
upgrade query freshen erase verify querytags rmsource' \
${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 (char class contains a space and tab)
COMPREPLY=( $( sed -ne 's/^\(%'${cur#\%}'[^ ]*\).*$/\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' ${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
;;
-qp*)
# 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' ${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' ${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' \
${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 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
;;
--rmsource)
file_glob spec
return 0
;;
-*g)
# package group completion
local IFS=$(echo -e "\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
}
complete -F _rpm rpm
# Debian Linux apt-get(8) completion.
#
_apt-get()
{
local cur prev special
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
}
complete -F _apt-get apt-get
# Debian Linux apt-cache(8) completion.
#
_apt-cache()
{
local cur prev special
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
}
complete -F _apt-cache 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
#
_chkconfig()
{
local cur prev
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
cur_nodash=${cur#--}
prev=${COMP_WORDS[COMP_CWORD-1]}
if [ $COMP_CWORD -eq 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
}
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
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
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
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<=NR; ++i) { \
if ($i ~ /'$cur'/) {print $i} \
}}' ${kh[@]} ) )
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.
#
_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 ) )
return 0
;;
-*l)
COMPREPLY=( $( compgen -u $cur ) )
return 0
;;
esac
# Host has been specified, so now do simple command completion
if [ $COMP_CWORD -gt 1 ]; then
COMPREPLY=( $( compgen -c $cur ) )
return 0
fi
# Otherwise, check for known hosts
_known_hosts
return 0
}
complete -F _ssh ssh slogin sftp
# 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
if [ -n "$2" ]; then
gcmd='grep "^$2"'
else
gcmd=cat
fi
# 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])' make gmake pmake
2001-01-10 15:09:48 -08:00
# 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
#
_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
2001-01-10 15:09:48 -08:00
#[[ "$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
}
complete -F _service service
# This meta-cd function observes the CDPATH variable, so that cd additionally
# completes on directories under those specified in CDPATH.
#
_cd()
{
local cur=${COMP_WORDS[COMP_CWORD]} dirs=()
# that's all if parameter contains a /
[[ "$cur" == /* ]] && return 0
[ -n "$CDPATH" ] && {
# 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
}
return 0
}
complete -F _cd -o dirnames cd
#
# 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 | awk '{if ($1 ~ /--.*/) print $1}' | grep ^"$2" | sort -u) )
}
complete -F _configure_func configure