Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 602 lines (528 sloc) 13.947 kb
254af1b @pdkl95 added some comments, added extending-completion example
authored
1 #!/bin/bash
2 # -*- mode: bash -*-
3 #
4 # ---------------------------
5 # --= bash completion for the =--
6 # --= rubygems "gem" program =--
7 # ---------------------------
5208a88 @pdkl95 initial import
authored
8 #
9 # Copyright C 2011 Brent Sanders <git@thoughtnoise.net>
10 # -> Derived losely from "git-completion.sh" in the git-sh
11 # package, copyright C 2006,2007 Shawn O. Pearce <spearce@spearce.org>
12 # -> Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
13 # Distributed under the GNU General Public License, version 2.0.
14 #
254af1b @pdkl95 added some comments, added extending-completion example
authored
15 # I have tested with these rubygems versions during development
16 # and several months of practical use:
17 # - 1.8.10
18 # - 1.8.11
19 # - 1.8.15
20 #
21 # It almost certainly works on related versions, as the interface
22 # dosn't change THAT often. You will run into trouble on very old versions,
23 # though, and who knows what the future brings. When in doubt, compare the
24 # relevant "_git_FOO" function with the output of "gem help FOO"
25 #
26 # Writing your own aliases?
27 # Wrapping gem in some function?
28 # ||
29 # |+-> See the end of this file for examples of
30 # +--> extending completion into your stuff!!!
31 #
672eca9 @pdkl95 fixed stale, non-POSIX usage of "function"
authored
32 #
33 # ChangeLog:
34 #
254af1b @pdkl95 added some comments, added extending-completion example
authored
35 # * 2012/01/27 - added some comments, added example of
36 # aliasing gem with completion, cleaned
37 # up the wrapping sanity-check
38 #
5930093 @pdkl95 forgot to add the changelog
authored
39 # * 2011/12/16 - added matching filenames, filtered by extension,
40 # which is used already in a few places
41 #
672eca9 @pdkl95 fixed stale, non-POSIX usage of "function"
authored
42 # * 2011/12/16 - remove use of stale bash features. (defining funs
43 # with the keyword 'function' is apparently not POSIX)
44 #
45 # * 2011/11/30 - Initial Release
46 #
5208a88 @pdkl95 initial import
authored
47
48
254af1b @pdkl95 added some comments, added extending-completion example
authored
49 #########################
50 # first, a SANITY CHECK #
51 #########################
5208a88 @pdkl95 initial import
authored
52
254af1b @pdkl95 added some comments, added extending-completion example
authored
53 __gem_iscmd() {
54 command hash "$1" 2>&-
55 }
56 __gem_missing() {
57 ! __gem_iscmd gem
58 }
59 __gem_cleanable="__gem_cleanable __gem_iscmd __gem_missing"
5208a88 @pdkl95 initial import
authored
60
254af1b @pdkl95 added some comments, added extending-completion example
authored
61 if __gem_missing ; then
62 # We should play nice with the bash environment, and not
63 # pollute the namespace if we can't actually do anything useful.
64 unset ${__gem_cleanable}
65 return 1
66 fi
67 # good, 'gem' exists - proceed with init
68
69
70 ###################
71 # compgen wrapper #
72 ###################
73
74 __gemcomp() {
75 local all c s=$'\n' IFS=' '$'\t'$'\n'
76 local cur="${COMP_WORDS[COMP_CWORD]}"
77 if [[ $# -gt 2 ]] ; then
78 cur="$3"
79 fi
80 for c in $1; do
81 case "$c$4" in
82 --*=*) all="$all$c$4$s" ;;
83 *.) all="$all$c$4$s" ;;
84 *) all="$all$c$4 $s" ;;
5208a88 @pdkl95 initial import
authored
85 esac
254af1b @pdkl95 added some comments, added extending-completion example
authored
86 done
87 IFS=$s
88 COMPREPLY=($(compgen -P "$2" -W "$all" -- "$cur"))
89 return
90 }
91
92
93 ##########################
94 # <EXTERNAL> completions #
95 ##########################
96
97 __gem_complete_file() {
98 local IFS=$'\n'
99 local EXT cur="${COMP_WORDS[COMP_CWORD]}"
100 [[ -n "$1" ]] && EXT=".$1" || EXT=''
101 COMPREPLY=( "${COMPREPLY[@]}" $( command ls -aF1d $cur*$EXT 2>/dev/null | sed -e 's/[*@|=]$//g' -e 's/[^\/]$/& /g' -e "s/^/$1/") )
102 }
103
104 __gem_complete_gemname() {
105 __gemcomp "$(gem list --no-details --no-versions)"
106 }
107
108 __gem_complete_gemnameversion() {
109 __gem_complete_gemname
110 }
111
112
113 ######################################
114 # Standard Options for most commands #
115 ######################################
116
117 __gem_stdopt_short() {
118 echo "-h -V -q"
119 }
120
121 __gem_stdopt_long() {
122 echo "--help --verbose --no-verbose --quiet --config-file= --backtrace --debug"
123 }
124
125 __gem_options() {
126 local cur="${COMP_WORDS[COMP_CWORD]}" short="$1" long="$2"
127 shift 2
128 case "$cur" in
129 --*)
130 __gemcomp "$(__gem_stdopt_long) ${long}"
131 return
132 ;;
133 -*)
134 __gemcomp "$(__gem_stdopt_short) ${short}"
135 return
136 ;;
137 esac
138 COMPREPLY=()
139 }
140
141 __gem_localremote_options() {
142 local short="$1" long="$2"
143 shift 2
144 __gem_options "-l -r -b -B -p ${short}" "\
145 --local
146 --remote
147 --both
148 --bulk-threshold=
149 --clear-sources
150 --source=
151 ${long}"
152 }
153
154 __gem_installupdate_options() {
155 local short="$1" long="$2"
156 shift 2
157 __gem_localremote_options "-i -n -d -E -f -w -P -W ${short}" "\
158 --install-dir=
159 --bindir=
160 --rdoc --no-rdoc
161 --ri --no-ri
162 --env-shebang --no-env-shebang
163 --force --no-force
164 --wrappers --no-wrappers
165 --trust-policy=
166 --ignore-dependencies
167 --include-dependencies
168 --format-executable --no-format-executable
169 --user-install --no-user-install
170 --development
171 --conservative
172 ${long}"
173 }
174
175 __gem_gemnames_or_options() {
176 case "${COMP_WORDS[COMP_CWORD]}" in
177 -*) __gem_options "$@" ;;
178 *) __gem_complete_gemname ;;
179 esac
180 }
181
182 __gem_gemnames_or_localremote_options() {
183 case "${COMP_WORDS[COMP_CWORD]}" in
184 -*) __gem_localremote_options "$@" ;;
185 *) __gem_complete_gemname ;;
186 esac
187 }
188
189
190 __gem_gemnames_or_installupdate_options() {
191 case "${COMP_WORDS[COMP_CWORD]}" in
192 -*) __gem_installupdate_options "$@" ;;
193 *) __gem_complete_gemname ;;
194 esac
195 }
196
197 __gem_files_or_options() {
198 case "${COMP_WORDS[COMP_CWORD]}" in
199 -*) __gem_options "$@" ;;
200 *) __gem_complete_file ;;
201 esac
202 }
203
204
205 #########################
206 # <BUILTIN> completions #
207 #########################
208
209 # this looks ugly, but is preparation
210 # for future automation
211 read -r -d '' GEM_COMMAND_LIST <<'ALLGEMCOMMANDS'
212 build
213 cert
214 check
215 cleanup
216 contents
217 dependency
218 environment
219 fetch
220 generate_index
221 help
222 install
223 list
224 lock
225 outdated
226 owner
227 pristine
228 push
229 query
230 rdoc
231 search
232 server
233 sources
234 specification
235 stale
236 uninstall
237 unpack
238 update
239 which
240 ALLGEMCOMMANDS
241
242
243 _gem_build() {
244 case "${COMP_WORDS[COMP_CWORD]}" in
245 -*) __gem_options "$@" ;;
246 *) __gem_complete_file gemspec ;;
247 esac
248 }
249
250 _gem_cert() {
251 __gem_options '-a -l -r -b -C -K -s' '\
252 --add=
253 --list
254 --remove=
255 --build=
256 --certificate=
257 --private-key=
258 --sign='
259 }
260
261 _gem_check() {
262 __gem_options '-a -v' '\
263 --verify=
264 --alien
265 --version='
266 }
267
268 _gem_cleanup() {
269 __gem_gemnames_or_options '-d' '--dryrun'
270 }
271
272 _gem_contents() {
273 __gem_gemnames_or_options '-v -s -l' '\
274 --version=
275 --all
276 --spec-dir=
277 --lib-only --no-lib-only
278 --prefix --no-prefix'
279 }
280
281 _gem_dependency() {
282 __gem_gemnames_or_localremote_options '-v -R' '\
283 --version=
284 --platform=
285 --prerelease --no-prerelease
286 --reverse-dependencies --no-reverse-dependencies
287 --pipe'
288 }
289
290 _gem_environment() {
291 case "${COMP_WORDS[COMP_CWORD]}" in
292 -*) __gem_options ;;
02da7cf @voxik Fix typo.
voxik authored
293 *) __gemcomp "packageversion gemdir gempath version remotesources platform" ;;
254af1b @pdkl95 added some comments, added extending-completion example
authored
294 esac
295 }
296
297 _gem_fetch() {
298 __gem_gemnames_or_options '-v -B -p', '\
299 --version=
300 --platform=
301 --prerelease --no-prerelease
302 --bulk-threshold=
303 --http-proxy --no-http-proxy
304 --source='
305 }
306
307 _gem_generate_index() {
308 __gem_options '-d' '\
309 --directory=
310 --legacy --no-legacy
311 --modern --no-modern
312 --update
313 --rss-gems-host=
314 --rss-host=
315 --rss-title='
316 }
317
318 _gem_help() {
319 case "${COMP_WORDS[COMP_CWORD]}" in
320 -*) __gem_options ;;
321 *) __gemcomp "commands examples ${__gem_commandlist}" ;;
322 esac
323 }
324
325 _gem_install() {
326 __gem_gemnames_or_installupdate_options '-v' '\
327 --platform=
328 --version=
329 --prerelease --no-prerelease'
330 }
331
332 _gem_list() {
333 __gem_options "-i -v -d -a" "\
334 --installed --no-installed
335 --version
336 --details --no-details
337 --versions --no-versions
338 --all"
339 }
340
341 _gem_lock() {
342 case "${COMP_WORDS[COMP_CWORD]}" in
343 -*) __gem_options '-s' '--strict --no-strict' ;;
344 *) __gem_complete_gemnameversion ;;
345 esac
346 }
347
348 _gem_outdated() {
349 __gem_localremote_options '' '--platform='
350 }
351
352 _gem_owner() {
353 __gem_options '-k -a -r -p' '\
354 --key=
355 --add=
356 --remote=
357 --http-proxy --no-http-proxy'
358 }
359
360 _gem_pristine() {
361 __gem_gemnames_or_options '-v' '\
362 --all
363 --extensions --no-extensions
364 --version='
365 }
366
367 _gem_push() {
368 case "${COMP_WORDS[COMP_CWORD]}" in
369 -*) __gem_options '-k -p' '--key= --host= --http-proxy --no-http-proxy' ;;
370 *) __gem_complete_file gem ;;
371 esac
372 }
373
374 _gem_query() {
375 __gem_localremote_options '-i -v -n -d -a' '\
376 --installed --no-installed
377 --version=
378 --name-matches=
379 --details --no-details
380 --versions --no-versions
381 --all
382 --prerelease --no-prerelease'
383 }
384
385 _gem_rdoc() {
386 __gem_gemnames_or_options '-v' '\
387 --all
388 --rdoc --no-rdoc
389 --ri --no-ri
390 --overwrite --no-overwrite
391 --version='
392 }
393
394 _gem_search() {
395 case "${COMP_WORDS[COMP_CWORD]}" in
396 -*) __gem_localremote_options '-i -v -d -a' '\
397 --installed --no-installed
398 --version=
399 --details --no-details
400 --versions --no-versions
401 --all
402 --prerelease --no-prerelease'
403 ;;
404 *) COMPREPLY=() ;;
405 esac
406 }
407
408 _gem_server() {
409 __gem_options '-p -d -b -l' '\
410 --port=
411 --dir=
412 --daemon --no-daemon
413 --bind=
414 --launch'
415 }
416
417 _gem_sources() {
418 __gem_options '-a -l -r -c -u -p' '\
419 --add=
420 --list
421 --remove=
422 --clear-all
423 --update
424 --http-proxy --no-http-proxy'
425 }
426
427 _gem_specification() {
428 case ${COMP_CWORD} in
429 2) __gem_complete_gemname ;;
430 3) __gemcomp "\
431 name
432 version
433 platform
434 authors
435 autorequire
436 bindir
437 cert_chain
438 date
439 dependencies
440 description
441 email
442 executables
443 extensions
444 extra_rdoc_files
445 files
446 homepage
447 licenses
448 post_install_message
449 rdoc_options
450 require_paths
451 required_ruby_version
452 required_rubygems_version
453 requirements
454 rubyforge_project
455 rubygems_version
456 signing_key
457 specification_version
458 summary
459 test_files"
460 ;;
461 *) __gem_localremote_options '-v' '\
462 --version=
463 --platform=
464 --all
465 --ruby
466 --yaml
467 --marshal'
468 ;;
469 esac
470 }
471
472 _gem_stale() {
473 __gem_options
474 }
475
476 _gem_uninstall() {
477 __gem_gemnames_or_options '-a -I -x -i -n -v' '\
478 --all --no-all
479 --ignore-dependencies --no-ignore-dependencies
480 --executables --no-executables
481 --install-dir=
482 --bindir=
483 --user-instal --no-user-install
484 --format-executable --no-format-executable
485 --version=
486 --platform='
487 }
488
489 _gem_unpack() {
490 __gem_gemnames_or_options '-v' '--target= --spec --version='
491 }
492
493 _gem_update() {
494 __gem_gemnames_or_installupdate_options '' '\
495 --system
496 --platform=
497 --prerelease --no-prerelease'
498 }
499
500 _gem_which() {
501 __gem_files_or_options '-a -g' '\
502 --all --no-all
503 --gems-first --no-gems-first'
504 }
505
506
507 ###############################
508 # toplevel wrapper completion #
509 ###############################
510
511 __gem() {
512 case "${COMP_WORDS[COMP_CWORD]}" in
513 --*=*) COMPREPLY=() ;;
514 --*) __gemcomp "--help --version" ;;
515 -*) __gemcomp "-h -v" ;;
516 *) __gemcomp "${GEM_COMMAND_LIST}" ;;
517 esac
518 }
519
520 _gem() {
521 local gemcmd
522
523 [[ $COMP_CWORD -gt 1 ]] && gemcmd="${COMP_WORDS[1]}"
524 [[ $COMP_CWORD -eq 1 ]] && [[ -z "$gemcmd" ]] && __gem && return
525
526 case "$gemcmd" in
527 build) _gem_build ;;
528 cert) _gem_cert ;;
529 check) _gem_check ;;
530 cleanup) _gem_cleanup ;;
531 contents) _gem_contents ;;
532 dependency) _gem_dependency ;;
533 environment) _gem_environment ;;
534 fetch) _gem_fetch ;;
535 generate_index) _gem_generate_index ;;
536 help) _gem_help ;;
537 install) _gem_install ;;
538 list) _gem_list ;;
539 lock) _gem_lock ;;
540 outdated) _gem_outdated ;;
541 owner) _gem_owner ;;
542 pristine) _gem_pristine ;;
543 push) _gem_push ;;
544 query) _gem_query ;;
545 rdoc) _gem_rdoc ;;
546 search) _gem_search ;;
547 server) _gem_server ;;
548 sources) _gem_sources ;;
549 specification) _gem_specification ;;
550 stale) _gem_stale ;;
551 uninstall) _gem_uninstall ;;
552 unpack) _gem_unpack ;;
553 update) _gem_update ;;
554 which) _gem_which ;;
555 *) COMPREPLY=() ;;
556 esac
557 }
558
559
560 ###########################################
561 # Finally, tie it all together with the a #
562 # single call to the 'complete' builtin. #
563 ###########################################
564
565 # required params:
566 # - completion function
567 # - command to complete
568 _gemcomp() {
569 complete -o default -o nospace -F "$@"
570 }
571 _gemcomp _gem gem
572
573
574 ##############################
575 # EXTENDING completion into #
576 # your own functions/aliases #
577 ##############################
578
579 # do you want to alias 'gem' itself?
580 # then use this to tie in the completion
581 #
582 #alias rg="command gem"
583 #_gemcomp _gem rg
5208a88 @pdkl95 initial import
authored
584
254af1b @pdkl95 added some comments, added extending-completion example
authored
585 # perhaps more useful, might be to alias to an
586 # internal gem command+options? In that case,
587 # you can skip _gem and go right to the specific
588 # completion funcion
589 #
590 #alias gi="command gem install --verbose"
591 #_gemcomp _gem_install gi
5208a88 @pdkl95 initial import
authored
592
593
594
254af1b @pdkl95 added some comments, added extending-completion example
authored
595 ######################################
596 # ...and finally, unload what we can #
597 ######################################
598
599 unset ${__gem_cleanable}
600 return 0
601 #EOF
Something went wrong with that request. Please try again.