]> git.ipfire.org Git - thirdparty/bash.git/blob - examples/complete/complete.ianmac
Imported from ../bash-2.05.tar.gz.
[thirdparty/bash.git] / examples / complete / complete.ianmac
1 #####
2 #To: chet@po.cwru.edu, sarahmckenna@lucent.com
3 #Message-Id: <slrn8mqioc.msb.ian@lovelorn.linuxcare.com>
4 #Posted-To: comp.unix.shell, gnu.bash.bug
5 #Subject: bash 2.04 programmable completion examples
6 #Reply-To: ian@linuxcare.com, ian@caliban.org
7 #Summary: examples of programmable completion for bash 2.04
8 #Date: Thu, 13 Jul 2000 00:52:33 -0400 (EDT)
9 #From: ianmacd@linuxcare.com (Ian Macdonald)
10 #####
11
12 #########################################################################
13 # Turn on extended globbing
14 shopt -s extglob
15
16 # A lot of the following one-liners were taken directly from the
17 # completion examples provided with the bash 2.04 source distribution
18
19 # Make directory commands see only directories
20 complete -d cd mkdir rmdir pushd
21
22 # Make file commands see only files
23 complete -f cat less more chown ln strip
24 complete -f -X '*.gz' gzip
25 complete -f -X '*.Z' compress
26 complete -f -X '!*.+(Z|gz|tgz|Gz)' gunzip zcat zmore
27 complete -f -X '!*.Z' uncompress zmore zcat
28 complete -f -X '!*.+(gif|jpg|jpeg|GIF|JPG|bmp)' ee xv
29 complete -f -X '!*.+(ps|PS|ps.gz)' gv
30 complete -f -X '!*.+(dvi|DVI)' dvips xdvi dviselect dvitype
31 complete -f -X '!*.+(pdf|PDF)' acroread xpdf
32 complete -f -X '!*.texi*' makeinfo texi2dvi texi2html
33 complete -f -X '!*.+(tex|TEX)' tex latex slitex
34 complete -f -X '!*.+(mp3|MP3)' mpg123
35
36 # kill sees only signals
37 complete -A signal kill -P '%'
38
39 # user commands see only users
40 complete -u finger su usermod userdel passwd
41
42 # bg completes with stopped jobs
43 complete -A stopped -P '%' bg
44
45 # other job commands
46 complete -j -P '%' fg jobs disown
47
48 # network commands complete with hostname
49 complete -A hostname ssh rsh telnet rlogin ftp ping fping host traceroute \
50 nslookup
51
52 # export and others complete with shell variables
53 complete -v export local readonly unset
54
55 # set completes with set options
56 complete -A setopt set
57
58 # shopt completes with shopt options
59 complete -A shopt shopt
60
61 # helptopics
62 complete -A helptopic help
63
64 # unalias completes with aliases
65 complete -a unalias
66
67 # various commands complete with commands
68 complete -c command type nohup exec nice eval strace gdb
69
70 # bind completes with readline bindings (make this more intelligent)
71 complete -A binding bind
72
73 # Now we get to the meat of the file, the functions themselves. Some
74 # of these are works in progress. Most assume GNU versions of the
75 # tools in question and may require modifications for use on vanilla
76 # UNIX systems.
77 #
78 # A couple of functions may have non-portable, Linux specific code in
79 # them, but this will be noted where applicable
80
81
82 # GNU chown(1) completion. This should be expanded to allow the use of
83 # ':' as well as '.' as the user.group separator.
84 #
85 _chown ()
86 {
87 local cur prev user group
88
89 COMPREPLY=()
90 cur=${COMP_WORDS[COMP_CWORD]}
91 prev=${COMP_WORDS[COMP_CWORD-1]}
92
93 # do not attempt completion if we're specifying an option
94 if [ "${cur:0:1}" = "-" ]; then return 0; fi
95
96 # first parameter on line or first since an option?
97 if [ $COMP_CWORD -eq 1 ] || [ "${prev:0:1}" = "-" ]; then
98 case "$cur" in
99 [a-zA-Z]*.*)
100 user=${cur%.*}
101 group=${cur#*.}
102 COMPREPLY=( $( awk 'BEGIN {FS=":"} \
103 {if ($1 ~ /^'$group'/) print $1}' \
104 /etc/group ) )
105 for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
106 COMPREPLY[i]=$user.${COMPREPLY[i]}
107 done
108 return 0
109 ;;
110 *)
111 COMPREPLY=( $( compgen -u $cur -S '.' ) )
112 return 0
113 ;;
114 esac
115 else
116 COMPREPLY=( $( compgen -f $cur ) )
117 fi
118
119 return 0
120 }
121 complete -F _chown chown
122
123 # umount(8) completion. This relies on the mount point being the third
124 # space-delimited field in the output of mount(8)
125 #
126 _umount ()
127 {
128 local cur
129
130 COMPREPLY=()
131 cur=${COMP_WORDS[COMP_CWORD]}
132
133 # could rewrite the cut | grep to be a sed command, but this is
134 # clearer and doesn't result in much overhead
135 COMPREPLY=( $( mount | cut -d' ' -f 3 | grep ^$cur) )
136 return 0
137 }
138 complete -F _umount umount
139
140 # GID completion. This will get a list of all valid group names from
141 # /etc/group and should work anywhere.
142 #
143 _gid_func ()
144 {
145 local cur
146
147 COMPREPLY=()
148 cur=${COMP_WORDS[COMP_CWORD]}
149 COMPREPLY=( $( awk 'BEGIN {FS=":"} {if ($1 ~ /^'$cur'/) print $1}' \
150 /etc/group ) )
151 return 0
152 }
153 complete -F _gid_func groupdel groupmod
154
155 # mount(8) completion. This will pull a list of possible mounts out of
156 # /etc/fstab, unless the word being completed contains a ':', which
157 # would indicate the specification of an NFS server. In that case, we
158 # query the server for a list of all available exports and complete on
159 # that instead.
160 #
161 _mount ()
162
163 { local cur
164
165 COMPREPLY=()
166 cur=${COMP_WORDS[COMP_CWORD]}
167
168 case "$cur" in
169 *:*)
170 COMPREPLY=( $( /usr/sbin/showmount -e --no-headers ${cur%%:*} |\
171 grep ^${cur#*:} | awk '{print $1}'))
172 return 0
173 ;;
174 *)
175 COMPREPLY=( $( awk '{if ($2 ~ /\//) print $2}' /etc/fstab | \
176 grep ^$cur ))
177 return 0
178 ;;
179 esac
180 }
181 complete -F _mount mount
182
183 # Linux rmmod(1) completion. This completes on a list of all currently
184 # installed kernel modules.
185 #
186 _rmmod ()
187 {
188 local cur
189
190 COMPREPLY=()
191 cur=${COMP_WORDS[COMP_CWORD]}
192
193 COMPREPLY=($( lsmod | awk '{if (NR != 1 && $1 ~ /^'$cur'/) print $1}'))
194 return 0
195 }
196 complete -F _rmmod rmmod
197
198 # Linux insmod(1) completion. This completes on a list of all
199 # available modules for the version of the kernel currently running.
200 #
201 _insmod ()
202 {
203 local cur modpath
204
205 COMPREPLY=()
206 cur=${COMP_WORDS[COMP_CWORD]}
207 modpath=/lib/modules/`uname -r`
208
209 COMPREPLY=($( ls -R $modpath | sed -ne 's/^\('$cur'.*\)\.o$/\1/p'))
210 return 0
211 }
212 complete -F _insmod insmod depmod modprobe
213
214 # man(1) completion. This relies on the security enhanced version of
215 # GNU locate(1). UNIX variants having non-numeric man page sections
216 # other than l, m and n should add the appropriate sections to the
217 # first clause of the case statement.
218 #
219 # This is Linux specific, in that 'man <section> <page>' is the
220 # expected syntax. This allows one to do something like
221 # 'man 3 str<tab>' to obtain a list of all string handling syscalls on
222 # the system.
223 #
224 _man ()
225 {
226 local cur prev
227
228 COMPREPLY=()
229 cur=${COMP_WORDS[COMP_CWORD]}
230 prev=${COMP_WORDS[COMP_CWORD-1]}
231
232 case "$prev" in
233 [0-9lmn])
234 COMPREPLY=($( slocate -ql 0 -r '/man/man'$prev'/'$cur | \
235 sed -ne 's/^.*\/\('$cur'[^.\/]*\)\..*$/\1/p' ))
236 return 0
237 ;;
238 *)
239 COMPREPLY=($( slocate -ql 0 -r '/man/man./'$cur | \
240 sed -ne 's/^.*\/\('$cur'[^.\/]*\)\..*$/\1/p' ))
241 return 0
242 ;;
243 esac
244 }
245 complete -F _man man
246
247 # Linux killall(1) completion. This wouldn't be much use on, say,
248 # Solaris, where killall does exactly that: kills ALL processes.
249 #
250 # This could be improved. For example, it currently doesn't take
251 # command line options into account
252 #
253 _killall ()
254 {
255 local cur prev
256
257 COMPREPLY=()
258 cur=${COMP_WORDS[COMP_CWORD]}
259 prev=${COMP_WORDS[COMP_CWORD-1]}
260
261 case "$prev" in
262 -[A-Z0-9]*)
263 # get a list of processes (the first sed evaluation
264 # takes care of swapped out processes, the second
265 # takes care of getting the basename of the process)
266 COMPREPLY=( $( ps ahx | awk '{if ($5 ~ /^'$cur'/) print $5}' | \
267 sed -e 's#[]\[]##g' -e 's#^.*/##' ))
268 return 0
269 ;;
270 esac
271
272 # first parameter can be either a signal or a process
273 if [ $COMP_CWORD -eq 1 ]; then
274 # standard signal completion is rather braindead, so we need
275 # to hack around to get what we want here, which is to
276 # complete on a dash, followed by the signal name minus
277 # the SIG prefix
278 COMPREPLY=( $( compgen -A signal SIG${cur#-} ))
279 for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
280 COMPREPLY[i]=-${COMPREPLY[i]#SIG}
281 done
282 fi
283
284 # get processes, adding to signals if applicable
285 COMPREPLY=( ${COMPREPLY[*]} $( ps ahx | \
286 awk '{if ($5 ~ /^'$cur'/) print $5}' | \
287 sed -e 's#[]\[]##g' -e 's#^.*/##' ))
288 return 0
289 }
290 complete -F _killall killall
291
292 # GNU find(1) completion. This makes heavy use of ksh style extended
293 # globs and contains Linux specific code for completing the parameter
294 # to the -fstype option.
295 #
296 _find ()
297 {
298 local cur prev
299
300 COMPREPLY=()
301 cur=${COMP_WORDS[COMP_CWORD]#-}
302 prev=${COMP_WORDS[COMP_CWORD-1]}
303
304 case "$prev" in
305 -@(max|min)depth)
306 COMPREPLY=( $( compgen -W '0 1 2 3 4 5 6 7 8 9' ) )
307 return 0
308 ;;
309 -?(a)newer|-fls|-fprint?(0|f))
310 COMPREPLY=( $( compgen -f $cur ) )
311 return 0
312 ;;
313 -fstype)
314 # this is highly non-portable (the option to -d is a tab)
315 COMPREPLY=( $( cut -d' ' -f 2 /proc/filesystems | grep ^$cur ) )
316 return 0
317 ;;
318 -gid)
319 COMPREPLY=( $( awk 'BEGIN {FS=":"} \
320 {if ($3 ~ /^'$cur'/) print $3}' /etc/group ) )
321 return 0
322 ;;
323 -group)
324 COMPREPLY=( $( awk 'BEGIN {FS=":"} \
325 {if ($1 ~ /^'$cur'/) print $1}' /etc/group ) )
326 return 0
327 ;;
328 -?(x)type)
329 COMPREPLY=( $( compgen -W 'b c d p f l s' $cur ) )
330 return 0
331 ;;
332 -uid)
333 COMPREPLY=( $( awk 'BEGIN {FS=":"} \
334 {if ($3 ~ /^'$cur'/) print $3}' /etc/passwd ) )
335 return 0
336 ;;
337 -user)
338 COMPREPLY=( $( compgen -u $cur ) )
339 return 0
340 ;;
341 -[acm]min|-[acm]time|-?(i)?(l)name|-inum|-?(i)path|-?(i)regex| \
342 -links|-perm|-size|-used|-exec|-ok|-printf)
343 # do nothing, just wait for a parameter to be given
344 return 0
345 ;;
346 esac
347
348 # complete using basic options ($cur has had its dash removed here,
349 # as otherwise compgen will bomb out with an error, since it thinks
350 # the dash is an option to itself)
351 COMPREPLY=( $( compgen -W 'daystart depth follow help maxdepth \
352 mindepth mount noleaf version xdev amin anewer atime \
353 cmin cnewer ctime empty false fstype gid group ilname \
354 iname inum ipath iregex links lname mmin mtime name \
355 newer nouser nogroup perm regex size true type uid \
356 used user xtype exec fls fprint fprint0 fprintf ok \
357 print print0 printf prune ls' $cur ) )
358
359 # this removes any options from the list of completions that have
360 # already been specified somewhere on the command line.
361 COMPREPLY=( $( echo "${COMP_WORDS[@]}-" | \
362 (while read -d '-' i; do
363 [ "$i" == "" ] && continue
364 # flatten array with spaces on either side,
365 # otherwise we cannot grep on word boundaries of
366 # first and last word
367 COMPREPLY=" ${COMPREPLY[@]} "
368 # remove word from list of completions
369 COMPREPLY=( ${COMPREPLY/ ${i%% *} / } )
370 done
371 echo ${COMPREPLY[@]})
372 ) )
373
374 # put dashes back
375 for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
376 COMPREPLY[i]=-${COMPREPLY[i]}
377 done
378
379 return 0
380 }
381 complete -F _find find
382
383 # Linux ifconfig(8) completion
384 #
385 _ifconfig ()
386 {
387 local cur
388
389 COMPREPLY=()
390 cur=${COMP_WORDS[COMP_CWORD]}
391
392 case "${COMP_WORDS[1]}" in
393 -|*[0-9]*)
394 COMPREPLY=( $( compgen -W '-a up down arp promisc allmulti \
395 metric mtu dstaddr netmask add del \
396 tunnel irq io_addr mem_start media \
397 broadcast pointopoint hw multicast \
398 address txqueuelen' $cur ))
399 COMPREPLY=( $( echo " ${COMP_WORDS[@]}" | \
400 (while read -d ' ' i; do
401 [ "$i" == "" ] && continue
402 # flatten array with spaces on either side,
403 # otherwise we cannot grep on word
404 # boundaries of first and last word
405 COMPREPLY=" ${COMPREPLY[@]} "
406 # remove word from list of completions
407 COMPREPLY=( ${COMPREPLY/ $i / } )
408 done
409 echo ${COMPREPLY[@]})
410 ) )
411 return 0
412 ;;
413 esac
414
415 COMPREPLY=( $( ifconfig -a | sed -ne 's/^\('$cur'[^ ]*\).*$/\1/p' ))
416 }
417 complete -F _ifconfig ifconfig
418
419 # Linux ipsec(8) completion (for FreeS/WAN). Very basic.
420 #
421 _ipsec ()
422 {
423 local cur
424
425 COMPREPLY=()
426 cur=${COMP_WORDS[COMP_CWORD]}
427
428 COMPREPLY=( $( compgen -W 'auto barf eroute klipsdebug look manual \
429 pluto ranbits rsasigkey setup showdefaults \
430 showhostkey spi spigrp tncfg whack' $cur ))
431 }
432 complete -F _ipsec ipsec
433 #########################################################################