summaryrefslogtreecommitdiff
path: root/examples/complete
diff options
context:
space:
mode:
Diffstat (limited to 'examples/complete')
-rw-r--r--examples/complete/bashcc-1.0.1.tar.gzbin0 -> 4609 bytes
-rw-r--r--examples/complete/complete-examples495
-rw-r--r--examples/complete/complete.freebsd31
-rw-r--r--examples/complete/complete.gnu-longopt43
-rw-r--r--examples/complete/complete.ianmac433
-rw-r--r--examples/complete/complete2.ianmac271
6 files changed, 1273 insertions, 0 deletions
diff --git a/examples/complete/bashcc-1.0.1.tar.gz b/examples/complete/bashcc-1.0.1.tar.gz
new file mode 100644
index 0000000..d680435
--- /dev/null
+++ b/examples/complete/bashcc-1.0.1.tar.gz
Binary files differ
diff --git a/examples/complete/complete-examples b/examples/complete/complete-examples
new file mode 100644
index 0000000..baa97e3
--- /dev/null
+++ b/examples/complete/complete-examples
@@ -0,0 +1,495 @@
+#
+# Completion examples
+#
+
+#
+# This encapsulates the default bash completion code
+# call with the word to be completed as $1
+#
+# Since programmable completion does not use the bash default completions
+# or the readline default of filename completion when the compspec does
+# not generate any matches, this may be used as a `last resort' in a
+# completion function to mimic the default bash completion behavior.
+#
+_bash_def_completion ()
+{
+ local h t
+ COMPREPLY=()
+
+ # command substitution
+ if [[ "$1" == \$\(* ]]; then
+ t=${1#??}
+ COMPREPLY=( $(compgen -c -P '$(' $t) )
+ fi
+ # variables with a leading `${'
+ if [ ${#COMPREPLY[@]} -eq 0 ] && [[ "$1" == \$\{* ]]; then
+ t=${1#??}
+ COMPREPLY=( $(compgen -v -P '${' -S '}' $t) )
+ fi
+ # variables with a leading `$'
+ if [ ${#COMPREPLY[@]} -eq 0 ] && [[ "$1" == \$* ]]; then
+ t=${1#?}
+ COMPREPLY=( $(compgen -v -P '$' $t ) )
+ fi
+ # username expansion
+ if [ ${#COMPREPLY[@]} -eq 0 ] && [[ "$1" == ~* ]] && [[ "$1" != */* ]]; then
+ t=${1#?}
+ COMPREPLY=( $( compgen -u -P '~' $t ) )
+ fi
+ # hostname
+ if [ ${#COMPREPLY[@]} -eq 0 ] && [[ "$1" == *@* ]]; then
+ h=${1%%@*}
+ t=${1#*@}
+ COMPREPLY=( $( compgen -A hostname -P "${h}@" $t ) )
+ fi
+ # glob pattern
+ if [ ${#COMPREPLY[@]} -eq 0 ]; then
+ # sh-style glob pattern
+ if [[ $1 == *[*?[]* ]]; then
+ COMPREPLY=( $( compgen -G "$1" ) )
+ # ksh-style extended glob pattern - must be complete
+ elif shopt -q extglob && [[ $1 == *[?*+\!@]\(*\)* ]]; then
+ COMPREPLY=( $( compgen -G "$1" ) )
+ fi
+ fi
+
+ # final default is filename completion
+ if [ ${#COMPREPLY[@]} -eq 0 ]; then
+ COMPREPLY=( $(compgen -f "$1" ) )
+ fi
+}
+
+#
+# Return 1 if $1 appears to contain a redirection operator. Handles backslash
+# quoting (barely).
+#
+_redir_op()
+{
+ case "$1" in
+ *\\'[\<\>]'*) return 1;;
+ *[\<\>]*) return 0;;
+ *) return 1;;
+ esac
+}
+
+
+# _redir_test tests the current word ($1) and the previous word ($2) for
+# redirection operators and does filename completion on the current word
+# if either one contains a redirection operator
+_redir_test()
+{
+ if _redir_op "$1" ; then
+ COMPREPLY=( $( compgen -f "$1" ) )
+ return 0
+ elif _redir_op "$2" ; then
+ COMPREPLY=( $( compgen -f "$1" ) )
+ return 0
+ fi
+ return 1
+}
+
+# optional, but without this you can't use extended glob patterns
+shopt -s extglob
+
+#
+# Easy ones for the shell builtins
+#
+# nothing for: alias, break, continue, dirs, echo, eval, exit, getopts,
+# let, logout, popd, printf, pwd, return, shift, suspend, test, times,
+# umask
+#
+
+complete -f -- . source
+complete -A enabled builtin
+complete -d cd
+
+# this isn't exactly right yet -- needs to skip shell functions and
+# do $PATH lookup (or do compgen -c and filter out matches that also
+# appear in compgen -A function)
+complete -c command
+
+# could add -S '=', but that currently screws up because readline appends
+# a space unconditionally
+
+complete -v export local readonly
+complete -A helptopic help # currently same as builtins
+
+complete -d pushd
+
+complete -A shopt shopt
+
+complete -c type
+
+complete -a unalias
+complete -v unset
+
+#
+# Job control builtins: fg, bg, disown, kill, wait
+# kill not done yet
+#
+
+complete -A stopped -P '%' bg
+complete -j -P '%' fg jobs disown
+
+# this is not quite right at this point
+
+_wait_func ()
+{
+ local cur
+ cur=${COMP_WORDS[COMP_CWORD]}
+
+ case "$cur" in
+ %*) COMPREPLY=( $(compgen -A running -P '%' ${cur#?} ) ) ;;
+ [0-9]*) COMPREPLY=( $(jobs -p | grep ^${cur}) ) ;;
+ *) COMPREPLY=( $(compgen -A running -P '%') $(jobs -p) )
+ ;;
+ esac
+}
+complete -F _wait_func wait
+
+#
+# more complicated things, several as yet unimplemented
+#
+
+#complete -F _bind_func bind
+
+_declare_func()
+{
+ local cur prev nflag opts
+
+ cur=${COMP_WORDS[COMP_CWORD]}
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ COMPREPLY=()
+ if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then
+ COMPREPLY=(-a -f -F -i -p -r -t -x)
+ return 0;
+ fi
+ if [[ $cur == '+' ]]; then
+ COMPREPLY=(+i +t +x)
+ return 0;
+ fi
+ if [[ $prev == '-p' ]]; then
+ COMPREPLY=( $(compgen -v $cur) )
+ return 0;
+ fi
+ return 1
+}
+complete -F _declare_func declare typeset
+
+_enable_func()
+{
+ local cur prev nflag opts
+
+ cur=${COMP_WORDS[COMP_CWORD]}
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ COMPREPLY=()
+ if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then
+ COMPREPLY=(-a -d -f -n -p -s)
+ return 0;
+ fi
+ if [[ $prev == '-f' ]]; then
+ COMPREPLY=( $( compgen -f $cur ) )
+ return 0;
+ fi
+ for opts in "${COMP_WORDS[@]}" ; do
+ if [[ $opts == -*n* ]]; then nflag=1; fi
+ done
+
+ if [ -z "$nflag" ] ; then
+ COMPREPLY=( $( compgen -A enabled $cur ) )
+ else
+ COMPREPLY=( $( compgen -A disabled $cur ) )
+ fi
+ return 0;
+}
+complete -F _enable_func enable
+
+_exec_func()
+{
+ local cur prev
+
+ cur=${COMP_WORDS[COMP_CWORD]}
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then
+ COMPREPLY=(-a -c -l)
+ return 0;
+ fi
+ if [[ $prev != -*a* ]]; then
+ COMPREPLY=( $( compgen -c $cur ) )
+ return 0
+ fi
+ return 1;
+}
+complete -F _exec_func exec
+
+_fc_func()
+{
+ local cur prev
+
+ cur=${COMP_WORDS[COMP_CWORD]}
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then
+ COMPREPLY=(-e -n -l -r -s)
+ return 0;
+ fi
+ if [[ $prev == -*e ]]; then
+ COMPREPLY=( $(compgen -c $cur) )
+ return 0
+ fi
+ return 1
+}
+complete -F _fc_func fc
+
+_hash_func()
+{
+ local cur prev
+
+ cur=${COMP_WORDS[COMP_CWORD]}
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then
+ COMPREPLY=(-p -r -t)
+ return 0;
+ fi
+
+ if [[ $prev == '-p' ]]; then
+ COMPREPLY=( $( compgen -f $cur ) )
+ return 0;
+ fi
+ COMPREPLY=( $( compgen -c $cur ) )
+ return 0
+}
+complete -F _hash_func hash
+
+_history_func()
+{
+ local cur prev
+
+ cur=${COMP_WORDS[COMP_CWORD]}
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ COMPREPLY=()
+ if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then
+ COMPREPLY=(-a -c -d -n -r -w -p -s)
+ return 0;
+ fi
+ if [[ $prev == -[anrw] ]]; then
+ COMPREPLY=( $( compgen -f $cur ) )
+ fi
+ return 0
+}
+complete -F _history_func history
+
+#complete -F _read_func read
+
+_set_func ()
+{
+ local cur prev
+
+ cur=${COMP_WORDS[COMP_CWORD]}
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ COMPREPLY=()
+
+ _redir_test "$cur" "$prev" && return 0;
+
+ if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then
+ COMPREPLY=(-a -b -e -f -k -m -n -o -p -t -u -v -x -B -C -H -P --)
+ return 0;
+ fi
+ if [[ $cur == '+' ]]; then
+ COMPREPLY=(+a +b +e +f +k +m +n +o +p +t +u +v +x +B +C +H +P)
+ return 0;
+ fi
+ if [[ $prev == [+-]o ]]; then
+ COMPREPLY=( $(compgen -A setopt $cur) )
+ return 0;
+ fi
+ return 1;
+}
+complete -F _set_func set
+
+_trap_func ()
+{
+ local cur
+ cur=${COMP_WORDS[COMP_CWORD]}
+
+ if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then
+ COMPREPLY=(-l -p)
+ return 0;
+ fi
+ COMPREPLY=( $( compgen -A signal ${cur}) )
+ return 0
+}
+complete -F _trap_func trap
+
+#
+# meta-completion (completion for complete/compgen)
+#
+_complete_meta_func()
+{
+ local cur prev cmd
+ COMPREPLY=()
+
+ cmd=$1
+
+ cur=${COMP_WORDS[COMP_CWORD]}
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ _redir_test "$cur" "$prev" && return 0;
+
+ if (( $COMP_CWORD <= 1 )) || [[ "$cur" == '-' ]]; then
+ case "$cmd" in
+ complete) COMPREPLY=(-a -b -c -d -e -f -j -k -s -v -u -r -p -A -G -W -P -S -X -F -C);;
+ compgen) COMPREPLY=(-a -b -c -d -e -f -j -k -s -v -u -A -G -W -P -S -X -F -C);;
+ esac
+ return 0
+ fi
+
+ if [[ $prev == -A ]]; then
+ COMPREPLY=(alias arrayvar binding builtin command directory \
+disabled enabled export file 'function' helptopic hostname job keyword \
+running service setopt shopt signal stopped variable)
+ return 0
+ elif [[ $prev == -F ]]; then
+ COMPREPLY=( $( compgen -A function $cur ) )
+ elif [[ $prev == -C ]]; then
+ COMPREPLY=( $( compgen -c $cur ) )
+ else
+ COMPREPLY=( $( compgen -c $cur ) )
+ fi
+ return 0
+}
+complete -F _complete_meta_func complete compgen
+
+#
+# some completions for shell reserved words
+#
+#complete -c -k time do if then else elif '{'
+
+#
+# external commands
+#
+
+complete -e printenv
+
+complete -c nohup exec nice eval trace truss strace sotruss gdb
+
+_make_targets ()
+{
+ 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
+ case "$prev" in
+ -*f) COMPREPLY=( $(compgen -f $cur ) ); return 0;;
+ esac
+
+ # if we want an option, return the possible posix options
+ case "$cur" in
+ -) COMPREPLY=(-e -f -i -k -n -p -q -r -S -s -t); return 0;;
+ esac
+
+ # make reads `makefile' before `Makefile'
+ # GNU make reads `GNUmakefile' before all other makefiles, but we
+ # check that we're completing `gmake' before checking for it
+ if [ -f GNUmakefile ] && [ ${COMP_WORDS[0]} == gmake ]; then
+ mdef=GNUmakefile
+ elif [ -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}' | tr -s ' ' '\012' | sort -u | eval $gcmd ) )
+}
+complete -F _make_targets -X '+($*|*.[cho])' make gmake pmake
+
+_umount_func ()
+{
+ COMPREPLY=( $(mount | awk '{print $1}') )
+}
+complete -F _umount_func umount
+
+_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
+
+complete -W '"${GROUPS[@]}"' newgrp
+
+complete -f chown ln more cat
+complete -d mkdir rmdir
+complete -f strip
+
+complete -f -X '*.gz' gzip
+complete -f -X '*.bz2' bzip2
+complete -f -X '*.Z' compress
+complete -f -X '!*.+(gz|tgz|Gz)' gunzip gzcat zcat zmore
+complete -f -X '!*.Z' uncompress zmore zcat
+complete -f -X '!*.bz2' bunzip2 bzcat
+complete -f -X '!*.zip' unzip
+complete -f -X '!*.+(gif|jpg|jpeg|GIF|JPG|JPEG|bmp)' xv
+
+complete -f -X '!*.pl' perl perl5
+
+complete -A hostname rsh telnet rlogin ftp ping xping host traceroute nslookup
+complete -A hostname rxterm rxterm3 rxvt2
+
+complete -u su
+complete -g newgrp groupdel groupmod
+
+complete -f -X '!*.+(ps|PS)' gs gv ghostview psselect pswrap
+complete -f -X '!*.+(dvi|DVI)' dvips xdvi dviselect dvitype catdvi
+complete -f -X '!*.+(pdf|PDF)' acroread4
+complete -f -X '!*.texi*' makeinfo texi2dvi texi2html
+complete -f -X '!*.+(tex|TEX)' tex latex slitex
+
+complete -f -X '!*.+(mp3|MP3)' mpg123
+complete -f -X '!*.+(htm|html)' links w3m lynx
+
+#
+# other possibilities, left as exercises
+#
+#complete -F _find_func find
+#complete -F _man_func man
+#complete -F _stty_func stty
diff --git a/examples/complete/complete.freebsd b/examples/complete/complete.freebsd
new file mode 100644
index 0000000..7f6f4c2
--- /dev/null
+++ b/examples/complete/complete.freebsd
@@ -0,0 +1,31 @@
+#Date: Wed, 31 Jan 2001 12:53:56 -0800
+#From: Aaron Smith <aaron@mutex.org>
+#To: freebsd-ports@freebsd.org
+#Subject: useful bash completion function for pkg commands
+#Message-ID: <20010131125356.G52003@gelatinous.com>
+
+#hi all. i just wanted to share this bash completion function i wrote that
+#completes package names for pkg_info and pkg_delete. i find this a great
+#help when dealing with port management. programmed completion requires
+#bash-2.04.
+
+_pkg_func ()
+{
+ local cur
+
+ cur=${COMP_WORDS[COMP_CWORD]}
+
+ if [[ $cur == '-' ]]; then
+ if [[ ${COMP_WORDS[0]} == 'pkg_info' ]]; then
+ COMPREPLY=(-a -c -d -D -i -k -r -R -p -L -q -I -m -v -e -l)
+ return 0;
+ elif [[ ${COMP_WORDS[0]} == 'pkg_delete' ]]; then
+ COMPREPLY=(-v -D -d -n -f -p)
+ return 0;
+ fi
+ fi
+
+ COMPREPLY=( $(compgen -d /var/db/pkg/$cur | sed sN/var/db/pkg/NNg) )
+ return 0
+}
+complete -F _pkg_func pkg_delete pkg_info
diff --git a/examples/complete/complete.gnu-longopt b/examples/complete/complete.gnu-longopt
new file mode 100644
index 0000000..c55b436
--- /dev/null
+++ b/examples/complete/complete.gnu-longopt
@@ -0,0 +1,43 @@
+#
+# Originally from:
+#
+#Message-ID: <3B13EC65.179451AE@wanadoo.fr>
+#Date: Tue, 29 May 2001 20:37:25 +0200
+#From: Manu Rouat <emmanuel.rouat@wanadoo.fr>
+#Subject: [bash] Universal command options completion?
+#
+#
+#In the recent versions of bash (after 2.04) programmable
+#completion is available. A useful completion function
+#is , for a particular command, to enumerate all flags
+#that can be used in the command. Now, most GNU unix
+#commands have so-called 'long options' for example:
+#
+#ls --color=always --no-group --size
+#
+#and these are all listed when you issue a '--help' flag.
+#So the idea is to use that, then parse the output of the
+#'--help' and reinject this to compgen. The basis of the
+#following 'universal' completion funtion was the _configure_func'
+#written by Ian McDonnald (or is it Chet Ramey ?)
+#A dedicated function will always be better, but this is quite
+#convenient. I chose to use 'long options' because they are
+#easy to parse and explicit too (it's the point I guess...)
+#Lots of room for improvement !
+
+_longopt_func ()
+{
+ case "$2" in
+ -*) ;;
+ *) return ;;
+ esac
+
+ case "$1" in
+ \~*) eval cmd=$1 ;;
+ *) cmd="$1" ;;
+ esac
+ COMPREPLY=( $("$cmd" --help | sed -e '/--/!d' -e 's/.*--\([^ ]*\).*/--\1/'| \
+grep ^"$2" |sort -u) )
+}
+
+complete -o default -F _longopt_func ldd wget bash id info # some examples that work
diff --git a/examples/complete/complete.ianmac b/examples/complete/complete.ianmac
new file mode 100644
index 0000000..2af9fc7
--- /dev/null
+++ b/examples/complete/complete.ianmac
@@ -0,0 +1,433 @@
+#####
+#To: chet@po.cwru.edu, sarahmckenna@lucent.com
+#Message-Id: <slrn8mqioc.msb.ian@lovelorn.linuxcare.com>
+#Posted-To: comp.unix.shell, gnu.bash.bug
+#Subject: bash 2.04 programmable completion examples
+#Reply-To: ian@linuxcare.com, ian@caliban.org
+#Summary: examples of programmable completion for bash 2.04
+#Date: Thu, 13 Jul 2000 00:52:33 -0400 (EDT)
+#From: ianmacd@linuxcare.com (Ian Macdonald)
+#####
+
+#########################################################################
+# Turn on extended globbing
+shopt -s extglob
+
+# 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 chown ln strip
+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
+complete -f -X '!*.+(mp3|MP3)' mpg123
+
+# 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
+
+# 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
+ if [ "${cur:0:1}" = "-" ]; then return 0; fi
+
+ # first parameter on line or first since an option?
+ if [ $COMP_CWORD -eq 1 ] || [ "${prev:0:1}" = "-" ]; then
+ case "$cur" in
+ [a-zA-Z]*.*)
+ 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
+ return 0
+ ;;
+ *)
+ COMPREPLY=( $( compgen -u $cur -S '.' ) )
+ return 0
+ ;;
+ esac
+ else
+ COMPREPLY=( $( compgen -f $cur ) )
+ fi
+
+ return 0
+}
+complete -F _chown 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]}
+
+ case "$cur" in
+ *:*)
+ COMPREPLY=( $( /usr/sbin/showmount -e --no-headers ${cur%%:*} |\
+ grep ^${cur#*:} | awk '{print $1}'))
+ return 0
+ ;;
+ *)
+ COMPREPLY=( $( awk '{if ($2 ~ /\//) print $2}' /etc/fstab | \
+ grep ^$cur ))
+ return 0
+ ;;
+ esac
+}
+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=($( lsmod | awk '{if (NR != 1 && $1 ~ /^'$cur'/) print $1}'))
+ return 0
+}
+complete -F _rmmod rmmod
+
+# Linux insmod(1) completion. This completes on a list of all
+# available modules for the version of the kernel currently running.
+#
+_insmod ()
+{
+ local cur modpath
+
+ COMPREPLY=()
+ cur=${COMP_WORDS[COMP_CWORD]}
+ modpath=/lib/modules/`uname -r`
+
+ COMPREPLY=($( ls -R $modpath | sed -ne 's/^\('$cur'.*\)\.o$/\1/p'))
+ return 0
+}
+complete -F _insmod insmod depmod 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
+
+ COMPREPLY=()
+ cur=${COMP_WORDS[COMP_CWORD]}
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ case "$prev" in
+ [0-9lmn])
+ COMPREPLY=($( slocate -ql 0 -r '/man/man'$prev'/'$cur | \
+ sed -ne 's/^.*\/\('$cur'[^.\/]*\)\..*$/\1/p' ))
+ return 0
+ ;;
+ *)
+ COMPREPLY=($( slocate -ql 0 -r '/man/man./'$cur | \
+ sed -ne 's/^.*\/\('$cur'[^.\/]*\)\..*$/\1/p' ))
+ return 0
+ ;;
+ esac
+}
+complete -F _man 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]}
+
+ case "$prev" in
+ -[A-Z0-9]*)
+ # get a list of processes (the first sed evaluation
+ # takes care of swapped out processes, the second
+ # takes care of getting the basename of the process)
+ COMPREPLY=( $( ps ahx | awk '{if ($5 ~ /^'$cur'/) print $5}' | \
+ sed -e 's#[]\[]##g' -e 's#^.*/##' ))
+ return 0
+ ;;
+ esac
+
+ # 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 | \
+ awk '{if ($5 ~ /^'$cur'/) print $5}' | \
+ sed -e 's#[]\[]##g' -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 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). Very basic.
+#
+_ipsec ()
+{
+ local cur
+
+ COMPREPLY=()
+ cur=${COMP_WORDS[COMP_CWORD]}
+
+ COMPREPLY=( $( compgen -W 'auto barf eroute klipsdebug look manual \
+ pluto ranbits rsasigkey setup showdefaults \
+ showhostkey spi spigrp tncfg whack' $cur ))
+}
+complete -F _ipsec ipsec
+#########################################################################
diff --git a/examples/complete/complete2.ianmac b/examples/complete/complete2.ianmac
new file mode 100644
index 0000000..6fb0a96
--- /dev/null
+++ b/examples/complete/complete2.ianmac
@@ -0,0 +1,271 @@
+#####
+#From: ian@linuxcare.com (Ian Macdonald)
+#Newsgroups: comp.unix.shell
+#Subject: More bash 2.04 completions
+#Date: 12 Aug 2000 09:53:40 GMT
+#Organization: Linuxcare, Inc.
+#Lines: 274
+#Message-ID: <slrn8pa7l2.jgm.ian@lovelorn.linuxcare.com>
+#Reply-To: ian@linuxcare.com
+#####
+
+# Turn on extended globbing
+shopt -s extglob
+
+# 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:0:1}" = "-" ]; then
+ COMPREPLY=( $( compgen -W 'add admin checkout commit diff \
+ export history import log rdiff release remove rtag status \
+ tag update' $cur ))
+ else
+ COMPREPLY=( $( compgen -f $cur ))
+ fi
+ return 0
+}
+complete -F _cvs cvs
+
+# rpm(8) completion. This isn't exhaustive yet, but still provides
+# quite a lot of functionality.
+#
+_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
+ }
+
+ local cur cur_nodash prev
+
+ COMPREPLY=()
+ cur=${COMP_WORDS[COMP_CWORD]}
+ cur_nodash=${cur#-}
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ if [ $COMP_CWORD = 1 ]; then
+ # first parameter on line
+ case "$cur" in
+ -b*)
+ COMPREPLY=( $( compgen -W 'ba bb bc bi bl bp bs' \
+ $cur_nodash ) )
+ dashify
+ return 0
+ ;;
+ -t*)
+ COMPREPLY=( $( compgen -W 'ta tb tc ti tl tp ts' \
+ $cur_nodash ) )
+ dashify
+ return 0
+ ;;
+ --*)
+ COMPREPLY=( $( compgen -W 'help version initdb \
+ checksig recompile rebuild resign addsign rebuilddb \
+ showrc setperms setgids' ${cur_nodash#-} ) )
+ dashify;
+ return 0
+ ;;
+ *)
+ COMPREPLY=( $( compgen -W 'b e F i q t U V' \
+ $cur_nodash ) )
+ dashify
+ return 0
+ ;;
+ esac
+ fi
+
+ case "${COMP_WORDS[1]}" in
+ -[iFU]*)
+ # 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' ${cur_nodash#-} ))
+ dashify;
+ # return if $cur is an option
+ [ "${cur:0:1}" = "-" ] && return 0
+ # add a list of RPMS to possible completions
+ COMPREPLY=( ${COMPREPLY[@]} $( compgen -G $cur\*.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' \
+ ${cur_nodash#-} ) )
+ dashify;
+ # return if $cur is an option
+ [ "${cur:0:1}" = "-" ] && return 0
+ # add a list of RPMS to possible completions
+ COMPREPLY=( ${COMPREPLY[@]} $( compgen -G $cur\*.rpm ) )
+ return 0
+ ;;
+ -*f)
+ # standard filename completion
+ COMPREPLY=( $( compgen -f $cur ) )
+ return 0
+ ;;
+ -e)
+ # complete on list of relevant options
+ COMPREPLY=( $( compgen -W 'allmatches noscripts notriggers \
+ nodeps test' ${cur_nodash#-} ) )
+ dashify;
+ # return if $cur is an option
+ [ "${cur:0:1}" = "-" ] && return 0
+ # complete on basename of installed RPMs
+ COMPREPLY=( $( rpm -qa | \
+ sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9.]\+$/\1/p' ) )
+ return 0
+ ;;
+ -qa*)
+ # 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' ${cur_nodash#-} ) )
+ dashify;
+ 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' ${cur_nodash#-} ) )
+ dashify;
+ # return if $cur is an option
+ [ "${cur:0:1}" = "-" ] && return 0
+ # add a list of RPMS to possible completions
+ COMPREPLY=( ${COMPREPLY[@]} $( rpm -qa | \
+ sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9.]\+$/\1/p' ) )
+ return 0
+ ;;
+ -[Vy]*)
+ # complete on list of relevant options
+ COMPREPLY=( $( compgen -W 'root rcfile dbpath nodeps nofiles \
+ noscripts nomd5 nopgp' ${cur_nodash#-} ) )
+ dashify;
+ # return if $cur is an option
+ [ "${cur:0:1}" = "-" ] && return 0
+ # add a list of RPMS to possible completions
+ COMPREPLY=( ${COMPREPLY[@]} $( rpm -qa | \
+ sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9.]\+$/\1/p' ) )
+ return 0
+ ;;
+ -b*)
+ # complete on list of relevant options
+ COMPREPLY=( $( compgen -W 'short-circuit timecheck clean \
+ rmsource test sign buildroot target buildarch buildos' \
+ ${cur_nodash#-} ) )
+ dashify;
+ # return if $cur is an option
+ [ "${cur:0:1}" = "-" ] && return 0
+ # complete on .spec files
+ COMPREPLY=( $( compgen -G $cur\*.spec ) )
+ return 0
+ ;;
+ -t*)
+ # complete on list of relevant options
+ COMPREPLY=( $( compgen -W 'short-circuit timecheck clean \
+ rmsource test sign buildroot target buildarch buildos' \
+ ${cur_nodash#-} ) )
+ dashify;
+ # return if $cur is an option
+ [ "${cur:0:1}" = "-" ] && return 0
+ # complete on .tar.gz files
+ COMPREPLY=( $( compgen -G $cur\*.tar.gz ) )
+ return 0
+ ;;
+ --re@(build|compile))
+ # complete on source RPMs
+ COMPREPLY=( $( compgen -G $cur\*.src.rpm ) )
+ return 0
+ ;;
+ --@(checksig|@(re|add)sign))
+ # complete on RPMs
+ COMPREPLY=( $( compgen -G $cur\*.rpm ) )
+ return 0
+ ;;
+ --set@(perms|gids))
+ # complete on installed RPMs
+ COMPREPLY=( ${COMPREPLY[@]} $( rpm -qa | \
+ sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9.]\+$/\1/p' ) )
+ return 0
+ ;;
+ esac
+}
+complete -F _rpm rpm
+
+# 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
+}
+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
+}
+complete -F _chkconfig chkconfig
+###