# bash_completion - some programmable completion functions for bash 2.05a # # $Id: bash_completion,v 1.332 2002/05/21 17:10:13 ianmacd Exp $ # # Copyright (C) Ian Macdonald # # 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: 20020521 [ -n "$DEBUG" ] && set -v || set +v # Alter the following to reflect the location of this file # [ -z "$BASH_COMPLETION" ] && declare -r BASH_COMPLETION=/etc/bash_completion [ -z "$BASH_COMPLETION_DIR" ] && \ declare -r BASH_COMPLETION_DIR=/etc/bash_completion.d # Set a couple of useful vars # UNAME=$( uname -s ) RELEASE=$( uname -r ) if [ ${BASH_VERSINFO[1]} '>' 04 ]; then default="-o default" dirnames="-o dirnames" filenames="-o filenames" fi [ ${BASH_VERSINFO[1]} = "05b" ] && nospace="-o nospace" # 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 pushd # The following section lists completions that are redefined later # Do NOT break these over multiple lines. # # START exclude -- do NOT remove this line complete -f -X '!*.bz2' bunzip2 bzcat bzcmp bzdiff bzegrep bzfgrep bzgrep complete -f -X '!*.@(zip|ZIP|jar|JAR|exe|EXE|pk3|war)' unzip zipinfo complete -f -X '*.Z' compress znew complete -f -X '!*.@(Z|gz|tgz|Gz)' gunzip zcmp zdiff zcat zegrep zfgrep zgrep zless zmore complete -f -X '!*.Z' uncompress complete -f -X '!*.@(gif|jp?(e)g|tif?(f)|png|p[bgp]m|bmp|xpm|ico|GIF|JPG|JP?(E)G|TIF?(F)|PNG|P[BGP]M|BMP|XPM|ICO)' ee display complete -f -X '!*.@(gif|jp?(e)g|tif?(f)|png|p[bgp]m|bmp|xpm|GIF|JPG|JP?(E)G|TIF?(F)|PNG|P[BGP]M|BMP|XPM)' xv qiv complete -f -X '!*.@(@(?(e)ps|?(E)PS|pdf|PDF)?(.gz|.GZ|.Z))' gv ggv complete -f -X '!*.@(dvi|DVI)?(.@(gz|Z|bz2))' xdvi complete -f -X '!*.@(dvi|DVI)' dvips dviselect dvitype complete -f -X '!*.@(pdf|PDF)' acroread xpdf complete -f -X '!*.texi*' makeinfo texi2dvi texi2html complete -f -X '!*.@(?(la)tex|?(LA)TEX|dtx|DTX|ins|INS)' tex latex slitex jadetex pdfjadetex pdftex pdflatex complete -f -X '!*.@(mp3|MP3)' mpg123 mpg321 complete -f -X '!*.@(mpg|mpeg|avi|asf|vob|bin|vcd|ps|pes|fli|viv|rm|ram|yuv|mov|wmv|mp3|MP3|ogg|OGG)' mplayer xine complete -f -X '!*.@(avi|asf)' aviplay complete -f -X '!*.@(rm|ram|smi?(l))' realplay complete -f -X '!*.@(mpg|mpeg|avi|mov)' xanim complete -f -X '!*.@(ogg|OGG)' ogg123 complete -f -X '!*.@(mp3|MP3|ogg|OGG|pls|m3u)' xmms gqmpeg freeamp complete -f -X '!*.fig' xfig complete -f -X '!*.@(mid?(i))' timidity playmidi complete -f -X '*.@(o|so|so.*|a|tar|?(t)gz|?(t)bz2|rpm|zip|ZIP|gif|GIF|jp?(e)g|JP?(E)G|mp3|MP3|mpg|MPG|avi|AVI|asf|ASF' vi vim emacs complete -f -X '!*.@(exe|EXE|com|COM)' wine complete -f -X '!*.@(zip|ZIP|z|Z|gz|GZ|tgz|TGZ)' bzme # FINISH exclude -- do not remove this line # start of section containing compspecs that can be handled within bash # user commands see only users complete -u finger su usermod userdel passwd chage write talk chfn # group commands see only groups [ ${BASH_VERSINFO[1]} '>' 04 ] && complete -g groupmod groupdel 2>/dev/null # bg completes with stopped jobs complete -A stopped -P '%' bg # other job commands complete -j -P '%' fg jobs disown # readonly and unset complete with shell variables complete -v 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 # type and which complete on commands complete -c command type which # start of section containing completion functions called by other functions # This function checks whether we have a given programs on the system. # No need for bulky functions in memory if we don't. # have() { unset -v have type $1 &> /dev/null [ $? -eq 0 ] && have="yes" } # This function performs file and directory completion. It's better than # simply using 'compgen -f', because it honours spaces in filenames. # If passed -d, it completes only on directories. If passed anything else, # it's assumed to be a file glob to complete on. # _filedir() { local IFS=$'\t\n' xspec _expand || return 0 if [ "$1" = -d ]; then COMPREPLY=( ${COMPREPLY[@]} $( compgen -d -- $cur ) ) return 0 fi xspec=${1:+"!*.$1"} # set only if glob passed in as $1 COMPREPLY=( ${COMPREPLY[@]} $( compgen -f -X "$xspec" -- "$cur" ) $( compgen -d -- "$cur" ) ) } # This function completes on signal names # _signals() { local i # 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 } # This function expands tildes in pathnames # _expand() { [ "$cur" != "${cur%\\}" ] && cur="$cur"'\' # expand ~username type directory specifications if [[ "$cur" == \~*/* ]]; then eval cur=$cur elif [[ "$cur" == \~* ]]; then cur=${cur#\~} COMPREPLY=( $( compgen -P '~' -u $cur ) ) return ${#COMPREPLY[@]} fi } # This function completes on process IDs # _pids() { COMPREPLY=( $( compgen -W '$( ps axo pid | sed 1d )' -- $cur ) ) } # This function completes on process group IDs # _pgids() { COMPREPLY=( $( compgen -W '$( ps axo pgid | sed 1d )' -- $cur ) ) } # start of section containing completion functions for bash built-ins # bash alias completion # _alias() { local cur COMPREPLY=() cur=${COMP_WORDS[$COMP_CWORD]}; case "$COMP_LINE" in *[^=]) COMPREPLY=( $( compgen -A alias -S '=' -- $cur ) ) ;; *=) COMPREPLY=( "$( alias ${cur%=} 2>/dev/null | \ sed -e 's|^alias '$cur'\(.*\)$|\1|' )" ) ;; esac } complete -F _alias alias # bash export completion # _export() { local cur COMPREPLY=() cur=${COMP_WORDS[$COMP_CWORD]}; case "$COMP_LINE" in *=\$*) COMPREPLY=( $( compgen -v -P '$' -- ${cur#*=\$} ) ) ;; *[^=]) COMPREPLY=( $( compgen -v -S '=' -- $cur ) ) ;; *=) COMPREPLY=( $( eval echo $`echo ${cur%=}` ) ) ;; esac } complete -F _export $default export # bash shell function completion # _function() { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} if [[ $1 == @(declare|typeset) ]]; then if [ "$prev" = -f ]; then COMPREPLY=( $( compgen -A function -- $cur ) ) elif [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '-a -f -F -i -r -x -p' -- \ $cur ) ) fi elif [ $COMP_CWORD -eq 1 ]; then COMPREPLY=( $( compgen -A function -- $cur ) ) else COMPREPLY=( "() $( type -- ${COMP_WORDS[1]} | sed -e 1,2d )" ) fi } complete -F _function function declare typeset # start of section containing completion functions for external programs # chown(1) completion # _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 -eq 1 ] || [[ "$prev" == -* ]]; then if [[ "$cur" == [a-zA-Z]*[.:]* ]] && \ [ ${BASH_VERSINFO[1]} '>' 04 ]; then user=${cur%%?(\\)[.:]*} group=${cur#*[.:]} COMPREPLY=( $( compgen -P $user'\:' \ -g -- $group 2>/dev/null) ) else COMPREPLY=( $( compgen -S '\:' -u $cur ) ) fi fi return 0 } complete -F _chown $default chown # chgrp(1) completion # _chgrp() { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} # first parameter on line or first since an option? if [ $COMP_CWORD -eq 1 ] && [[ "$cur" != -* ]] || \ [[ "$prev" == -* ]]; then [ ${BASH_VERSINFO[1]} '>' 04 ] && \ COMPREPLY=( $( compgen -g $cur 2>/dev/null) ) else _expand || return 0 fi return 0 } complete -F _chgrp $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]} COMPREPLY=( $( compgen -W '$( mount | cut -d" " -f 3 )' -- $cur ) ) return 0 } complete -F _umount $dirnames 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}/{,s}bin/showmount; do [ -x $i ] && sm=$i && break; done if [ -n "$sm" ] && [[ "$cur" == *:* ]]; then COMPREPLY=( $( $sm -e ${cur%%:*} | sed 1d | \ grep ^${cur#*:} | awk '{print $1}' ) ) else COMPREPLY=( $( awk '{if ($2 ~ /\//) print $2}' /etc/fstab | \ grep "^$cur" ) ) fi return 0 } complete -F _mount $default mount # Linux rmmod(1) completion. This completes on a list of all currently # installed kernel modules. # [ $UNAME = Linux ] && _rmmod() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} COMPREPLY=( $( /sbin/lsmod | \ awk '{if (NR != 1 && $1 ~ /^'$cur'/) print $1}' ) ) return 0 } [ $UNAME = 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. # [ $UNAME = 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 [ $1 = "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 _filedir return 0 fi if [ $COMP_CWORD -gt 1 ]; then # do module parameter completion COMPREPLY=( $( /sbin/modinfo -p ${COMP_WORDS[1]} 2>/dev/null | \ awk '{if ($1 ~ /^parm:/ && $2 ~ /^'$cur'/) { print $2 } \ else if ($1 !~ /:/ && $1 ~ /^'$cur'/) { print $1 }}' ) ) elif [ -r $modpath -a -x $modpath ]; then # do module name completion COMPREPLY=( $( \ls -R $modpath | \ sed -ne 's/^\('$cur'.*\)\.o\(\|.gz\)$/\1/p') ) else _filedir fi return 0 } [ $UNAME = Linux ] && complete -F _insmod $filenames insmod modprobe # man(1) completion. This is GNU, GNU/Linux and Darwin specific, in that # 'man
' is the expected syntax. # [ $UNAME = GNU -o $UNAME = Linux -o $UNAME = Darwin ] && _man() { local cur prev sect manpath UNAME COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} _expand || return 0 # default completion if parameter contains / if [[ "$cur" == */* ]]; then _filedir return 0 fi UNAME=$( uname -s ) if [ $UNAME = GNU -o $UNAME = Linux ]; then manpath=$( manpath 2>/dev/null || \man --path ) else manpath=$MANPATH fi if [ -z "$manpath" ]; then COMPREPLY=( $( compgen -c -- $cur ) ) return 0 fi # determine manual section to search [[ "$prev" == [0-9ln] ]] && sect=$prev || sect='?' manpath=$manpath: if [ -n "$cur" ]; then manpath="${manpath//://man$sect/$cur* }" else manpath="${manpath//://man$sect/ }" fi # redirect stderr for when path doesn't exist COMPREPLY=( $( eval \\ls "$manpath" 2>/dev/null ) ) # weed out directory path names and paths to man pages COMPREPLY=( ${COMPREPLY[@]##*/?(:)} ) # strip suffix from man pages COMPREPLY=( ${COMPREPLY[@]%.@(gz|bz2)} ) COMPREPLY=( ${COMPREPLY[@]%.*} ) [[ "$prev" != [0-9ln] ]] && _filedir '[0-9ln]' return 0 } [ $UNAME = GNU -o $UNAME = Linux -o $UNAME = Darwin ] && complete -F _man $filenames man # renice(8) completion # _renice() { local command cur curopt i COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} command=$1 i=0 # walk back throuh command line and find last option while [ $i -le $COMP_CWORD -a ${#COMPREPLY[@]} -eq 0 ]; do curopt=${COMP_WORDS[COMP_CWORD-$i]} case "$curopt" in -u) COMPREPLY=( $( compgen -u -- $cur ) ) ;; -g) _pgids ;; -p|$command) _pids ;; esac i=$(( ++i )) done } complete -F _renice renice # kill(1) completion # _kill() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} if [ $COMP_CWORD -eq 1 ] && [[ "$cur" == -* ]]; then # return list of available signals _signals else # return list of available PIDs _pids fi } complete -F _kill kill # Linux and FreeBSD killall(1) completion. # [ $UNAME = Linux -o $UNAME = FreeBSD ] && _killall() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} if [ $COMP_CWORD -eq 1 ] && [[ "$cur" == -* ]]; then _signals else COMPREPLY=( $( compgen -W '$( ps axo ucomm | sed 1d )' \ -- $cur ) ) fi return 0 } [ $UNAME = Linux -o $UNAME = FreeBSD ] && 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' -- $cur ) ) return 0 ;; -?(a)newer|-fls|-fprint?(0|f)|-?(i)?(l)name) _filedir 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 ~ /^'$ncur'/) print $3}' /etc/group ) ) return 0 ;; -group) [ ${BASH_VERSINFO[1]} '>' 04 ] && \ COMPREPLY=( $( compgen -g -- $cur 2>/dev/null) ) return 0 ;; -?(x)type) COMPREPLY=( $( compgen -W 'b c d p f l s' -- $cur ) ) return 0 ;; -uid) COMPREPLY=( $( awk 'BEGIN {FS=":"} \ {if ($3 ~ /^'$ncur'/) 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 _expand || return 0 # handle case where first parameter is not a dash option if [ $COMP_CWORD -eq 1 ] && [[ "$cur" != -* ]]; then _filedir -d return 0 fi # complete using basic options 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[@]}) ) ) return 0 } complete -F _find $filenames find # Linux ifconfig(8) completion # [ $UNAME = 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=( $( /sbin/ifconfig -a | \ sed -ne 's|^\('$cur'[^ ]*\).*$|\1|p' )) } [ $UNAME = Linux ] && complete -F _ifconfig ifconfig # RedHat & Debian GNU/Linux if{up,down} completion # [ $UNAME = Linux ] && ( have ifup || have ifdown ) && _ifupdown() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} if [ $COMP_CWORD -eq 1 ]; then if [ -f /etc/debian_version ]; then # Debian system COMPREPLY=( $( sed -ne 's|^iface \([^ ]\+\).*$|\1|p' \ /etc/network/interfaces ) ) else # Assume Red Hat COMPREPLY=( $( \ls /etc/sysconfig/network-scripts/ifcfg-* | sed -ne 's|.*ifcfg-\('$cur'.*\)|\1|p' ) ) fi fi return 0 } [ $UNAME = Linux ] && have ifup && complete -F _ifupdown ifup ifdown # Linux ipsec(8) completion (for FreeS/WAN). Basic. # [ $UNAME = Linux ] && have ipsec && _ipsec() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} if [ $COMP_CWORD -eq 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 ) ) ;; manual) COMPREPLY=( $( compgen -W '--up --down --route --unroute \ --union' $cur ) ) ;; ranbits) COMPREPLY=( $( compgen -W '--quick --continuous --bytes' $cur ) ) ;; setup) COMPREPLY=( $( compgen -W '--start --stop --restart' $cur ) ) ;; *) ;; esac return 0 } [ $UNAME = Linux ] && [ "$have" ] && complete -F _ipsec ipsec # Postfix completion. # have postfix && { # postfix(1) # _postfix () { COMPREPLY=( $( compgen -W 'start stop reload abort flush check' -- \ "${COMP_WORDS[COMP_CWORD]}" ) ) } complete -F _postfix postfix # postalias(1) and postmap(1) # _postmap() { local cur prev len idx cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} if [[ $cur == '-' ]]; then COMPREPLY=(-N -f -i -n -o -r -v -w -c -d -q) return 0 fi if [[ $prev == '-c' ]]; then _filedir -d return 0 fi if [[ $prev == -[dq] ]]; then return 0 fi if [[ "$cur" == *:* ]]; then COMPREPLY=( $( compgen -f -- ${cur#*:} ) ) else len=${#cur} idx=0 for pval in $( postconf -m ); do if [[ "$cur" == "${pval:0:$len}" ]]; then COMPREPLY[$idx]="$pval:" idx=$(($idx+1)) fi done if [[ $idx -eq 0 ]]; then COMPREPLY=( $( compgen -f -- "$cur" ) ) fi fi return 0 } complete -F _postmap postmap postalias # postconf(1) # _postconf() { local cur prev len idx eqext cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} if [[ $cur == '-' ]]; then COMPREPLY=(-c -d -e -h -m -l -n -v) return 0 fi if [[ $prev == '-c' ]]; then _filedir -d return 0 fi if [[ $prev == '-e' ]]; then cur=${cur#[\"\']} eqext='=' fi len=${#cur} idx=0 for pval in $( postconf | cut -d ' ' -f 1 ); do if [[ "$cur" == "${pval:0:$len}" ]]; then COMPREPLY[$idx]="$pval$eqext" idx=$(($idx+1)) fi done return 0 } complete -F _postconf postconf # postsuper(1) # _postsuper() { local cur prev len idx cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} if [[ $cur == '-' ]]; then COMPREPLY=(-d -p -r -s -v) return 0 fi if [[ $prev == -[dr] ]]; then len=${#cur} idx=0 for pval in $( mailq | \ sed -e '1d; $d; /^[^0-9A-Z]\|^$/d; s/[* ].*$//' ); do if [[ "$cur" == "${pval:0:$len}" ]]; then COMPREPLY[$idx]=$pval idx=$(($idx+1)) fi done return 0 fi _filedir -d return 0 } complete -F _postsuper postsuper } # cvs(1) completion # have cvs && { set_prefix() { [ -z "$prefix" ] || prefix=${cur%/*}/ [ -r ${prefix}CVS/Entries ] || prefix="" } get_entries() { entries=( $( compgen -W \ "$( echo $( cut -d/ -f2 -s ${prefix}CVS/Entries ) )" -- $cur ) ) } get_modules() { if [ -n "$prefix" ]; then COMPREPLY=( $( \ls -d ${cvsroot}/${prefix}/!(CVSROOT) )) else COMPREPLY=( $( \ls -d ${cvsroot}/!(CVSROOT) ) ) fi } _cvs() { local cur count mode i cvsroot pwd local -a flags miss files entries changed newremoved COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} count=1 for i in ${COMP_WORDS[@]}; do [ $count -eq $COMP_CWORD ] && break if [ -z "$mode" ]; then case $i in -d) cvsroot=${COMP_WORDS[((++count))]} ;; @(add|new)) mode=add ;; @(admin|rcs)) mode=admin ;; @(checkout|co|get)) mode=checkout ;; @(commit|ci)) mode=commit ;; @(annotate|diff|@(ex|im)port|history|release|status|update)) mode=$i ;; ?(r)log) mode=log ;; @(rdiff|patch)) mode=rdiff ;; @(remove|rm|delete)) mode=remove ;; @(rtag|rfreeze)) mode=rtag ;; @(tag|freeze)) mode=tag ;; *) ;; esac continue elif [[ "$i" = -* ]]; then flags=( ${flags[@]} $i ) fi count=$((++count)) done case "$mode" in add) if [[ "$cur" != -* ]]; then set_prefix if [ $COMP_CWORD -gt 1 -a -r ${prefix}CVS/Entries ]; then get_entries [ -z "$cur" ] && \ files=$( \ls -A !(CVS) ) || \ files=$( \ls -d ${cur}* 2>/dev/null ) for i in ${entries[@]}; do files=( ${files[@]%$i} ) done COMPREPLY=( $( compgen -W '${files[@]}' -- \ $cur ) ) fi else COMPREPLY=( $( compgen -W '-k -m' -- $cur ) ) fi ;; admin) if [[ "$cur" = -* ]]; then COMPREPLY=( $( compgen -W '-i -a -A -e -b -c -k -l -u \ -L -U -m -M -n -N -o -q -I \ -s -t -t- -T -V -x -z' -- \ $cur ) ) fi ;; checkout) if [[ "$cur" != -* ]]; then [ -z "$cvsroot" ] && cvsroot=$CVSROOT COMPREPLY=( $( cvs -d "$cvsroot" co -c | awk '{print $1}' ) ) COMPREPLY=( $( compgen -W '${COMPREPLY[@]}' -- $cur ) ) else COMPREPLY=( $( compgen -W '-A -N -P -R -c -f -l -n -p \ -s -r -D -d -k -j' -- $cur ) ) fi ;; commit) set_prefix if [[ "$cur" != -* ]] && [ -r ${prefix}CVS/Entries ]; then # if $COMP_CVS_REMOTE is not null, 'cvs commit' will # complete on remotely checked-out files (requires # passwordless access to the remote repository if [ -n "$COMP_CVS_REMOTE" ]; then # this is the least computationally intensive # way found so far, but other changes # (something other than changed/removed/new) # may be missing changed=( $( cvs diff --brief 2>&1 | \ sed -ne 's/^Files [^ ]* and \([^ ]*\) differ$/\1/p' ) ) newremoved=( $( cvs diff --brief 2>&1 | \ sed -ne 's/^cvs diff: \([^ ]*\) .*, no comparison available$/\1/p' ) ) COMPREPLY=( $( compgen -W '${changed[@]} \ ${newremoved[@]}' -- $cur ) ) else COMPREPLY=( $( compgen -f -- $cur ) ) fi else COMPREPLY=( $( compgen -W '-n -R -l -f -F -m -r' -- \ $cur ) ) fi ;; diff) if [[ "$cur" == -* ]]; then _longopt diff else get_entries COMPREPLY=( ${entries[@]} ) fi ;; remove) if [[ "$cur" != -* ]]; then set_prefix if [ $COMP_CWORD -gt 1 -a -r ${prefix}CVS/Entries ]; then get_entries # find out what files are missing for i in ${entries[@]}; do [ ! -r "$i" ] && miss=( ${miss[@]} $i ) done COMPREPLY=( $(compgen -W '${miss[@]}' -- $cur) ) fi else COMPREPLY=( $( compgen -W '-f -l -R' -- $cur ) ) fi ;; import) if [[ "$cur" != -* ]]; then # starts with same algorithm as checkout [ -z "$cvsroot" ] && cvsroot=$CVSROOT prefix=${cur%/*} if [ -r ${cvsroot}/${prefix} ]; then get_modules COMPREPLY=( ${COMPREPLY[@]#$cvsroot} ) COMPREPLY=( ${COMPREPLY[@]#\/} ) fi pwd=$( pwd ) pwd=${pwd##*/} COMPREPLY=( $( compgen -W '${COMPREPLY[@]} $pwd' -- \ $cur ) ) else COMPREPLY=( $( compgen -W '-d -k -I -b -m -W' -- $cur )) fi ;; "") COMPREPLY=( $( compgen -W 'add admin annotate checkout ci co \ commit diff delete export freeze \ get history import log new patch rcs\ rdiff release remove rfreeze rlog \ rm rtag status tag update -H -Q -q \ -b -d -e -f -l -n -t -r -v -w -x \ -z --help --version' -- $cur ) ) ;; *) ;; esac return 0 } [ "$have" ] && complete -F _cvs $default cvs } have rpm && { # helper functions for rpm completion # rpm_installed_packages() { if [ -r /var/log/rpmpkgs -a \ /var/log/rpmpkgs -nt /var/lib/rpm/Packages ]; then # using RHL 7.2 - this is quicker than querying the DB COMPREPLY=( $( sed -ne \ 's|^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9a-z.]\+.*\.rpm$|\1|p' \ /var/log/rpmpkgs ) ) else COMPREPLY=( $( rpm -qa | sed -ne \ 's|^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9a-z.]\+$|\1|p' ) ) fi } rpm_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' ) ) } # rpm(8) completion # _rpm() { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} if [ $COMP_CWORD -eq 1 ]; then # first parameter on line case "$cur" in -b*) COMPREPLY=( $( compgen -W '-ba -bb -bc -bi -bl -bp -bs'\ -- $cur ) ) ;; -t*) COMPREPLY=( $( compgen -W '-ta -tb -tc -ti -tl -tp -ts'\ -- $cur ) ) ;; --*) 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 --clean \ --import' -- $cur ) ) ;; *) COMPREPLY=( $( compgen -W '-b -e -F -i -q -t -U -V' \ -- $cur ) ) ;; esac return 0 fi case "$prev" in --@(@(db|exclude)path|prefix|relocate|root)) _filedir -d 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) _filedir return 0 ;; --specfile) # complete on .spec files _filedir spec return 0 ;; --whatprovides) if [[ "$cur" == */* ]]; then _filedir else # complete on capabilities COMPREPLY=( $( rpm -qa --queryformat \ '%{providename}\n' | grep "^$cur" ) ) fi 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)) if [[ "$cur" == -* ]]; then 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 --nosuggests \ --nodigest --nosignature' -- $cur ) ) else _filedir 'rpm' fi ;; -@(e|-erase)) if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '--allmatches --noscripts \ --notriggers --nodeps --test --repackage' -- $cur ) ) else rpm_installed_packages fi ;; -@(q*|-query)) # check whether we're doing file completion if [ "${COMP_LINE#* -*([^ -])f}" != "$COMP_LINE" ]; then _filedir elif [ "${COMP_LINE#* -*([^ -])g}" != "$COMP_LINE" ]; then rpm_group_completion elif [ "${COMP_LINE#* -*([^ -])p}" != "$COMP_LINE" ]; then # uninstalled package completion if [[ "$cur" == -* ]]; then 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 --nodigest \ --nosignature' -- $cur ) ) else _filedir 'rpm' fi else # installed package completion if [[ "$cur" == -* ]]; then 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 --pkgid --hdrid \ --fileid --tid --nodigest --nosignature' \ -- $cur ) ) elif [ "${COMP_LINE#* -*([^ -])a}" == "$COMP_LINE" ]; then rpm_installed_packages fi fi ;; -@(K|-checksig)) if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '--nopgp --nogpg --nomd5 \ --nodigest --nosignature' -- $cur ) ) else _filedir 'rpm' fi ;; -@([Vy]*|-verify)) if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '--root --rcfile --dbpath \ --nodeps --nofiles --noscripts --nomd5 --querytags \ --specfile --whatrequires --whatprovides --nodigest \ --nosignature' -- $cur ) ) # check whether we're doing file completion elif [ "${COMP_LINE#* -*([^ -])f}" != "$COMP_LINE" ]; then _filedir elif [ "${COMP_LINE#* -*([^ -])g}" != "$COMP_LINE" ]; then rpm_group_completion elif [ "${COMP_LINE#* -*([^ -])p}" != "$COMP_LINE" ]; then _filedir 'rpm' else rpm_installed_packages fi ;; -[bt]*) if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '--short-circuit --timecheck \ --clean --rmsource --rmspec --test --sign --buildroot \ --targetbuildarch --buildos --nobuild --nodeps \ --nodirtokens' -- $cur ) ) elif [[ ${COMP_WORDS[1]} == -b* ]]; then _filedir 'spec' else _filedir '@(tgz|tar.@(gz|bz2))' fi ;; --re@(build|compile)) if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '--nodeps --rmsource \ --rmspec --sign --nodirtokens' -- $cur ) ) else _filedir 'src.rpm' fi ;; --tarbuild) _filedir '@(tgz|tar.@(gz|bz2))' ;; --@(re|add)sign) _filedir 'rpm' ;; --set@(perms|gids)) rpm_installed_packages ;; --@(clean|rms@(ource|pec))) if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '--clean --rmsource \ --rmspec' -- $cur ) ) else _filedir 'spec' fi ;; --@(import|dbpath|root)) if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '--import --dbpath --root' \ -- $cur ) ) else _filedir fi ;; esac return 0 } complete -F _rpm $filenames rpm rpmbuild } # Debian 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|build-dep) ]]; then special=${COMP_WORDS[i]} fi done if [ -n "$special" ]; then case $special in @(install|source|build-dep)) COMPREPLY=( $( apt-cache pkgnames $cur ) ) return 0 ;; remove) if [ -f /etc/debian_version ]; then # Debian system COMPREPLY=( $( _comp-dpkg-installed-packages \ $cur ) ) else # assume RPM based rpm_installed_packages fi return 0 ;; esac fi if [[ "$prev" == -*c ]] || [ "$prev" = --config-file ]; then _filedir else COMPREPLY=( $( compgen -W 'update upgrade dselect-upgrade \ dist-upgrade install remove source \ build-dep 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' -- $cur ) ) fi return 0 } [ "$have" ] && complete -F _apt_get $filenames apt-get # Debian 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|show?(pkg)|depends|dotty) ]]; then special=${COMP_WORDS[i]} fi done if [ -n "$special" ]; then case $special in add) _filedir return 0 ;; show?(pkg)|depends|dotty) COMPREPLY=( $( apt-cache pkgnames $cur ) ) return 0 ;; esac fi if [[ "$prev" == -*c ]] || [ "$prev" = --config-file ]; then _filedir else COMPREPLY=( $( compgen -W 'add gencaches showpkg stats dump \ dumpavail unmet check search show dotty \ 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' -- $cur ) ) fi return 0 } [ "$have" ] && complete -F _apt-cache $filenames apt-cache complete -F _apt_cache $filenames apt-cache # Debian Linux aptitude(1) completion # have aptitude && { _comp-dpkg-hold-packages() { grep -B 2 'hold' /var/lib/dpkg/status | grep 'Package' \ | cut -d\ -f2 } _aptitude() { local cur dashoptions prev special i COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} dashoptions='-S -u -i -h --help --version -s --simulate -d \ --download-only -P --prompt -y --assume-yes -F \ --display-format -w --width -f --with-recommends \ --with-suggests --without-recommends --without-suggests' for (( i=0; i < ${#COMP_WORDS}-1; i++ )); do if [[ ${COMP_WORDS[i]} == @(install|hold|unhold|markauto|unmarkauto|dist-upgrade|download|purge|remove) ]]; then special=${COMP_WORDS[i]} fi #exclude some mutually exclusive options [[ ${COMP_WORDS[i]} == '-u' ]] && dashoptions=${dashoptions/-i} [[ ${COMP_WORDS[i]} == '-i' ]] && dashoptions=${dashoptions/-u} done if [[ -n "$special" ]]; then case $special in @(install|hold|markauto|unmarkauto|dist-upgrade|download)) COMPREPLY=( $( apt-cache pkgnames $cur ) ) return 0 ;; @(purge|remove)) COMPREPLY=( $( _comp-dpkg-installed-packages $cur ) ) return 0 ;; unhold) COMPREPLY=( $( _comp-dpkg-hold-packages $cur ) ) return 0 ;; esac fi case $prev in # don't complete anything if these options are found @(autoclean|clean|forget-new|search|upgrade|update)) return 0 ;; -S) _filedir return 0 ;; esac if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W "$dashoptions" -- $cur ) ) else COMPREPLY=( $( compgen -W 'update upgrade forget-new clean \ autoclean install remove hold unhold \ purge markauto unmarkauto dist-upgrade \ download search' -- $cur ) ) fi } [ "$have" ] && complete -F _aptitude $default aptitude } # 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 COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} if [ $COMP_CWORD -eq 1 ]; then COMPREPLY=( $( compgen -W '--list --add --del --level' -- \ $cur ) ) 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 ocur user suffix aliases global_kh user_kh hosts local -a kh config COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} ocur=$cur [ "$1" = -a ] || [ "$2" = -a ] && aliases='yes' [ "$1" = -c ] || [ "$2" = -c ] && suffix=':' [[ $cur == *@* ]] && user=${cur%@*}@ && cur=${cur#*@} kh=() # ssh config files [ -r /etc/ssh/ssh_config ] && config[0]=/etc/ssh/ssh_config [ -r ~/.ssh/config ] && config[1]=~/.ssh/config if [ ${#config[@]} -gt 0 ]; then # expand path (if present) to global known hosts file global_kh=$( eval echo $( sed -ne 's/^GlobalKnownHostsFile['$'\t '']*\(.*\)$/\1/ip' ${config[@]} ) ) # expand path (if present) to user known hosts file user_kh=$( eval echo $( sed -ne 's/^UserKnownHostsFile['$'\t '']*\(.*\)$/\1/ip' ${config[@]} ) ) fi # choose which global known hosts file to use if [ -r "$global_kh" ]; then kh=( "$global_kh" ) else [ -r /etc/known_hosts ] && kh[0]=/etc/known_hosts [ -r /etc/known_hosts2 ] && kh[1]=/etc/known_hosts2 fi # choose which user known hosts file to use if [ -r "$user_kh" ]; then kh=( ${kh[@]} "$user_kh" ) else [ -r ~/.ssh/known_hosts ] && kh=( ${kh[@]} ~/.ssh/known_hosts ) [ -r ~/.ssh/known_hosts2 ] && kh=( ${kh[@]} ~/.ssh/known_hosts2 ) fi # 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[@]} ) ) # append any available aliases from config files if [ ${#config[@]} -gt 0 ] && [ -n "$aliases" ]; then hosts=$( compgen -W "$( echo $( sed -ne "s/^Host["$'\t '"]*\([^*?]*\)$/\1/ip" ${config[@]} ) )" -- $ocur ) COMPREPLY=( ${COMPREPLY[@]} $hosts ) fi # apply suffix for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do COMPREPLY[i]=$user${COMPREPLY[i]}$suffix done else # Just do normal hostname completion COMPREPLY=( $( compgen -A hostname -S "$suffix" -- $cur ) ) fi return 0 } complete -F _known_hosts traceroute ping fping telnet host nslookup rsh \ rlogin ftp # ssh(1) completion # have ssh && { _ssh() { local cur prev local -a config 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 -a [ $COMP_CWORD -eq 1 ] || \ COMPREPLY=( ${COMPREPLY[@]} $( compgen -c -- $cur ) ) esac return 0 } [ "$have" ] && shopt -u hostcomplete && complete -F _ssh ssh slogin sftp # scp(1) completion # _scp() { local cur userhost path COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} _expand || return 0 if [[ "$cur" == *:* ]]; then # remove backslash escape from : cur=${cur/\\:/:} userhost=${cur%%?(\\):*} path=${cur#*:} if [ -z "$path" ]; then # default to home dir of specified user on remote host path=$( ssh -o 'Batchmode yes' $userhost pwd ) fi COMPREPLY=( $( compgen -P "$userhost:" \ -W "`echo $( ssh -o 'Batchmode yes' $userhost \ compgen -f -- $path 2>/dev/null)`")) return 0 fi [[ "$cur" == */* ]] || _known_hosts -c -a _filedir return 0 } [ "$have" ] && complete $filenames -F _scp scp } # Linux route(8) completion # [ $UNAME = Linux ] && _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 COMPREPLY=( $( compgen -W 'add del -host -net netmask metric mss \ window irtt reject mod dyn reinstate dev \ default gw' -- $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 } [ $UNAME = Linux ] && complete -F _route route # GNU make(1) completion (adapted from the example supplied with the bash 2.04 # source code) # have make && _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 _filedir return 0 fi # check for a long option if [[ "$cur" == --* ]]; then _longopt $1 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' \ -- $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 COMPREPLY=( $( grep -v '^\w\w*[[:space:]]*:=' $makef 2>/dev/null | \ awk 'BEGIN {FS=":"} /^[^.#'$'\t''][^=]*:/ {print $1}' | \ eval $gcmd ) ) # default to filename completion if all else failed [ ${#COMPREPLY[@]} -eq 0 ] && _filedir return 0 } [ "$have" ] && complete -F _make -X '+($*|*.[cho])' $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 -eq 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 # GNU tar(1) completion # _tar() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} if [ $COMP_CWORD = 1 ]; then COMPREPLY=( $( compgen -W 'c t x u r d A' -- $cur ) ) return 0 fi case "${COMP_WORDS[1]}" in c*f) _filedir ;; +([^Izjy])f) _filedir 'tar' ;; *z*f) _filedir 't?(ar.)gz' ;; *[Ijy]*f) _filedir 'tar.bz2' ;; *) _filedir ;; esac return 0 } complete -F _tar $filenames tar # jar(1) completion # have jar && _jar() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} if [ $COMP_CWORD = 1 ]; then COMPREPLY=( $( compgen -W 'c t x u' -- $cur ) ) return 0 fi case "${COMP_WORDS[1]}" in c*f) _filedir ;; *f) _filedir 'jar' ;; *) _filedir ;; esac } [ "$have" ] && complete -F _jar $filenames jar # 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 # autorpm(8) completion # have autorpm && _autorpm() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} COMPREPLY=( $( compgen -W '--notty --debug --help --version \ auto add fullinfo info help install list \ remove set' -- $cur ) ) } [ "$have" ] && complete -F _autorpm autorpm # 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]} i j k # Use standard dir completion if no CDPATH or parameter starts with /, # ./ or ../ if [ -z "$CDPATH" ] || [[ "$cur" == ?(.)?(.)/* ]]; then _filedir -d return 0 fi IFS=$'\t\n' # we have a CDPATH, so loop on its contents for i in ${CDPATH//:/$'\t'}; do # create an array of matched subdirs k=${#COMPREPLY[@]} for j in $( compgen -d $i/$cur); do COMPREPLY[$k]=${j#$i/} k=$((++k)) done done _filedir -d return 0 } complete -F _cd $nospace $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 -eq 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 # # 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 # remove any \: generated by a command that doesn't # default to filenames or dirnames (e.g. sudo chown) if [ "${cspec#*-o }" != "$cspec" ]; then cspec=${cspec#*-o } cspec=${cspec%% *} if [[ "$cspec" != @(dir|file)names ]]; then COMPREPLY=( "${COMPREPLY[@]//\\\\:/:}" ) fi fi 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 func=${cspec#*-A } func=${func%% *} COMPREPLY=( $( compgen -A $func -- $cur ) ) fi fi [ ${#COMPREPLY[@]} -eq 0 ] && _filedir } complete -F _command $filenames nohup exec nice eval strace time _root_command() { PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin _command $1 } complete -F _root_command $filenames sudo fakeroot # ant(1) completion # have ant && _ant() { local cur prev buildfile i COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} case "$prev" in -buildfile) _filedir 'xml' return 0 ;; -logfile) _filedir return 0 ;; esac if [[ "$cur" == -* ]]; then # relevant options completion COMPREPLY=( $( compgen -W '-help -projecthelp -version -quiet \ -verbose -debug -emacs -logfile -logger \ -listener -buildfile -D -find' -- $cur ) ) else # available targets completion # find wich buildfile to use buildfile=build.xml for (( i=1; i < COMP_CWORD; i++ )); do if [[ "${COMP_WORDS[i]}" == -buildfile ]]; then buildfile=${COMP_WORDS[i+1]} break fi done [ ! -f $buildfile ] && return 0 # parse buildfile for targets COMPREPLY=( $( awk -F'"' '//dev/null | \ sed -ne 's|^ \('$cur'[^ ]*\).*$|\1|p' ) ) } _pg_users() { COMPREPLY=( $( psql -qtc 'select usename from pg_user' 2>/dev/null | \ grep "^ $cur" ) ) [ ${#COMPREPLY[@]} -eq 0 ] && COMPREPLY=( $( compgen -u -- $cur ) ) } # psql(1) completion # _psql() { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} case "$prev" in -h|--host) _known_hosts return 0 ;; -U|--username) _pg_users return 0 ;; -d|--dbname) _pg_databases return 0 ;; -@(o|f)|--output|--file) _filedir return 0 ;; esac if [[ "$cur" == -* ]]; then # return list of available options COMPREPLY=( $( compgen -W '-a --echo-all -A --no-align \ -c --command -d --dbname -e --echo-queries \ -E --echo-hidden -f --file -F --filed-separator \ -h --host -H --html -l --list -n -o --output \ -p --port -P --pset -q -R --record-separator \ -s --single-step -S --single-line -t --tuples-only \ -T --table-attr -U --username -v --variable \ -V --version -W --password -x --expanded -X --nopsqlrc \ -? --help ' -- $cur ) ) else # return list of available databases _pg_databases fi } complete -F _psql $default psql # createdb(1) completion # _createdb() { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} case "$prev" in -@(h|-host=)) _known_hosts return 0 ;; -@(U|-username=)) _pg_users return 0 ;; esac if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '-D -T -E -h -p -U -W -e -q \ --location= --template= --encoding= --host= --port= \ --username= --password --echo --quiet --help' -- $cur )) else _pg_databases fi } complete -F _createdb $default createdb # dropdb(1) completion # _dropdb() { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} case "$prev" in -@(h|-host=)) _known_hosts return 0 ;; -@(U|-username=)) _pg_users return 0 ;; esac if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '-h -p -U -W -e -q \ --host= --port= --username= --password \ --interactive --echo --quiet --help' -- $cur ) ) else _pg_databases fi } complete -F _dropdb $default dropdb } _longopt() { local cur opt cur=${COMP_WORDS[COMP_CWORD]} if [[ "$cur" == --*=* ]]; then opt=${cur%%=*} # cut backlash that gets inserted before '=' sign opt=${opt%\\*} cur=${cur#*=} _filedir COMPREPLY=( $( compgen -P "$opt=" -W '${COMPREPLY[@]}' -- $cur)) return 0 fi if [[ "$cur" == -* ]]; then COMPREPLY=( $( $1 --help 2>&1 | sed -e '/--/!d' \ -e 's/.*\(--[-A-Za-z0-9]\+=\?\).*/\1/' | \ grep "^$cur" | sort -u ) ) elif [[ "$1" == @(mk|rm)dir ]]; then _filedir -d else _filedir fi } # makeinfo and texi2dvi are defined elsewhere for i in a2ps autoconf automake bc gprof ld nm objcopy objdump readelf strip \ bison cpio diff patch enscript cp df dir du ln ls mkfifo mknod mv rm \ touch vdir xargs awk gperf grep gpg grub indent less m4 sed shar date \ env seq su tee uname who texindex cat csplit cut expand fmt fold head \ md5sum nl od paste pr ptx sha1sum sort split tac tail tr unexpand \ uniq wc units wget rsync ldd bash id info irb mkdir rmdir netstat; do have $i && complete -F _longopt $filenames $i done unset i # gcc(1) completion # # The only unusual feature is that we don't parse "gcc --help -v" output # directly, because that would include the options of all the other backend # tools (linker, assembler, preprocessor, etc) without any indication that # you cannot feed such options to the gcc driver directly. (For example, the # linker takes a -z option, but you must type -Wl,-z for gcc.) Instead, we # ask the driver ("g++") for the name of the compiler ("cc1"), and parse the # --help output of the compiler. # have gcc && _gcc() { local cur cc backend COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} _expand || return 0 case "$1" in gcj) backend=jc1 ;; gpc) backend=gpc1 ;; *77) backend=f771 ;; *) backend=cc1 # (near-)universal backend ;; esac if [[ "$cur" == -* ]]; then cc=$( $1 -print-prog-name=$backend ) # sink stderr: # for C/C++/ObjectiveC it's useless # for FORTRAN/Java it's an error COMPREPLY=( $( $cc --help 2>/dev/null | tr '\t' ' ' | \ sed -e '/^ *-/!d' -e 's/ *-\([^ ]*\).*/-\1/' | \ grep "^$cur" | sort -u ) ) else _filedir fi } [ "$have" ] && complete $filenames -F _gcc gcc g++ c++ g77 gcj gpc [ $UNAME = GNU -o $UNAME = Linux ] && complete $filenames -F _gcc cc # Linux cardctl(8) completion # have cardctl && _cardctl() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} if [ $COMP_CWORD -eq 1 ]; then COMPREPLY=( $( compgen -W 'status config ident suspend \ resume reset eject insert scheme' \ -- $cur ) ) fi } [ "$have" ] && complete -F _cardctl cardctl # This function is required by _dpkg() and _dpkg-reconfigure() # have dpkg && { _comp-dpkg-installed-packages() { grep -B 2 'ok installed' /var/lib/dpkg/status | grep 'Package' | \ cut -d\ -f2 } # Debian dpkg(8) completion # _dpkg() { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} _expand || return 0 # find the last option flag if [[ $cur != -* ]]; then while [[ $prev != -* && $COMP_CWORD != 1 ]]; do COMP_CWORD=$((COMP_CWORD-1)) prev=${COMP_WORDS[COMP_CWORD-1]} done fi case "$prev" in -i|--install|--unpack|-A|--record-avail|-c|--contents|-I|--info| \ --fsys-tarfile|-f|--field|-e|--control|-X|--extract) _filedir 'deb' return 0 ;; -b|--build) _filedir -d return 0 ;; -s|--status|-p|--print-avail|-l|--list) COMPREPLY=( $( apt-cache pkgnames $cur ) ) return 0 ;; -S|--search) _filedir return 0 ;; -r|--remove|--purge|-L|--listfiles) COMPREPLY=( $( _comp-dpkg-installed-packages $cur ) ) return 0 ;; *) ;; esac COMPREPLY=( $( compgen -W '-i --install --unpack -A --record-avail \ --configure -r --remove --purge --get-selections \ --set-selections --update-avail --merge-avail \ --clear-avail --command-fd --forget-old-unavail -s \ --status -p --print-avail -L --listfiles -l --list \ -S --search -C --audit --print-architecture \ --print-gnu-build-architecture \ --print-installation-architecture \ --compare-versions --help --version --force-help \ --force-all --force-auto-select --force-downgrade \ --force-configure-any --force-hold --force-bad-path \ --force-not-root --force-overwrite \ --force-overwrite-diverted --force-bad-verify \ --force-depends-version --force-depends \ --force-confnew --force-confold --force-confdef \ --force-miss --force-conflicts --force-architecture \ --force-overwrite-dir --force-remove-reinstreq \ --force-remove-essential -Dh \ --debug=help --licence --admindir= --root= --instdir= \ -O --selected-only -E --skip-same-version \ -G --refuse-downgrade -B --auto-deconfigure \ --no-debsig --no-act -D --debug= --status-fd \ -b --build -I --info -f --field -c --contents \ -x --extract -X --vextract --fsys-tarfile -e --control \ --ignore-depends= --abort-after' -- $cur ) ) } [ "$have" ] && complete -F _dpkg $filenames dpkg dpkg-deb } # Debian GNU dpkg-reconfigure(8) completion # have dpkg-reconfigure && _dpkg-reconfigure() { local cur prev opt COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} case "$prev" in -@(f|-frontend)) opt=( $( echo /usr/share/perl5/Debconf/FrontEnd/* ) ) opt=( ${opt[@]##*/} ) opt=( ${opt[@]%.pm} ) COMPREPLY=( $( compgen -W '${opt[@]}' -- $cur ) ) return 0 ;; -@(p|-priority)) COMPREPLY=( $( compgen -W 'low medium high critical' -- $cur ) ) return 0 ;; esac if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '-f --frontend -p --priority -a --all \ -u --unseen-only -h --help -s --showold \ --force --terse' -- $cur ) ) else COMPREPLY=( $( _comp-dpkg-installed-packages $cur ) ) fi } [ "$have" ] && complete -F _dpkg-reconfigure $default dpkg-reconfigure # Debian Linux dselect(8) completion. # have dselect && _dselect() { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} if [ "$prev" = --admindir ]; then _filedir -d elif [[ "$prev" == -*D ]] || [ "$prev" = --debug ]; then _filedir else COMPREPLY=( $( compgen -W 'access update select install \ config remove quit --admindir --help \ --version --licence --license --expert \ --debug' -- $cur ) ) fi return 0 } [ "$have" ] && complete -F _dselect $filenames dselect have java && _java() { local cur prev classpath i COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} case "$prev" in -@(cp|classpath)) _filedir return 0 ;; esac if [[ "$cur" == -* ]]; then # relevant options completion COMPREPLY=( $( compgen -W '-client -hotspot -server -classic \ -cp -classpath -D -verbose -version \ -showversion -? -help -X' -- $cur ) ) else # available classes completion # find wich classpath to use if [ -n "$CLASSPATH" ]; then classpath=$CLASSPATH else classpath=. fi for (( i=1; i < COMP_CWORD; i++ )); do if [[ "${COMP_WORDS[i]}" == -classpath ]] || \ [[ "${COMP_WORDS[i]}" == -cp ]]; then classpath=${COMP_WORDS[i+1]} break fi done # parse each classpath element for classes for i in ${classpath//:/ }; do if [ -f $i ] && [[ "$i" == *.@(jar|zip) ]]; then COMPREPLY=( ${COMPREPLY[@]} $( jar tf $i | \ grep '\.class' | sed -e 's|\.class||g' \ -e 's|/|.|g' | grep "^$cur" )) elif [ -d $i ]; then COMPREPLY=( ${COMPREPLY[@]} $( find $i -type f \ -name \*.class | \ sed -e 's|^'$i'/||' \ -e 's|\.class$||' \ -e 's|/|.|g' | grep "^$cur" ) ) fi done fi } [ "$have" ] && complete -F _java java # PINE address-book completion # have pine && _pineaddr() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} COMPREPLY=( $( compgen -W '$( awk '{print $1}' < ~/.addressbook )' \ -- $cur ) ) } [ "$have" ] && complete -F _pineaddr $default pine _configure_func() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} # if $COMP_CONFIGURE_HINTS is not null, then completions of the form # --option=SETTING will include 'SETTING' as a contextual hint [[ "$cur" != -* ]] && return 0 if [ -n "$COMP_CONFIGURE_HINTS" ]; then COMPREPLY=( $( $1 --help | sed -ne 's|^ *\('$cur'[^ '$'\t'',[]\+\).*$|\1|p' ) ) else COMPREPLY=( $( $1 --help | sed -ne 's|^ *\('$cur'[^ '$'\t'',=[]\+=\?\).*$|\1|p' ) ) fi } complete -F _configure_func $default configure # urpmi media function required by other urpmi functions # have urpmi && _urpmi_media() { local IFS=$'\t\n' # return list of available urpmi media COMPREPLY=( $( sed -ne "s/^\(.\+\) \(\(file\|removable\|ftp\|http\):\/\/.*\)\? {$/\1/p" /etc/urpmi/urpmi.cfg | grep "^${cur//\\\\/\\\\}" ) ) } # Mandrake urpmi completion # have urpmi && _urpmi() { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} case "$prev" in --media) _urpmi_media return 0;; esac if [[ "$cur" == -* ]]; then # return list of available options COMPREPLY=( $( compgen -W '-a -p -P -y -s -q -v --help \ --update --media --auto --auto-select --fuzzy --src \ --noclean --complete --force --wget --curl --X \ --best-output' -- $cur ) ) else # return list of available packages COMPREPLY=( $( gzip -dc /var/lib/urpmi/synthesis.hdlist.* | \ awk -F'@' '/info/ {print $1}' | grep "^$cur" ) ) fi } [ "$have" ] && complete -F _urpmi urpmi # Mandrake urpmi.update completion # have urpmi.update && _urpmi_update() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} if [[ "$cur" == -* ]]; then # return list of available options COMPREPLY=( $( compgen -W '-a -c -d -f --curl --wget' -- $cur)) else # return list of available media _urpmi_media fi } [ "$have" ] && complete -F _urpmi_update urpmi.update # Mandrake urpmi.addmedia completion # have urpmi.addmedia && _urpmi_addmedia() { local cur i args COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} if [[ "$cur" == -* ]]; then # return list of available options COMPREPLY=( $( compgen -W '-c -h -f --wget --curl --update \ --distrib' -- $cur ) ) else # count number of mandatory args given sofar args=$COMP_CWORD for (( i=1; i < COMP_CWORD; i++ )); do if [[ "${COMP_WORDS[i]}" == -* ]]; then args=$(($args-1)) fi done case $args in 1) # return list of available media _urpmi_media ;; 2) # return list of available protocols COMPREPLY=( $( compgen -W 'file:// http:// \ ftp:// removable://' -- $cur ) ) ;; 3) # return word "with" COMPREPLY=( 'with' ) ;; esac fi } [ "$have" ] && complete -F _urpmi_addmedia urpmi.addmedia # Mandrake urpmi.removemedia completion # have urpmi.removemedia && _urpmi_removemedia() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} if [[ "$cur" == -* ]]; then # if word begins with a dash, return list of available options COMPREPLY=( $( compgen -W '-a -c' -- $cur ) ) else # elsewhere, return list of available media _urpmi_media fi } [ "$have" ] && complete -F _urpmi_removemedia urpmi.removemedia # Debian reportbug(1) completion # have reportbug && _reportbug() { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} case "$prev" in -f|--filename|-i|--include|--mta|-o|--output) _filedir return 0 ;; -B|--bts) COMPREPLY=( $( compgen -W "debian guug kde mandrake help" -- \ $cur )) return 0 ;; -e|--editor|--mua) COMP_WORDS=(COMP_WORDS[0] $cur) COMP_CWORD=1 _command return 0 ;; --mode) COMPREPLY=( $( compgen -W "novice standard expert" -- $cur ) ) return 0 ;; -S|--severity) COMPREPLY=( $( compgen -W "grave serious important normal \ minor wishlist" -- $cur ) ) return 0; ;; -u|--ui|--interface) COMPREPLY=( $( compgen -W "newt text gnome" -- $cur ) ) return 0 ;; -t|--type) COMPREPLY=( $( compgen -W "gnats debbugs" -- $cur ) ) return 0; ;; -T|--tags) COMPREPLY=( $( compgen -W "none patch security upstream sid \ woody potato sarge fixed" -- $cur ) ) return 0; ;; *) ;; esac COMPREPLY=($( compgen -W '-h --help -v --version -a --af -b \ --no-query-bts --query-bts -B --bts -c --configure \ --no-config-files --check-available -d --debug \ --no-check-available -e --editor --email -f \ --filename -g --gnupg -H --header -i --include -j \ --justification -l --ldap --no-ldap -L --list-cc -m \ --maintonly --mode --mua --mta --mutt -n --mh --nmh \ -o --output -p --print -P --pgp --proxy --http_proxy\ -q --quiet -Q --query-only --realname --report-quiet \ --reply-to --replyto -s --subject -S --severity \ --smtphost -t --type -T --tags --template -V -x \ --no-cc --package-version -z --no-compress \ --ui --interface -u \ wnpp boot-floppies kernel-image' -- $cur ) \ $( apt-cache pkgnames -- $cur ) ) _filedir return 0 } [ "$have" ] && complete -F _reportbug $filenames reportbug # Debian querybts(1) completion # have querybts && _querybts() { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} case "$prev" in -B|--bts) COMPREPLY=( $( compgen -W "debian guug kde mandrake help" -- \ $cur )) return 0 ;; -u|--ui|--interface) COMPREPLY=($( compgen -W "newt text gnome" -- $cur )) return 0 ;; *) ;; esac COMPREPLY=($( compgen -W '-h --help -v --version -A --archive \ -B --bts -l --ldap --no-ldap --proxy= --http_proxy= \ -s --source -w --web -u --ui --interface \ wnpp boot-floppies' -- $cur ) \ $( apt-cache pkgnames -- $cur ) ) } [ "$have" ] && complete -F _querybts $filenames querybts # update-alternatives completion # have update-alternatives && _update_alternatives() { installed_alternatives() { local admindir # find wich admin dir to use if [ -f /etc/debian_version ]; then admindir=/var/lib/dpkg/alternatives else admindir=/var/lib/rpm/alternatives fi for (( i=1; i < COMP_CWORD; i++ )); do if [[ "${COMP_WORDS[i]}" == --admindir ]]; then admindir=${COMP_WORDS[i+1]} break fi done COMPREPLY=( $( \ls $admindir | grep "^$cur" ) ) } local cur prev mode args COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} case "$prev" in --@(altdir|admindir)) _filedir -d return 0 ;; --@(help|version)) return 0 ;; esac # find wich mode to use and how many real args used so far for (( i=1; i < COMP_CWORD; i++ )); do if [[ "${COMP_WORDS[i]}" == --@(install|remove|auto|display|config) ]]; then mode=${COMP_WORDS[i]} args=$(($COMP_CWORD - i)) break fi done case $mode in --install) case $args in 1) _filedir ;; 2) installed_alternatives ;; 3) _filedir ;; esac ;; --remove) case $args in 1) installed_alternatives ;; 2) _filedir ;; esac ;; --auto) installed_alternatives ;; --display) installed_alternatives ;; --config) installed_alternatives ;; *) COMPREPLY=( $( compgen -W '--verbose --quiet --help --version \ --altdir --admindir' -- $cur ) \ $( compgen -W '--install --remove --auto --display \ --config' -- $cur ) ) esac } [ "$have" ] && complete -F _update_alternatives update-alternatives # Python completion # have python && _python() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} # first parameter on line a Python script? if [ $COMP_CWORD -eq 1 ] && [[ "$cur" != -* ]]; then _filedir '@(py|pyc|pyo)' fi return 0 } [ "$have" ] && complete -F _python $default python _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;}' $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' \ $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 $filenames ${list[@]} fi unset list[@] # source completion directory definitions if [ -d $BASH_COMPLETION_DIR -a -r $BASH_COMPLETION_DIR -a \ -x $BASH_COMPLETION_DIR ]; then for i in $BASH_COMPLETION_DIR/*; do [ -f $i -a -r $i ] && . $i done fi unset i # source user completion file [ $BASH_COMPLETION != ~/.bash_completion -a -r ~/.bash_completion ] \ && . ~/.bash_completion unset -f have unset UNAME RELEASE have default dirnames filenames nospace ### Local Variables: ### mode: shell-script ### End: