From c3d398fcc6e400be546c28eb1fc25abfa5816eac Mon Sep 17 00:00:00 2001 From: David Paleino Date: Sun, 8 Jan 2012 00:19:18 +0100 Subject: Imported Upstream version 1.99 --- CHANGES | 76 ++++ Makefile.am | 10 +- Makefile.in | 64 ++- README | 4 +- bash_completion | 360 ++++++++++------ completions/Makefile.am | 47 +- completions/Makefile.in | 47 +- completions/_mock | 2 +- completions/_modules | 6 +- completions/_yum | 2 +- completions/ant | 2 +- completions/apt-build | 2 +- completions/apt-cache | 4 +- completions/apt-get | 4 +- completions/avctrl | 20 + completions/cardctl | 2 +- completions/ccache | 26 ++ completions/cfrun | 2 +- completions/chkconfig | 8 +- completions/cksfv | 2 +- completions/configure | 2 +- completions/cowsay | 3 +- completions/cpio | 2 +- completions/cppcheck | 18 +- completions/cryptsetup | 2 +- completions/curl | 16 +- completions/cvs | 25 +- completions/desktop-file-validate | 23 + completions/dict | 19 +- completions/dmesg | 13 +- completions/dnsspoof | 26 ++ completions/dpkg | 22 +- completions/e2label | 2 +- completions/export | 60 ++- completions/fbgs | 4 +- completions/fbi | 17 +- completions/feh | 14 +- completions/function | 6 +- completions/gcc | 16 +- completions/gdb | 4 +- completions/gpg | 2 +- completions/gpg2 | 2 +- completions/hcitool | 34 +- completions/htop | 32 ++ completions/id | 18 + completions/ifup | 2 +- completions/info | 10 +- completions/invoke-rc.d | 6 +- completions/iperf | 63 +++ completions/ipmitool | 14 +- completions/ipsec | 4 +- completions/iptables | 4 +- completions/isql | 2 +- completions/iwconfig | 6 +- completions/iwlist | 2 +- completions/iwpriv | 2 +- completions/iwspy | 2 +- completions/java | 10 +- completions/kcov | 14 +- completions/killall | 19 +- completions/kldload | 2 +- completions/koji | 234 ++++++++++ completions/links | 2 +- completions/lintian | 7 +- completions/lrzip | 9 +- completions/lvm | 14 +- completions/lzip | 44 ++ completions/make | 8 +- completions/man | 4 +- completions/minicom | 7 +- completions/mount | 115 +---- completions/mount.linux | 224 ++++++++++ completions/mplayer | 4 +- completions/mtx | 2 +- completions/mutt | 25 +- completions/mysql | 2 +- completions/nethogs | 25 ++ completions/openssl | 8 +- completions/p4 | 6 +- completions/perl | 12 +- completions/pgrep | 22 +- completions/pidof | 19 + completions/plague-client | 14 + completions/povray | 2 +- completions/psql | 2 +- completions/puppet | 2 +- completions/qdbus | 2 +- completions/rcs | 2 +- completions/removepkg | 12 +- completions/ri | 12 +- completions/route | 4 +- completions/rpcdebug | 2 +- completions/rpm | 8 +- completions/rpm2tgz | 6 +- completions/rrdtool | 2 +- completions/rsync | 2 +- completions/sbopkg | 26 +- completions/service | 34 -- completions/sitecopy | 2 +- completions/slackpkg | 48 +-- completions/slapt-get | 20 +- completions/slapt-src | 20 +- completions/smbclient | 4 +- completions/sqlite3 | 4 +- completions/ssh | 32 +- completions/strace | 2 +- completions/tar | 2 +- completions/udevadm | 76 ++++ completions/umount | 21 + completions/umount.linux | 140 ++++++ completions/unace | 4 +- completions/unrar | 4 +- completions/update-alternatives | 2 +- completions/update-rc.d | 4 +- completions/upgradepkg | 18 +- completions/valgrind | 104 +++++ completions/wine | 20 + completions/wodim | 6 +- completions/wtf | 10 +- completions/xgamma | 17 +- completions/xhost | 2 - completions/xrandr | 48 +-- configure | 23 +- configure.ac | 4 +- doc/Makefile.am | 8 + doc/Makefile.in | 309 +++++++++++++ doc/bash_completion.txt | 59 +++ doc/bashrc | 41 ++ doc/inputrc | 21 + doc/main.txt | 18 + doc/makeHtml.sh | 4 + doc/styleguide.txt | 111 +++++ doc/testing.txt | 573 +++++++++++++++++++++++++ test/completion/ccache.exp | 1 + test/completion/desktop-file-validate.exp | 1 + test/completion/export.exp | 1 + test/completion/htop.exp | 1 + test/completion/iperf.exp | 1 + test/completion/koji.exp | 1 + test/completion/lzip.exp | 1 + test/completion/nethogs.exp | 1 + test/completion/pidof.exp | 1 + test/completion/plague-client.exp | 1 + test/completion/udevadm.exp | 1 + test/completion/umount.exp | 1 + test/completion/valgrind.exp | 1 + test/completion/vi.exp | 1 + test/completion/wine.exp | 1 + test/fixtures/_known_hosts_real/config_tilde | 4 +- test/fixtures/_known_hosts_real/known_hosts | 2 +- test/fixtures/_known_hosts_real/known_hosts2 | 2 +- test/fixtures/_known_hosts_real/known_hosts4 | 1 + test/fixtures/make/Makefile | 16 + test/fixtures/make/empty_dir/.nothing_here | 0 test/fixtures/make/sample.c | 7 + test/fixtures/shared/ld.so.conf.d/foo.txt | 0 test/fixtures/shared/ld.so.conf.d/libfoo.conf | 0 test/fixtures/shared/ld.so.conf.d/libfoo.so | 0 test/fixtures/shared/ld.so.conf.d/libfoo.so.1 | 0 test/lib/completions/ccache.exp | 18 + test/lib/completions/cppcheck.exp | 12 + test/lib/completions/desktop-file-validate.exp | 20 + test/lib/completions/export.exp | 55 +++ test/lib/completions/htop.exp | 20 + test/lib/completions/iperf.exp | 20 + test/lib/completions/killall.exp | 2 +- test/lib/completions/koji.exp | 22 + test/lib/completions/lzip.exp | 20 + test/lib/completions/make.exp | 29 +- test/lib/completions/nethogs.exp | 20 + test/lib/completions/perldoc.exp | 9 +- test/lib/completions/pidof.exp | 20 + test/lib/completions/plague-client.exp | 20 + test/lib/completions/ssh.exp | 2 +- test/lib/completions/udevadm.exp | 20 + test/lib/completions/umount.exp | 20 + test/lib/completions/upgradepkg.exp | 12 + test/lib/completions/valgrind.exp | 50 +++ test/lib/completions/vi.exp | 22 + test/lib/completions/wine.exp | 31 ++ test/lib/library.exp | 7 +- test/unit/_get_comp_words_by_ref.exp | 8 + test/unit/_known_hosts_real.exp | 9 +- test/unit/_parse_help.exp | 5 + test/unit/_parse_usage.exp | 5 + test/unit/quote.exp | 69 +++ 186 files changed, 3775 insertions(+), 759 deletions(-) create mode 100644 completions/avctrl create mode 100644 completions/ccache create mode 100644 completions/desktop-file-validate create mode 100644 completions/dnsspoof create mode 100644 completions/htop create mode 100644 completions/id create mode 100644 completions/iperf create mode 100644 completions/koji create mode 100644 completions/lzip create mode 100644 completions/mount.linux create mode 100644 completions/nethogs create mode 100644 completions/pidof create mode 100644 completions/plague-client delete mode 100644 completions/service create mode 100644 completions/udevadm create mode 100644 completions/umount create mode 100644 completions/umount.linux create mode 100644 completions/valgrind create mode 100644 completions/wine create mode 100644 doc/Makefile.am create mode 100644 doc/Makefile.in create mode 100644 doc/bash_completion.txt create mode 100644 doc/bashrc create mode 100644 doc/inputrc create mode 100644 doc/main.txt create mode 100755 doc/makeHtml.sh create mode 100644 doc/styleguide.txt create mode 100644 doc/testing.txt create mode 100644 test/completion/ccache.exp create mode 100644 test/completion/desktop-file-validate.exp create mode 100644 test/completion/export.exp create mode 100644 test/completion/htop.exp create mode 100644 test/completion/iperf.exp create mode 100644 test/completion/koji.exp create mode 100644 test/completion/lzip.exp create mode 100644 test/completion/nethogs.exp create mode 100644 test/completion/pidof.exp create mode 100644 test/completion/plague-client.exp create mode 100644 test/completion/udevadm.exp create mode 100644 test/completion/umount.exp create mode 100644 test/completion/valgrind.exp create mode 100644 test/completion/vi.exp create mode 100644 test/completion/wine.exp create mode 100644 test/fixtures/_known_hosts_real/known_hosts4 create mode 100644 test/fixtures/make/Makefile create mode 100644 test/fixtures/make/empty_dir/.nothing_here create mode 100644 test/fixtures/make/sample.c create mode 100644 test/fixtures/shared/ld.so.conf.d/foo.txt create mode 100644 test/fixtures/shared/ld.so.conf.d/libfoo.conf create mode 100644 test/fixtures/shared/ld.so.conf.d/libfoo.so create mode 100644 test/fixtures/shared/ld.so.conf.d/libfoo.so.1 create mode 100644 test/lib/completions/ccache.exp create mode 100644 test/lib/completions/desktop-file-validate.exp create mode 100644 test/lib/completions/export.exp create mode 100644 test/lib/completions/htop.exp create mode 100644 test/lib/completions/iperf.exp create mode 100644 test/lib/completions/koji.exp create mode 100644 test/lib/completions/lzip.exp create mode 100644 test/lib/completions/nethogs.exp create mode 100644 test/lib/completions/pidof.exp create mode 100644 test/lib/completions/plague-client.exp create mode 100644 test/lib/completions/udevadm.exp create mode 100644 test/lib/completions/umount.exp create mode 100644 test/lib/completions/valgrind.exp create mode 100644 test/lib/completions/vi.exp create mode 100644 test/lib/completions/wine.exp create mode 100644 test/unit/quote.exp diff --git a/CHANGES b/CHANGES index 17667d08..e650f5ee 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,79 @@ +bash-completion (1.99) + + * Hopefully the last 2.0 preview. + + [ David Paleino ] + * Correctly list purgeable packages for dpkg --listfiles and dpkg + --purge (Debian: #647684) + * Fix bash_completion paths in README (Debian: #647941) + + [ Florian Hubold ] + * xv: Add *.eps and *.ps to filename completions (Alioth: #313477) + + [ Igor Murzov ] + * Add and use _sysvdirs() function that sets correct SysV init + directory. + * cppcheck: Add new options introduced in cppcheck-1.52. + * cppcheck: Several ids separated by commas can be given for + --enable=. + * _known_hosts_real: Add some quotes (Alioth #313158) + * Merge completions/service into the bash_completion script. + * _modules: Follow symlinks in /lib/modules/$(uname -r) (Alioth: + #313461) + * mount, umount: Add linux-specific completions. + * mount: Don't suggest short options. + * pidof: Don't check OS type (Alioth #311403) + * removepkg: Make it possible to complete filenames. + * umount: Fix for completion of relative paths. + * upgradepkg: Support oldpackage%newpackage notation. + * wine: Complete all files after an .exe (Alioth #313131) + * New completions: + - htop, nethogs. + + [ Jan Kratochvil ] + * rpm: Treat -r as --root (RedHat: #759224). + + [ Raphaël Droz ] + * Added a word about compopt -o nospace in styleguide.txt. + * _ip_addresses: Make it locale agnostic. + + [ Ville Skyttä ] + * cc, c++: Install gcc completion if compiler looks like GCC + (Alioth: #311408). + * cppcheck: Offer header filename completions too. + * curl: Add bunch of new option argument completions. + * dequote: Use printf instead of echo (Alioth: #312163). + * dict: Speed up word completion with common use cases and large + word lists. + * dmesg: Adapt to versions returning long options. + * Document $split && return. + * _filedir, _tilde: Ignore compopt stderr for direct invocations in + unit tests. + * Include doc/ in dist tarball. + * _known_hosts_real: Handle more than two hostnames per known hosts + line (Debian: #647352). + * _known_hosts_real: Include hosts reported by ruptime (Alioth: + #313308). + * _known_hosts_real: Support > 1 files per *KnownHostsFile line + (Debian: #650514). + * lintian: Use <<< instead of echo and a pipe (Alioth: #312163). + * lrzip: -T no longer takes an argument since version 0.570. + * _mac_addresses: Grab addresses from FreeBSD's ifconfig -a output + too. + * make: Add -j/--jobs completion, complete up to number of CPUs * 2. + * _muttconffiles: Use printf instead of echo (Alioth: #312163). + * _parse_help, _parse_usage: If first arg is "-", read from stdin. + * rpm: Add --delsign completion, don't suggest --resign (identical + to --addsign). + * _variables: New function split from _init_completion. + * vi and friends: Fix /etc/ld.so.conf.d/* completion (Alioth: + #312409). + * New completions: + - plague-client, desktop-file-validate, valgrind, ccache, iperf, + koji, lzip, udevadm. + + -- David Paleino Sat, 07 Jan 2012 23:52:36 +0100 + bash-completion (1.90) * bash-completion 2 preview: dynamic loading of completions. diff --git a/Makefile.am b/Makefile.am index 3441b630..dbbba0c2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,10 @@ -SUBDIRS = completions helpers test +SUBDIRS = completions doc helpers test pkgdata_DATA = bash_completion +# Empty, but here just to get the compat dir created with install +compat_DATA = + profiledir = $(sysconfdir)/profile.d profile_DATA = bash_completion.sh @@ -18,6 +21,7 @@ EXTRA_DIST = CHANGES $(sysconf_DATA) $(pkgdata_DATA) bash_completion.sh.in \ install-data-hook: tmpfile=`mktemp $${TMPDIR:-/tmp}/bash_completion.XXXXXX` && \ - sed -e 's|=/etc/bash_completion\.d|=$(sysconfdir)/bash_completion.d|' \ + sed -e 's|=/etc/bash_completion\.d|=$(compatdir)|' \ $(DESTDIR)$(pkgdatadir)/bash_completion > $$tmpfile && \ - mv $$tmpfile $(DESTDIR)$(pkgdatadir)/bash_completion + cat $$tmpfile > $(DESTDIR)$(pkgdatadir)/bash_completion && \ + rm $$tmpfile diff --git a/Makefile.in b/Makefile.in index 43fbb6d7..96b70a94 100644 --- a/Makefile.in +++ b/Makefile.in @@ -75,9 +75,10 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__installdirs = "$(DESTDIR)$(pkgconfigdir)" \ +am__installdirs = "$(DESTDIR)$(compatdir)" "$(DESTDIR)$(pkgconfigdir)" \ "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(profiledir)" -DATA = $(pkgconfig_DATA) $(pkgdata_DATA) $(profile_DATA) +DATA = $(compat_DATA) $(pkgconfig_DATA) $(pkgdata_DATA) \ + $(profile_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ @@ -196,8 +197,11 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -SUBDIRS = completions helpers test +SUBDIRS = completions doc helpers test pkgdata_DATA = bash_completion + +# Empty, but here just to get the compat dir created with install +compat_DATA = profiledir = $(sysconfdir)/profile.d profile_DATA = bash_completion.sh pkgconfigdir = $(datadir)/pkgconfig @@ -245,6 +249,26 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): bash-completion.pc: $(top_builddir)/config.status $(srcdir)/bash-completion.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ +install-compatDATA: $(compat_DATA) + @$(NORMAL_INSTALL) + test -z "$(compatdir)" || $(MKDIR_P) "$(DESTDIR)$(compatdir)" + @list='$(compat_DATA)'; test -n "$(compatdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(compatdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(compatdir)" || exit $$?; \ + done + +uninstall-compatDATA: + @$(NORMAL_UNINSTALL) + @list='$(compat_DATA)'; test -n "$(compatdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(compatdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(compatdir)" && rm -f $$files install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" @@ -620,7 +644,7 @@ check: check-recursive all-am: Makefile $(DATA) installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(profiledir)"; do \ + for dir in "$(DESTDIR)$(compatdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(profiledir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive @@ -670,8 +694,8 @@ info: info-recursive info-am: -install-data-am: install-pkgconfigDATA install-pkgdataDATA \ - install-profileDATA +install-data-am: install-compatDATA install-pkgconfigDATA \ + install-pkgdataDATA install-profileDATA @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-recursive @@ -718,8 +742,8 @@ ps: ps-recursive ps-am: -uninstall-am: uninstall-pkgconfigDATA uninstall-pkgdataDATA \ - uninstall-profileDATA +uninstall-am: uninstall-compatDATA uninstall-pkgconfigDATA \ + uninstall-pkgdataDATA uninstall-profileDATA .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-data-am install-strip tags-recursive @@ -730,15 +754,16 @@ uninstall-am: uninstall-pkgconfigDATA uninstall-pkgdataDATA \ dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \ distclean distclean-generic distclean-tags distcleancheck \ distdir distuninstallcheck dvi dvi-am html html-am info \ - info-am install install-am install-data install-data-am \ - install-data-hook install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-pkgconfigDATA install-pkgdataDATA install-profileDATA \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ + info-am install install-am install-compatDATA install-data \ + install-data-am install-data-hook install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkgconfigDATA install-pkgdataDATA \ + install-profileDATA install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-compatDATA \ uninstall-pkgconfigDATA uninstall-pkgdataDATA \ uninstall-profileDATA @@ -748,9 +773,10 @@ bash_completion.sh: bash_completion.sh.in Makefile install-data-hook: tmpfile=`mktemp $${TMPDIR:-/tmp}/bash_completion.XXXXXX` && \ - sed -e 's|=/etc/bash_completion\.d|=$(sysconfdir)/bash_completion.d|' \ + sed -e 's|=/etc/bash_completion\.d|=$(compatdir)|' \ $(DESTDIR)$(pkgdatadir)/bash_completion > $$tmpfile && \ - mv $$tmpfile $(DESTDIR)$(pkgdatadir)/bash_completion + cat $$tmpfile > $(DESTDIR)$(pkgdatadir)/bash_completion && \ + rm $$tmpfile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/README b/README index 428f2947..1558f62f 100644 --- a/README +++ b/README @@ -8,8 +8,8 @@ from either /etc/bashrc or ~/.bashrc (or any other file sourcing those). You can do this by simply using: # Use bash-completion, if available -[[ $PS1 && -f /usr/share/bash-completion/bash-completion ]] && \ - . /usr/share/bash-completion/bash-completion +[[ $PS1 && -f /usr/share/bash-completion/bash_completion ]] && \ + . /usr/share/bash-completion/bash_completion (if you happen to have *only* bash >= 4.1 installed, see further if not) diff --git a/bash_completion b/bash_completion index 62ef87ed..374e20c3 100644 --- a/bash_completion +++ b/bash_completion @@ -24,7 +24,7 @@ # # http://bash-completion.alioth.debian.org/ # -# RELEASE: 1.90 +# RELEASE: 1.99 if [[ $- == *v* ]]; then BASH_COMPLETION_ORIGINAL_V_VALUE="-v" @@ -32,15 +32,15 @@ else BASH_COMPLETION_ORIGINAL_V_VALUE="+v" fi -if [[ -n $BASH_COMPLETION_DEBUG ]]; then +if [[ ${BASH_COMPLETION_DEBUG-} ]]; then set -v else set +v fi -# Alter the following to reflect the location of this file. +# Set the following to the location of the backwards compat completion dir. # -[ -n "$BASH_COMPLETION_COMPAT_DIR" ] || BASH_COMPLETION_COMPAT_DIR=/etc/bash_completion.d +: ${BASH_COMPLETION_COMPAT_DIR:=/etc/bash_completion.d} readonly BASH_COMPLETION_COMPAT_DIR # Blacklisted completions, causing problems with our code. @@ -102,6 +102,17 @@ _userland() [[ $userland == $1 ]] } +# This function sets correct SysV init directories +# +_sysvdirs() +{ + sysvdirs=( ) + [[ -d /etc/rc.d/init.d ]] && sysvdirs+=( /etc/rc.d/init.d ) + [[ -d /etc/init.d ]] && sysvdirs+=( /etc/init.d ) + # Slackware uses /etc/rc.d + [[ -f /etc/slackware-version ]] && sysvdirs=( /etc/rc.d ) +} + # This function checks whether we have a given program on the system. # _have() @@ -131,7 +142,8 @@ _rl_enabled() # This function shell-quotes the argument quote() { - echo \'${1//\'/\'\\\'\'}\' #'# Help vim syntax highlighting + local quoted=${1//\'/\'\\\'\'} + printf "'%s'" "$quoted" } # @see _quote_readline_by_ref() @@ -146,7 +158,7 @@ quote_readline() # This function shell-dequotes the argument dequote() { - eval echo "$1" 2> /dev/null + eval printf %s "$1" 2> /dev/null } @@ -245,24 +257,21 @@ __reassemble_comp_words_by_ref() # empty and is word made up of just word separator characters to # be excluded and is current word not preceded by whitespace in # original line? - while [[ $i -gt 0 && ${COMP_WORDS[$i]} && - ${COMP_WORDS[$i]//[^$exclude]} == ${COMP_WORDS[$i]} - ]]; do + while [[ $i -gt 0 && ${COMP_WORDS[$i]} == +([$exclude]) ]]; do # Is word separator not preceded by whitespace in original line # and are we not going to append to word 0 (the command # itself), then append to current word. - [[ ${line:0:1} != ' ' && ${line:0:1} != $'\t' ]] && - (( j >= 2 )) && ((j--)) + [[ $line != [$' \t']* ]] && (( j >= 2 )) && ((j--)) # Append word separator to current or new word ref="$2[$j]" eval $2[$j]=\${!ref}\${COMP_WORDS[i]} # Indicate new cword - [ $i = $COMP_CWORD ] && eval $3=$j + [[ $i == $COMP_CWORD ]] && eval $3=$j # Remove optional whitespace + word separator from line copy line=${line#*"${COMP_WORDS[$i]}"} # Start new word if word separator in original line is # followed by whitespace. - [[ ${line:0:1} == ' ' || ${line:0:1} == $'\t' ]] && ((j++)) + [[ $line == [$' \t']* ]] && ((j++)) # Indicate next word if available, else end *both* while and # for loop (( $i < ${#COMP_WORDS[@]} - 1)) && ((i++)) || break 2 @@ -295,14 +304,14 @@ __get_cword_at_cursor_by_ref() local cword words=() __reassemble_comp_words_by_ref "$1" words cword - local i cur cur2 index=$COMP_POINT lead=${COMP_LINE:0:$COMP_POINT} + local i cur index=$COMP_POINT lead=${COMP_LINE:0:$COMP_POINT} # Cursor not at position 0 and not leaded by just space(s)? if [[ $index -gt 0 && ( $lead && ${lead//[[:space:]]} ) ]]; then cur=$COMP_LINE for (( i = 0; i <= cword; ++i )); do while [[ # Current word fits in $cur? - "${#cur}" -ge ${#words[i]} && + ${#cur} -ge ${#words[i]} && # $cur doesn't match cword? "${cur:0:${#words[i]}}" != "${words[i]}" ]]; do @@ -313,11 +322,11 @@ __get_cword_at_cursor_by_ref() done # Does found word match cword? - if [[ "$i" -lt "$cword" ]]; then + if [[ $i -lt $cword ]]; then # No, cword lies further; - local old_size="${#cur}" - cur="${cur#${words[i]}}" - local new_size="${#cur}" + local old_size=${#cur} + cur="${cur#"${words[i]}"}" + local new_size=${#cur} index=$(( index - old_size + new_size )) fi done @@ -472,7 +481,7 @@ _get_cword() # _get_pword() { - if [ $COMP_CWORD -ge 1 ]; then + if [[ $COMP_CWORD -ge 1 ]]; then _get_cword "${@:-}" 1 fi } @@ -501,7 +510,7 @@ __ltrim_colon_completions() # Remove colon-word prefix from COMPREPLY items local colon_word=${1%${1##*:}} local i=${#COMPREPLY[*]} - while [ $((--i)) -ge 0 ]; do + while [[ $((--i)) -ge 0 ]]; do COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"} done fi @@ -526,7 +535,7 @@ __ltrim_colon_completions() # @param $2 Name of variable to return result to _quote_readline_by_ref() { - if [[ ${1:0:1} == "'" ]]; then + if [[ $1 == \'* ]]; then # Leave out first character printf -v $2 %s "${1:1}" else @@ -536,7 +545,7 @@ _quote_readline_by_ref() # If result becomes quoted like this: $'string', re-evaluate in order to # drop the additional quoting. See also: http://www.mail-archive.com/ # bash-completion-devel@lists.alioth.debian.org/msg01942.html - [[ ${!2:0:1} == '$' ]] && eval $2=${!2} + [[ ${!2} == \$* ]] && eval $2=${!2} } # _quote_readline_by_ref() @@ -581,9 +590,11 @@ _filedir() -n "$1" && "$1" != -d && ${#toks[@]} -lt 1 ]] && \ toks+=( $( compgen -f -- $quoted ) ) - [ ${#toks[@]} -ne 0 ] && compopt -o filenames 2>/dev/null - - COMPREPLY+=( "${toks[@]}" ) + if [[ ${#toks[@]} -ne 0 ]]; then + # 2>/dev/null for direct invocation, e.g. in the _filedir unit test + compopt -o filenames 2>/dev/null + COMPREPLY+=( "${toks[@]}" ) + fi } # _filedir() @@ -606,6 +617,20 @@ _split_longopt() return 1 } +# Complete variables. +# @return True (0) if variables were completed, +# False (> 0) if not. +_variables() +{ + if [[ $cur =~ ^(\$\{?)([A-Za-z0-9_]*)$ ]]; then + [[ $cur == *{* ]] && local suffix=} || local suffix= + COMPREPLY+=( $( compgen -P ${BASH_REMATCH[1]} -S "$suffix" -v -- \ + "${BASH_REMATCH[2]}" ) ) + return 0 + fi + return 1 +} + # Initialize completion and deal with various general things: do file # and variable completion where appropriate, and adjust prev, words, # and cword as if no redirections exist so that completions do not @@ -623,7 +648,7 @@ _split_longopt() # _init_completion() { - local exclude flag outx errx inx OPTIND=1 + local exclude= flag outx errx inx OPTIND=1 while getopts "n:e:o:i:s" flag "$@"; do case $flag in @@ -646,12 +671,7 @@ _init_completion() _get_comp_words_by_ref -n "$exclude<>&" cur prev words cword # Complete variable names. - if [[ $cur =~ ^(\$\{?)([A-Za-z0-9_]*)$ ]]; then - [[ $cur == *{* ]] && local suffix=} || local suffix= - COMPREPLY=( $( compgen -P ${BASH_REMATCH[1]} -S "$suffix" -v -- \ - "${BASH_REMATCH[2]}" ) ) - return 1 - fi + _variables && return 1 # Complete on files if current is a redirect possibly followed by a # filename, e.g. ">foo", or previous is a "bare" redirect, e.g. ">". @@ -690,7 +710,7 @@ _init_completion() [[ $cword -eq 0 ]] && return 1 prev=${words[cword-1]} - [[ $split ]] && _split_longopt && split=true + [[ ${split-} ]] && _split_longopt && split=true return 0 } @@ -727,14 +747,18 @@ __parse_options() } # Parse GNU style help output of the given command. -# @param $1 command +# @param $1 command; if "-", read from stdin and ignore rest of args # @param $2 command options (default: --help) # _parse_help() { - eval local cmd=$1 + eval local cmd=$( quote "$1" ) local line - "$cmd" ${2:---help} 2>&1 | while read -r line; do + { case $cmd in + -) cat ;; + *) "$( dequote "$cmd" )" ${2:---help} 2>&1 ;; + esac } \ + | while read -r line; do [[ $line == *([ $'\t'])-* ]] || continue # transform "-f FOO, --foo=FOO" to "-f , --foo=FOO" etc @@ -748,14 +772,18 @@ _parse_help() } # Parse BSD style usage output (options in brackets) of the given command. -# @param $1 command +# @param $1 command; if "-", read from stdin and ignore rest of args # @param $2 command options (default: --usage) # _parse_usage() { - eval local cmd=$1 + eval local cmd=$( quote "$1" ) local line match option i char - "$cmd" ${2:---usage} 2>&1 | while read -r line; do + { case $cmd in + -) cat ;; + *) "$( dequote "$cmd" )" ${2:---usage} 2>&1 ;; + esac } \ + | while read -r line; do while [[ $line =~ \[[[:space:]]*(-[^]]+)[[:space:]]*\] ]]; do match=${BASH_REMATCH[0]} @@ -793,9 +821,11 @@ _mac_addresses() local re='\([A-Fa-f0-9]\{2\}:\)\{5\}[A-Fa-f0-9]\{2\}' local PATH="$PATH:/sbin:/usr/sbin" - # Local interfaces (Linux only?) + # Local interfaces (Linux: HWAddr, FreeBSD: ether) COMPREPLY+=( $( ifconfig -a 2>/dev/null | sed -ne \ - "s/.*[[:space:]]HWaddr[[:space:]]\{1,\}\($re\)[[:space:]]*$/\1/p" ) ) + "s/.*[[:space:]]HWaddr[[:space:]]\{1,\}\($re\)[[:space:]]*$/\1/p" -ne \ + "s/^[[:space:]]\{1,\}ether[[:space:]]\{1,\}\($re\)[[:space:]]*$/\1/p" \ + ) ) # ARP cache COMPREPLY+=( $( arp -an 2>/dev/null | sed -ne \ @@ -814,16 +844,16 @@ _mac_addresses() # _configured_interfaces() { - if [ -f /etc/debian_version ]; then + if [[ -f /etc/debian_version ]]; then # Debian system COMPREPLY=( $( compgen -W "$( sed -ne 's|^iface \([^ ]\{1,\}\).*$|\1|p'\ /etc/network/interfaces )" -- "$cur" ) ) - elif [ -f /etc/SuSE-release ]; then + elif [[ -f /etc/SuSE-release ]]; then # SuSE system COMPREPLY=( $( compgen -W "$( printf '%s\n' \ /etc/sysconfig/network/ifcfg-* | \ sed -ne 's|.*ifcfg-\(.*\)|\1|p' )" -- "$cur" ) ) - elif [ -f /etc/pld-release ]; then + elif [[ -f /etc/pld-release ]]; then # PLD Linux COMPREPLY=( $( compgen -W "$( command ls -B \ /etc/sysconfig/interfaces | \ @@ -841,7 +871,7 @@ _configured_interfaces() _ip_addresses() { COMPREPLY+=( $( compgen -W \ - "$( PATH="$PATH:/sbin" ifconfig -a | + "$( PATH="$PATH:/sbin" LC_ALL=C ifconfig -a | sed -ne 's/.*addr:\([^[:space:]]*\).*/\1/p' \ -ne 's/.*inet[[:space:]]\{1,\}\([^[:space:]]*\).*/\1/p' )" \ -- "$cur" ) ) @@ -862,9 +892,9 @@ _available_interfaces() { local cmd - if [ "${1:-}" = -w ]; then + if [[ ${1:-} == -w ]]; then cmd="iwconfig" - elif [ "${1:-}" = -a ]; then + elif [[ ${1:-} == -a ]]; then cmd="ifconfig" else cmd="ifconfig -a" @@ -875,6 +905,14 @@ _available_interfaces() COMPREPLY=( $( compgen -W '${COMPREPLY[@]/%[[:punct:]]/}' -- "$cur" ) ) } +# Echo number of CPUs, falling back to 1 on failure. +_ncpus() +{ + local var=NPROCESSORS_ONLN + [[ $OSTYPE == *linux* ]] && var=_$var + local n=$( getconf $var 2>/dev/null ) + printf %s ${n:-1} +} # Perform tilde (~) completion # @return True (0) if completion needs further processing, @@ -887,7 +925,8 @@ _tilde() # Try generate ~username completions COMPREPLY=( $( compgen -P '~' -u "${1#\~}" ) ) result=${#COMPREPLY[@]} - [ $result -gt 0 ] && compopt -o filenames 2>/dev/null + # 2>/dev/null for direct invocation, e.g. in the _tilde unit test + [[ $result -gt 0 ]] && compopt -o filenames 2>/dev/null fi return $result } @@ -918,9 +957,9 @@ _tilde() __expand_tilde_by_ref() { # Does $1 start with tilde (~)? - if [ "${!1:0:1}" = "~" ]; then + if [[ ${!1} == ~* ]]; then # Does $1 contain slash (/)? - if [ "${!1}" != "${!1//\/}" ]; then + if [[ ${!1} == */* ]]; then # Yes, $1 contains slash; # 1: Remove * including and after first slash (/), i.e. "~a/b" # becomes "~a". Double quotes allow eval. @@ -952,7 +991,7 @@ _expand() elif [[ "$cur" == \~* ]]; then cur=${cur#\~} COMPREPLY=( $( compgen -P '~' -u "$cur" ) ) - [ ${#COMPREPLY[@]} -eq 1 ] && eval COMPREPLY[0]=${COMPREPLY[0]} + [[ ${#COMPREPLY[@]} -eq 1 ]] && eval COMPREPLY[0]=${COMPREPLY[0]} return ${#COMPREPLY[@]} fi } @@ -1037,37 +1076,75 @@ _gids() # _backup_glob='@(#*#|*@(~|.@(bak|orig|rej|swp|dpkg*|rpm@(orig|new|save))))' +# Complete on xinetd services +# +_xinetd_services() +{ + local xinetddir=/etc/xinetd.d + if [[ -d $xinetddir ]]; then + local restore_nullglob=$(shopt -p nullglob); shopt -s nullglob + local -a svcs=( $( printf '%s\n' $xinetddir/!($_backup_glob) ) ) + $restore_nullglob + COMPREPLY+=( $( compgen -W '${svcs[@]#$xinetddir/}' -- "$cur" ) ) + fi +} + # This function completes on services # _services() { - local sysvdir famdir - [ -d /etc/rc.d/init.d ] && sysvdir=/etc/rc.d/init.d || sysvdir=/etc/init.d - famdir=/etc/xinetd.d + local sysvdirs + _sysvdirs local restore_nullglob=$(shopt -p nullglob); shopt -s nullglob - - COMPREPLY=( $( printf '%s\n' $sysvdir/!($_backup_glob|functions) ) ) - - if [ -d $famdir ]; then - COMPREPLY+=( $( printf '%s\n' $famdir/!($_backup_glob) ) ) - fi - + COMPREPLY=( $( printf '%s\n' ${sysvdirs[0]}/!($_backup_glob|functions) ) ) $restore_nullglob COMPREPLY+=( $( systemctl list-units --full --all 2>/dev/null | \ awk '$1 ~ /\.service$/ { sub("\\.service$", "", $1); print $1 }' ) ) - COMPREPLY=( $( compgen -W '${COMPREPLY[@]#@($sysvdir|$famdir)/}' -- "$cur" ) ) + COMPREPLY=( $( compgen -W '${COMPREPLY[@]#${sysvdirs[0]}/}' -- "$cur" ) ) } +# This completes on a list of all available service scripts for the +# 'service' command and/or the SysV init.d directory, followed by +# that script's available commands +# +_service() +{ + local cur prev words cword + _init_completion || return + + # don't complete past 2nd token + [[ $cword -gt 2 ]] && return 0 + + if [[ $cword -eq 1 && $prev == ?(*/)service ]]; then + _services + [[ -e /etc/mandrake-release ]] && _xinetd_services + else + local sysvdirs + _sysvdirs + COMPREPLY=( $( compgen -W '`sed -e "y/|/ /" \ + -ne "s/^.*\(U\|msg_u\)sage.*{\(.*\)}.*$/\2/p" \ + ${sysvdirs[0]}/${prev##*/} 2>/dev/null` start stop' -- "$cur" ) ) + fi +} && +complete -F _service service +_sysvdirs +for svcdir in ${sysvdirs[@]}; do + for svc in $svcdir/!($_backup_glob); do + [[ -x $svc ]] && complete -F _service $svc + done +done +unset svc svcdir sysvdirs + # This function completes on modules # _modules() { local modpath modpath=/lib/modules/$1 - COMPREPLY=( $( compgen -W "$( command ls -R $modpath | \ + COMPREPLY=( $( compgen -W "$( command ls -RL $modpath | \ sed -ne 's/^\(.*\)\.k\{0,1\}o\(\.gz\)\{0,1\}$/\1/p' )" -- "$cur" ) ) } @@ -1172,7 +1249,7 @@ _fstypes() { local fss - if [ -e /proc/filesystems ] ; then + if [[ -e /proc/filesystems ]]; then # Linux fss="$( cut -d$'\t' -f2 /proc/filesystems ) $( awk '! /\*/ { print $NF }' /etc/filesystems 2>/dev/null )" @@ -1182,11 +1259,10 @@ _fstypes() $( awk '/^[ \t]*[^#]/ { print $3 }' /etc/mnttab 2>/dev/null ) $( awk '/^[ \t]*[^#]/ { print $4 }' /etc/vfstab 2>/dev/null ) $( awk '{ print $1 }' /etc/dfs/fstypes 2>/dev/null ) - $( [ -d /etc/fs ] && command ls /etc/fs )" + $( [[ -d /etc/fs ]] && command ls /etc/fs )" fi - [ -n "$fss" ] && \ - COMPREPLY+=( $( compgen -W "$fss" -- "$cur" ) ) + [[ -n $fss ]] && COMPREPLY+=( $( compgen -W "$fss" -- "$cur" ) ) } # Get real command. @@ -1340,53 +1416,58 @@ _known_hosts_real() p) prefix=$OPTARG ;; esac done - [ $# -lt $OPTIND ] && echo "error: $FUNCNAME: missing mandatory argument CWORD" + [[ $# -lt $OPTIND ]] && echo "error: $FUNCNAME: missing mandatory argument CWORD" cur=${!OPTIND}; let "OPTIND += 1" - [ $# -ge $OPTIND ] && echo "error: $FUNCNAME("$@"): unprocessed arguments:"\ - $(while [ $# -ge $OPTIND ]; do printf '%s\n' ${!OPTIND}; shift; done) + [[ $# -ge $OPTIND ]] && echo "error: $FUNCNAME("$@"): unprocessed arguments:"\ + $(while [[ $# -ge $OPTIND ]]; do printf '%s\n' ${!OPTIND}; shift; done) [[ $cur == *@* ]] && user=${cur%@*}@ && cur=${cur#*@} kh=() # ssh config files - if [ -n "$configfile" ]; then - [ -r "$configfile" ] && - config+=( "$configfile" ) + if [[ -n $configfile ]]; then + [[ -r $configfile ]] && config+=( "$configfile" ) else - for i in /etc/ssh/ssh_config "${HOME}/.ssh/config" \ - "${HOME}/.ssh2/config"; do - [ -r $i ] && config+=( "$i" ) + for i in /etc/ssh/ssh_config ~/.ssh/config ~/.ssh2/config; do + [[ -r $i ]] && config+=( "$i" ) done fi # Known hosts files from configs - if [ ${#config[@]} -gt 0 ]; then - local OIFS=$IFS IFS=$'\n' + if [[ ${#config[@]} -gt 0 ]]; then + local OIFS=$IFS IFS=$'\n' j local -a tmpkh # expand paths (if present) to global and user known hosts files # TODO(?): try to make known hosts files with more than one consecutive # spaces in their name work (watch out for ~ expansion # breakage! Alioth#311595) tmpkh=( $( awk 'sub("^[ \t]*([Gg][Ll][Oo][Bb][Aa][Ll]|[Uu][Ss][Ee][Rr])[Kk][Nn][Oo][Ww][Nn][Hh][Oo][Ss][Tt][Ss][Ff][Ii][Ll][Ee][ \t]+", "") { print $0 }' "${config[@]}" | sort -u ) ) + IFS=$OIFS for i in "${tmpkh[@]}"; do - # Remove possible quotes - i=${i//\"} - # Eval/expand possible `~' or `~user' - __expand_tilde_by_ref i - [ -r "$i" ] && kh+=( "$i" ) + # First deal with quoted entries... + while [[ $i =~ ^([^\"]*)\"([^\"]*)\"(.*)$ ]]; do + i=${BASH_REMATCH[1]}${BASH_REMATCH[3]} + j=${BASH_REMATCH[2]} + __expand_tilde_by_ref j # Eval/expand possible `~' or `~user' + [[ -r $j ]] && kh+=( "$j" ) + done + # ...and then the rest. + for j in $i; do + __expand_tilde_by_ref j # Eval/expand possible `~' or `~user' + [[ -r $j ]] && kh+=( "$j" ) + done done - IFS=$OIFS fi - if [ -z "$configfile" ]; then + if [[ -z $configfile ]]; then # Global and user known_hosts files for i in /etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2 \ /etc/known_hosts /etc/known_hosts2 ~/.ssh/known_hosts \ ~/.ssh/known_hosts2; do - [ -r $i ] && kh+=( $i ) + [[ -r $i ]] && kh+=( "$i" ) done for i in /etc/ssh2/knownhosts ~/.ssh2/hostkeys; do - [ -d $i ] && khd+=( $i/*pub ) + [[ -d $i ]] && khd+=( "$i"/*pub ) done fi @@ -1404,23 +1485,25 @@ _known_hosts_real() # Digits followed by no dot or colon - search for digits followed # by a dot or a colon awkcur="^$awkcur.*[.:]" - elif [ -z "$awkcur" ]; then + elif [[ -z $awkcur ]]; then # A blank - search for a dot, a colon, or an alpha character awkcur="[a-z.:]" else awkcur="^$awkcur" fi - if [ ${#kh[@]} -gt 0 ]; then + if [[ ${#kh[@]} -gt 0 ]]; then # FS needs to look for a comma separated list COMPREPLY+=( $( awk 'BEGIN {FS=","} - /^\s*[^|\#]/ {for (i=1; i<=2; ++i) { \ - sub(" .*$", "", $i); \ + /^\s*[^|\#]/ { + sub("^@[^ ]+ +", ""); \ + sub(" .*$", ""); \ + for (i=1; i<=NF; ++i) { \ sub("^\\[", "", $i); sub("\\](:[0-9]+)?$", "", $i); \ - if ($i ~ /'"$awkcur"'/) {print $i} \ + if ($i !~ /[*?]/ && $i ~ /'"$awkcur"'/) {print $i} \ }}' "${kh[@]}" 2>/dev/null ) ) fi - if [ ${#khd[@]} -gt 0 ]; then + if [[ ${#khd[@]} -gt 0 ]]; then # Needs to look for files called # .../.ssh2/key_22_.pub # dont fork any processes, because in a cluster environment, @@ -1460,9 +1543,13 @@ _known_hosts_real() awk -F';' '/^=/ { print $7 }' | sort -u )" -- "$cur" ) ) fi + # Add hosts reported by ruptime. + COMPREPLY+=( $( compgen -W \ + "$( ruptime 2>/dev/null | awk '{ print $1 }' )" -- "$cur" ) ) + # Add results of normal hostname completion, unless # `COMP_KNOWN_HOSTS_WITH_HOSTFILE' is set to an empty value. - if [ -n "${COMP_KNOWN_HOSTS_WITH_HOSTFILE-1}" ]; then + if [[ -n ${COMP_KNOWN_HOSTS_WITH_HOSTFILE-1} ]]; then COMPREPLY+=( $( compgen -A hostname -P "$prefix$user" -S "$suffix" -- "$cur" ) ) fi @@ -1483,11 +1570,6 @@ _cd() _init_completion || return local IFS=$'\n' i j k - # try to allow variable completion - if [[ "$cur" == ?(\\)\$* ]]; then - COMPREPLY=( $( compgen -v -P '$' -- "${cur#?(\\)$}" ) ) - return 0 - fi compopt -o filenames @@ -1557,16 +1639,16 @@ _command_offset() # find new first word position, then # rewrite COMP_LINE and adjust COMP_POINT - local word_offset=$1 - local first_word=${COMP_WORDS[$word_offset]} char_offset i - for (( i=0; i <= ${#COMP_LINE}; i++ )); do - if [[ "${COMP_LINE:$i:${#first_word}}" == "$first_word" ]]; then - char_offset=$i - break - fi + local word_offset=$1 i j + for (( i=0; i < $word_offset; i++ )); do + for (( j=0; j <= ${#COMP_LINE}; j++ )); do + [[ "$COMP_LINE" == "${COMP_WORDS[i]}"* ]] && break + COMP_LINE=${COMP_LINE:1} + ((COMP_POINT--)) + done + COMP_LINE=${COMP_LINE#"${COMP_WORDS[i]}"} + ((COMP_POINT-=${#COMP_WORDS[i]})) done - COMP_LINE=${COMP_LINE:$char_offset} - COMP_POINT=$(( COMP_POINT - $char_offset )) # shift COMP_WORDS elements and adjust COMP_CWORD for (( i=0; i <= COMP_CWORD - $word_offset; i++ )); do @@ -1575,7 +1657,7 @@ _command_offset() for (( i; i <= COMP_CWORD; i++ )); do unset COMP_WORDS[i] done - COMP_CWORD=$(( $COMP_CWORD - $word_offset )) + ((COMP_CWORD -= $word_offset)) COMPREPLY=() local cur @@ -1588,28 +1670,21 @@ _command_offset() else local cmd=${COMP_WORDS[0]} compcmd=${COMP_WORDS[0]} local cspec=$( complete -p $cmd 2>/dev/null ) + + # If we have no completion for $cmd yet, see if we have for basename + if [[ ! $cspec && $cmd == */* ]]; then + cspec=$( complete -p ${cmd##*/} 2>/dev/null ) + [[ $cspec ]] && compcmd=${cmd##*/} + fi + # If still nothing, just load it for the basename if [[ ! $cspec ]]; then - if [[ $cmd == */* ]]; then - # Load completion for full path - _completion_loader $cmd - if [[ $? -eq 124 ]]; then - # Success, but we may now have the full path completion... - cspec=$( complete -p $cmd 2>/dev/null ) - if [[ ! $cspec ]]; then - # ...or just the basename one. - compcmd=${cmd##*/} - cspec=$( complete -p $compcmd 2>/dev/null ) - fi - fi - else - # Simple, non-full path case. - _completion_loader $cmd - [[ $? -eq 124 ]] && cspec=$( complete -p $cmd 2>/dev/null ) - fi + compcmd=${cmd##*/} + _completion_loader $compcmd + cspec=$( complete -p $compcmd 2>/dev/null ) fi if [[ -n $cspec ]]; then - if [ "${cspec#* -F }" != "$cspec" ]; then + if [[ ${cspec#* -F } != $cspec ]]; then # complete -F # get function name @@ -1627,7 +1702,7 @@ _command_offset() while true; do # FIXME: should we take "+o opt" into account? t=${cspec#*-o } - if [ "$t" == "$cspec" ]; then + if [[ $t == $cspec ]]; then break fi opt=${t%% *} @@ -1639,7 +1714,9 @@ _command_offset() cspec=${cspec%%$compcmd} COMPREPLY=( $( eval compgen "$cspec" -- "$cur" ) ) fi - elif [ ${#COMPREPLY[@]} -eq 0 ]; then + elif [[ ${#COMPREPLY[@]} -eq 0 ]]; then + # XXX will probably never happen as long as completion loader loads + # *something* for every command thrown at it ($cspec != empty) _minimal fi fi @@ -1651,7 +1728,7 @@ _root_command() { local PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin local root_command=$1 - _command $1 $2 $3 + _command } complete -F _root_command fakeroot gksu gksudo kdesudo really sudo @@ -1748,13 +1825,15 @@ _filedir_xspec() toks+=( $( eval compgen -f -X "!$xspec" -- "\$(quote_readline "\$cur")" | { while read -r tmp; do - [ -n $tmp ] && printf '%s\n' $tmp + [[ -n $tmp ]] && printf '%s\n' $tmp done } )) - [ ${#toks[@]} -ne 0 ] && compopt -o filenames - COMPREPLY=( "${toks[@]}" ) + if [[ ${#toks[@]} -ne 0 ]]; then + compopt -o filenames + COMPREPLY=( "${toks[@]}" ) + fi } _install_xspec() @@ -1778,7 +1857,8 @@ _install_xspec '!*.@(tlz|lzma)' lzcat lzegrep lzfgrep lzgrep lzless lzmore unlzm _install_xspec '!*.@(?(t)xz|tlz|lzma)' unxz xzcat _install_xspec '!*.lrz' lrunzip _install_xspec '!*.@(gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx)' ee -_install_xspec '!*.@(gif|jp?(e)g|tif?(f)|png|p[bgp]m|bmp|x[bp]m|rle|rgb|pcx|fits|pm)' xv qiv +_install_xspec '!*.@(gif|jp?(e)g|tif?(f)|png|p[bgp]m|bmp|x[bp]m|rle|rgb|pcx|fits|pm)' qiv +_install_xspec '!*.@(gif|jp?(e)g|tif?(f)|png|p[bgp]m|bmp|x[bp]m|rle|rgb|pcx|fits|pm|?(e)ps)' xv _install_xspec '!*.@(@(?(e)ps|?(E)PS|pdf|PDF)?(.gz|.GZ|.bz2|.BZ2|.Z))' gv ggv kghostview _install_xspec '!*.@(dvi|DVI)?(.@(gz|Z|bz2))' xdvi kdvi _install_xspec '!*.dvi' dvips dviselect dvitype dvipdf advi dvipdfm dvipdfmx @@ -1801,8 +1881,7 @@ _install_xspec '!*.fig' xfig _install_xspec '!*.@(mid?(i)|cmf)' playmidi _install_xspec '!*.@(mid?(i)|rmi|rcp|[gr]36|g18|mod|xm|it|x3m|s[3t]m|kar)' timidity _install_xspec '!*.@(669|abc|am[fs]|d[bs]m|dmf|far|it|mdl|m[eo]d|mid?(i)|mt[2m]|okta|p[st]m|s[3t]m|ult|umx|wav|xm)' modplugplay modplug123 -_install_xspec '*.@(o|so|so.!(conf)|a|[rs]pm|gif|jp?(e)g|mp3|mp?(e)g|avi|asf|ogg|class)' vi vim gvim rvim view rview rgvim rgview gview emacs xemacs sxemacs kate kwrite -_install_xspec '!*.@([eE][xX][eE]?(.[sS][oO])|[cC][oO][mM]|[sS][cC][rR])' wine +_install_xspec '*.@(o|so|so.!(conf|*/*)|a|[rs]pm|gif|jp?(e)g|mp3|mp?(e)g|avi|asf|ogg|class)' vi vim gvim rvim view rview rgvim rgview gview emacs xemacs sxemacs kate kwrite _install_xspec '!*.@(zip|z|gz|tgz)' bzme # konqueror not here on purpose, it's more than a web/html browser _install_xspec '!*.@(?([xX]|[sS])[hH][tT][mM]?([lL]))' netscape mozilla lynx opera galeon dillo elinks amaya firefox mozilla-firefox iceweasel google-chrome chromium-browser epiphany @@ -1839,11 +1918,6 @@ _completion_loader() local compdir=./completions [[ $BASH_SOURCE == */* ]] && compdir="${BASH_SOURCE%/*}/completions" - # Special case for init.d scripts. - if [[ $1 == /etc?(/rc.d)/init.d/* ]]; then - . "$compdir/service" &>/dev/null && return 124 || return 1 - fi - # Try basename. . "$compdir/${1##*/}" &>/dev/null && return 124 @@ -1878,7 +1952,7 @@ if [[ -d $BASH_COMPLETION_COMPAT_DIR && -r $BASH_COMPLETION_COMPAT_DIR && \ && -f $i && -r $i ]] && . "$i" done fi -unset i +unset i _blacklist_glob # source user completion file [[ ${BASH_SOURCE[0]} != ~/.bash_completion && -r ~/.bash_completion ]] \ diff --git a/completions/Makefile.am b/completions/Makefile.am index 21201925..ba3cfb03 100644 --- a/completions/Makefile.am +++ b/completions/Makefile.am @@ -20,6 +20,7 @@ bashcomp_DATA = a2x \ autoreconf \ autorpm \ autoscan \ + avctrl \ badblocks \ bk \ brctl \ @@ -28,6 +29,7 @@ bashcomp_DATA = a2x \ cal \ cancel \ cardctl \ + ccache \ cfagent \ cfrun \ chage \ @@ -53,14 +55,16 @@ bashcomp_DATA = a2x \ cpio \ cppcheck \ crontab \ - curl \ cryptsetup \ + curl \ cvs \ cvsps \ dd \ + desktop-file-validate \ dhclient \ dict \ dmesg \ + dnsspoof \ dot \ dpkg \ dpkg-source \ @@ -112,8 +116,10 @@ bashcomp_DATA = a2x \ hddtemp \ hid2hci \ hping2 \ + htop \ htpasswd \ iconv \ + id \ idn \ iftop \ ifup \ @@ -124,9 +130,10 @@ bashcomp_DATA = a2x \ invoke-rc.d \ ionice \ ip \ - iptables \ + iperf \ ipmitool \ ipsec \ + iptables \ ipv6calc \ iscsiadm \ isql \ @@ -145,6 +152,7 @@ bashcomp_DATA = a2x \ killall \ kldload \ kldunload \ + koji \ ktutil \ larch \ lastlog \ @@ -166,6 +174,7 @@ bashcomp_DATA = a2x \ lrzip \ lsof \ lvm \ + lzip \ lzma \ lzop \ macof \ @@ -186,6 +195,7 @@ bashcomp_DATA = a2x \ mmsitepass \ monodevelop \ mount \ + mount.linux \ mplayer \ msynctool \ mtx \ @@ -197,6 +207,7 @@ bashcomp_DATA = a2x \ mysql \ mysqladmin \ ncftp \ + nethogs \ newgrp \ newlist \ newusers \ @@ -209,11 +220,13 @@ bashcomp_DATA = a2x \ passwd \ perl \ pgrep \ + pidof \ pine \ ping \ pkg-config \ pkg_delete \ pkgtool \ + plague-client \ pm-hibernate \ pm-is-supported \ pm-powersave \ @@ -243,8 +256,8 @@ bashcomp_DATA = a2x \ remove_members \ removepkg \ renice \ - reptyr \ reportbug \ + reptyr \ resolvconf \ rfkill \ ri \ @@ -261,7 +274,6 @@ bashcomp_DATA = a2x \ sbcl \ sbopkg \ screen \ - service \ sh \ sitecopy \ slackpkg \ @@ -287,6 +299,9 @@ bashcomp_DATA = a2x \ tcpnice \ tracepath \ tune2fs \ + udevadm \ + umount \ + umount.linux \ unace \ unpack200 \ unrar \ @@ -298,11 +313,13 @@ bashcomp_DATA = a2x \ useradd \ userdel \ usermod \ + valgrind \ vipw \ vncviewer \ vpnc \ watch \ webmitm \ + wine \ withlist \ wodim \ wol \ @@ -333,6 +350,7 @@ CLEANFILES = \ alternatives \ animate \ apropos \ + arm-koji \ asciidoc.py \ autoheader \ automake-1.11 \ @@ -424,7 +442,6 @@ CLEANFILES = \ pccardctl \ perldoc \ phing \ - pidof \ pigz \ pinfo \ ping6 \ @@ -435,6 +452,7 @@ CLEANFILES = \ pm-suspend-hybrid \ pmake \ postalias \ + ppc-koji \ puppetca \ puppetd \ puppetdoc \ @@ -464,6 +482,7 @@ CLEANFILES = \ rpm2txz \ rpmbuild \ rpmbuild-md5 \ + s390-koji \ sbcl-mt \ scp \ sdptool \ @@ -476,12 +495,12 @@ CLEANFILES = \ smbpasswd \ smbtar \ smbtree \ + sparc-koji \ spovray \ stream \ tightvncviewer \ tracepath6 \ typeset \ - umount \ vgcfgbackup \ vgcfgrestore \ vgchange \ @@ -624,9 +643,9 @@ symlinks: rm -f $(targetdir)/$$file && \ $(LN_S) java $(targetdir)/$$file ; \ done - for file in pkill ; do \ + for file in arm-koji ppc-koji s390-koji sparc-koji ; do \ rm -f $(targetdir)/$$file && \ - $(LN_S) killall $(targetdir)/$$file ; \ + $(LN_S) koji $(targetdir)/$$file ; \ done for file in ldapadd ldapmodify ldapdelete ldapcompare ldapmodrdn \ ldapwhoami ldappasswd ; do \ @@ -658,10 +677,6 @@ symlinks: rm -f $(targetdir)/$$file && \ $(LN_S) mcrypt $(targetdir)/$$file ; \ done - for file in umount ; do \ - rm -f $(targetdir)/$$file && \ - $(LN_S) mount $(targetdir)/$$file ; \ - done for file in mplayer2 mencoder gmplayer kplayer ; do \ rm -f $(targetdir)/$$file && \ $(LN_S) mplayer $(targetdir)/$$file ; \ @@ -682,10 +697,6 @@ symlinks: rm -f $(targetdir)/$$file && \ $(LN_S) perl $(targetdir)/$$file ; \ done - for file in pidof ; do \ - rm -f $(targetdir)/$$file && \ - $(LN_S) pgrep $(targetdir)/$$file ; \ - done for file in alpine ; do \ rm -f $(targetdir)/$$file && \ $(LN_S) pine $(targetdir)/$$file ; \ @@ -698,6 +709,10 @@ symlinks: rm -f $(targetdir)/$$file && \ $(LN_S) pkg_delete $(targetdir)/$$file ; \ done + for file in pkill ; do \ + rm -f $(targetdir)/$$file && \ + $(LN_S) pgrep $(targetdir)/$$file ; \ + done for file in pm-suspend pm-suspend-hybrid ; do \ rm -f $(targetdir)/$$file && \ $(LN_S) pm-hibernate $(targetdir)/$$file ; \ diff --git a/completions/Makefile.in b/completions/Makefile.in index 16d05310..b7e1bd1f 100644 --- a/completions/Makefile.in +++ b/completions/Makefile.in @@ -163,6 +163,7 @@ bashcomp_DATA = a2x \ autoreconf \ autorpm \ autoscan \ + avctrl \ badblocks \ bk \ brctl \ @@ -171,6 +172,7 @@ bashcomp_DATA = a2x \ cal \ cancel \ cardctl \ + ccache \ cfagent \ cfrun \ chage \ @@ -196,14 +198,16 @@ bashcomp_DATA = a2x \ cpio \ cppcheck \ crontab \ - curl \ cryptsetup \ + curl \ cvs \ cvsps \ dd \ + desktop-file-validate \ dhclient \ dict \ dmesg \ + dnsspoof \ dot \ dpkg \ dpkg-source \ @@ -255,8 +259,10 @@ bashcomp_DATA = a2x \ hddtemp \ hid2hci \ hping2 \ + htop \ htpasswd \ iconv \ + id \ idn \ iftop \ ifup \ @@ -267,9 +273,10 @@ bashcomp_DATA = a2x \ invoke-rc.d \ ionice \ ip \ - iptables \ + iperf \ ipmitool \ ipsec \ + iptables \ ipv6calc \ iscsiadm \ isql \ @@ -288,6 +295,7 @@ bashcomp_DATA = a2x \ killall \ kldload \ kldunload \ + koji \ ktutil \ larch \ lastlog \ @@ -309,6 +317,7 @@ bashcomp_DATA = a2x \ lrzip \ lsof \ lvm \ + lzip \ lzma \ lzop \ macof \ @@ -329,6 +338,7 @@ bashcomp_DATA = a2x \ mmsitepass \ monodevelop \ mount \ + mount.linux \ mplayer \ msynctool \ mtx \ @@ -340,6 +350,7 @@ bashcomp_DATA = a2x \ mysql \ mysqladmin \ ncftp \ + nethogs \ newgrp \ newlist \ newusers \ @@ -352,11 +363,13 @@ bashcomp_DATA = a2x \ passwd \ perl \ pgrep \ + pidof \ pine \ ping \ pkg-config \ pkg_delete \ pkgtool \ + plague-client \ pm-hibernate \ pm-is-supported \ pm-powersave \ @@ -386,8 +399,8 @@ bashcomp_DATA = a2x \ remove_members \ removepkg \ renice \ - reptyr \ reportbug \ + reptyr \ resolvconf \ rfkill \ ri \ @@ -404,7 +417,6 @@ bashcomp_DATA = a2x \ sbcl \ sbopkg \ screen \ - service \ sh \ sitecopy \ slackpkg \ @@ -430,6 +442,9 @@ bashcomp_DATA = a2x \ tcpnice \ tracepath \ tune2fs \ + udevadm \ + umount \ + umount.linux \ unace \ unpack200 \ unrar \ @@ -441,11 +456,13 @@ bashcomp_DATA = a2x \ useradd \ userdel \ usermod \ + valgrind \ vipw \ vncviewer \ vpnc \ watch \ webmitm \ + wine \ withlist \ wodim \ wol \ @@ -476,6 +493,7 @@ CLEANFILES = \ alternatives \ animate \ apropos \ + arm-koji \ asciidoc.py \ autoheader \ automake-1.11 \ @@ -567,7 +585,6 @@ CLEANFILES = \ pccardctl \ perldoc \ phing \ - pidof \ pigz \ pinfo \ ping6 \ @@ -578,6 +595,7 @@ CLEANFILES = \ pm-suspend-hybrid \ pmake \ postalias \ + ppc-koji \ puppetca \ puppetd \ puppetdoc \ @@ -607,6 +625,7 @@ CLEANFILES = \ rpm2txz \ rpmbuild \ rpmbuild-md5 \ + s390-koji \ sbcl-mt \ scp \ sdptool \ @@ -619,12 +638,12 @@ CLEANFILES = \ smbpasswd \ smbtar \ smbtree \ + sparc-koji \ spovray \ stream \ tightvncviewer \ tracepath6 \ typeset \ - umount \ vgcfgbackup \ vgcfgrestore \ vgchange \ @@ -971,9 +990,9 @@ symlinks: rm -f $(targetdir)/$$file && \ $(LN_S) java $(targetdir)/$$file ; \ done - for file in pkill ; do \ + for file in arm-koji ppc-koji s390-koji sparc-koji ; do \ rm -f $(targetdir)/$$file && \ - $(LN_S) killall $(targetdir)/$$file ; \ + $(LN_S) koji $(targetdir)/$$file ; \ done for file in ldapadd ldapmodify ldapdelete ldapcompare ldapmodrdn \ ldapwhoami ldappasswd ; do \ @@ -1005,10 +1024,6 @@ symlinks: rm -f $(targetdir)/$$file && \ $(LN_S) mcrypt $(targetdir)/$$file ; \ done - for file in umount ; do \ - rm -f $(targetdir)/$$file && \ - $(LN_S) mount $(targetdir)/$$file ; \ - done for file in mplayer2 mencoder gmplayer kplayer ; do \ rm -f $(targetdir)/$$file && \ $(LN_S) mplayer $(targetdir)/$$file ; \ @@ -1029,10 +1044,6 @@ symlinks: rm -f $(targetdir)/$$file && \ $(LN_S) perl $(targetdir)/$$file ; \ done - for file in pidof ; do \ - rm -f $(targetdir)/$$file && \ - $(LN_S) pgrep $(targetdir)/$$file ; \ - done for file in alpine ; do \ rm -f $(targetdir)/$$file && \ $(LN_S) pine $(targetdir)/$$file ; \ @@ -1045,6 +1056,10 @@ symlinks: rm -f $(targetdir)/$$file && \ $(LN_S) pkg_delete $(targetdir)/$$file ; \ done + for file in pkill ; do \ + rm -f $(targetdir)/$$file && \ + $(LN_S) pgrep $(targetdir)/$$file ; \ + done for file in pm-suspend pm-suspend-hybrid ; do \ rm -f $(targetdir)/$$file && \ $(LN_S) pm-hibernate $(targetdir)/$$file ; \ diff --git a/completions/_mock b/completions/_mock index cb7d6571..020b39b4 100644 --- a/completions/_mock +++ b/completions/_mock @@ -12,7 +12,7 @@ _mock() local cfgdir=/etc/mock count=0 i for i in "${words[@]}" ; do - [ $count -eq $cword ] && break + [[ $count -eq $cword ]] && break if [[ "$i" == --configdir ]] ; then cfgdir="${words[((count+1))]}" elif [[ "$i" == --configdir=* ]] ; then diff --git a/completions/_modules b/completions/_modules index 6f337a90..b5a1d94a 100644 --- a/completions/_modules +++ b/completions/_modules @@ -49,7 +49,7 @@ _module () local cur prev words cword _init_completion || return - if [ $cword -eq 1 ] ; then + if [[ $cword -eq 1 ]]; then # First parameter on line -- we expect it to be a mode selection local options @@ -58,7 +58,7 @@ _module () COMPREPLY=( $(compgen -W "$options" -- "$cur") ) - elif [ $cword -eq 2 ] ; then + elif [[ $cword -eq 2 ]]; then case $prev in add|display|help|load|show|whatis) COMPREPLY=( $(_module_avail "$cur") ) @@ -70,7 +70,7 @@ _module () COMPREPLY=( $(_module_path "$cur") ) ;; esac - elif [ $cword -eq 3 ] ; then + elif [[ $cword -eq 3 ]]; then case ${words[1]} in swap|switch) COMPREPLY=( $(_module_avail "$cur") ) diff --git a/completions/_yum b/completions/_yum index c2d37948..9860c540 100644 --- a/completions/_yum +++ b/completions/_yum @@ -45,7 +45,7 @@ _yum() fi done - if [ -n "$special" ]; then + if [[ -n $special ]]; then # TODO: install|update|upgrade should not match *src.rpm if [[ "$cur" == @(*/|[.~])* && \ "$special" == @(deplist|install|update|upgrade) ]]; then diff --git a/completions/ant b/completions/ant index 96ef8172..dd3606dc 100644 --- a/completions/ant +++ b/completions/ant @@ -45,7 +45,7 @@ _ant() break fi done - [ ! -f $buildfile ] && return 0 + [[ ! -f $buildfile ]] && return 0 # parse buildfile for targets local line targets diff --git a/completions/apt-build b/completions/apt-build index aa78b230..8e593131 100644 --- a/completions/apt-build +++ b/completions/apt-build @@ -12,7 +12,7 @@ _apt_build() fi done - if [ -n "$special" ]; then + if [[ -n $special ]]; then case $special in install|source|info) COMPREPLY=( $( apt-cache pkgnames "$cur" 2> /dev/null ) ) diff --git a/completions/apt-cache b/completions/apt-cache index 00b41478..3e2ca0db 100644 --- a/completions/apt-cache +++ b/completions/apt-cache @@ -6,7 +6,7 @@ _apt_cache() _init_completion || return local special i - if [ "$cur" != show ]; then + if [[ $cur != show ]]; then for (( i=0; i < ${#words[@]}-1; i++ )); do if [[ ${words[i]} == @(add|depends|dotty|madison|policy|rdepends|show?(pkg|src|)) ]]; then special=${words[i]} @@ -15,7 +15,7 @@ _apt_cache() fi - if [ -n "$special" ]; then + if [[ -n $special ]]; then case $special in add) _filedir diff --git a/completions/apt-get b/completions/apt-get index 447305a4..a6c902e1 100644 --- a/completions/apt-get +++ b/completions/apt-get @@ -12,10 +12,10 @@ _apt_get() fi done - if [ -n "$special" ]; then + if [[ -n $special ]]; then case $special in remove|autoremove|purge) - if [ -f /etc/debian_version ]; then + if [[ -f /etc/debian_version ]]; then # Debian system COMPREPLY=( $( \ _xfunc dpkg _comp_dpkg_installed_packages $cur ) ) diff --git a/completions/avctrl b/completions/avctrl new file mode 100644 index 00000000..bac38cd6 --- /dev/null +++ b/completions/avctrl @@ -0,0 +1,20 @@ +# avctrl completion -*- shell-script -*- + +_avctrl() +{ + local cur prev words cword + _init_completion || return + + if [[ "$cur" == -* ]]; then + COMPREPLY=( $( compgen -W '--help --quiet' -- "$cur" ) ) + else + local args + _count_args + if [[ $args -eq 1 ]]; then + COMPREPLY=( $( compgen -W 'discover switch' -- "$cur" ) ) + fi + fi +} && +complete -F _avctrl avctrl + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/cardctl b/completions/cardctl index 0532d6ef..90837269 100644 --- a/completions/cardctl +++ b/completions/cardctl @@ -5,7 +5,7 @@ _cardctl() local cur prev words cword _init_completion || return - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then COMPREPLY=( $( compgen -W 'status config ident suspend \ resume reset eject insert scheme' -- "$cur" ) ) fi diff --git a/completions/ccache b/completions/ccache new file mode 100644 index 00000000..63f5a1c6 --- /dev/null +++ b/completions/ccache @@ -0,0 +1,26 @@ +# ccache(1) completion -*- shell-script -*- + +_ccache() +{ + local cur prev words cword split + _init_completion -s || return + + if [[ $COMP_CWORD -eq 1 && ${COMP_WORDS[COMP_CWORD]} != -* ]]; then + _command_offset 1 + return + fi + + case $prev in + -h|--help|-V|--version|-F|--max-files|-M|--max-size) + return + ;; + esac + + $split && return + + COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) + [[ $COMPREPLY == *= ]] && compopt -o nospace +} && +complete -F _ccache ccache + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/cfrun b/completions/cfrun index 288bcf43..0be44132 100644 --- a/completions/cfrun +++ b/completions/cfrun @@ -31,7 +31,7 @@ _cfrun() break fi done - [ ! -f $hostfile ] && return 0 + [[ ! -f $hostfile ]] && return 0 COMPREPLY=( $(compgen -W "$( command grep -v \ -E '(=|^$|^#)' $hostfile )" -- "$cur" ) ) diff --git a/completions/chkconfig b/completions/chkconfig index 31a575e3..b1dd925e 100644 --- a/completions/chkconfig +++ b/completions/chkconfig @@ -8,6 +8,7 @@ _chkconfig() case $prev in --level=[1-6]|[1-6]|--list|--add|--del|--override) _services + _xinetd_services return 0 ;; --level) @@ -19,12 +20,15 @@ _chkconfig() $split && return 0 if [[ "$cur" == -* ]]; then - COMPREPLY=( $( compgen -W '--list --add --del --override --level' -- "$cur" ) ) + COMPREPLY=( $( compgen -W '--list --add --del --override --level' \ + -- "$cur" ) ) else if [[ $cword -eq 2 || $cword -eq 4 ]]; then - COMPREPLY=( $( compgen -W 'on off reset resetpriorities' -- "$cur" ) ) + COMPREPLY=( $( compgen -W 'on off reset resetpriorities' \ + -- "$cur" ) ) else _services + _xinetd_services fi fi } && diff --git a/completions/cksfv b/completions/cksfv index d21bcf39..eabe3730 100644 --- a/completions/cksfv +++ b/completions/cksfv @@ -5,7 +5,7 @@ _cksfv() local cur prev words cword _init_completion || return - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) return 0 fi diff --git a/completions/configure b/completions/configure index 8e28d451..2337c497 100644 --- a/completions/configure +++ b/completions/configure @@ -26,7 +26,7 @@ _configure() # --option=SETTING will include 'SETTING' as a contextual hint [[ "$cur" != -* ]] && return 0 - if [ -n "$COMP_CONFIGURE_HINTS" ]; then + if [[ -n $COMP_CONFIGURE_HINTS ]]; then COMPREPLY=( $( compgen -W "$( $1 --help 2>&1 | \ awk '/^ --[A-Za-z]/ { print $1; \ if ($2 ~ /--[A-Za-z]/) print $2 }' | sed -e 's/[[,].*//g' )" \ diff --git a/completions/cowsay b/completions/cowsay index 47c2e52c..8e96b91e 100644 --- a/completions/cowsay +++ b/completions/cowsay @@ -7,7 +7,8 @@ _cowsay() case $prev in -f) - COMPREPLY=( $( compgen -W '$( cowsay -l | tail -n +2)' -- "$cur" ) ) + COMPREPLY=( $( compgen -W \ + '$( cowsay -l 2>/dev/null | tail -n +2 )' -- "$cur" ) ) return 0 ;; esac diff --git a/completions/cpio b/completions/cpio index ebbe5c57..45824007 100644 --- a/completions/cpio +++ b/completions/cpio @@ -33,7 +33,7 @@ _cpio() $split && return 0 - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then COMPREPLY=( $( compgen -W '-o --create -i --extract -p --pass-through \ -? --help --license --usage --version' -- "$cur" ) ) else diff --git a/completions/cppcheck b/completions/cppcheck index 5dd30931..d3c7a422 100644 --- a/completions/cppcheck +++ b/completions/cppcheck @@ -7,16 +7,24 @@ _cppcheck() case $prev in --append|--exitcode-suppressions|--file-list|--rule-file|\ - --suppressions-list|-i) + --suppressions-list|--includes-file|-i) _filedir return ;; - -D|--rule|--suppress|--template) + -D|-U|--rule|--suppress|--template|--max-configs) return ;; --enable) + # split comma-separated list + split=false + if [[ "$cur" == ?*,* ]]; then + prev="${cur%,*}" + cur="${cur##*,}" + split=true + fi COMPREPLY=( $( compgen -W 'all style performance portability information unusedFunction missingInclude' -- "$cur" ) ) + $split && COMPREPLY=( ${COMPREPLY[@]/#/"$prev,"} ) return ;; --error-exitcode) @@ -28,11 +36,11 @@ _cppcheck() return ;; -j) - COMPREPLY=( $( compgen -W '{2..16}' -- "$cur" ) ) + COMPREPLY=( $( compgen -W "{2..$(_ncpus)}" -- "$cur" ) ) return ;; --std) - COMPREPLY=( $( compgen -W 'c99 posix' -- "$cur" ) ) + COMPREPLY=( $( compgen -W 'c99 c++11 posix' -- "$cur" ) ) return ;; --platform) @@ -52,7 +60,7 @@ _cppcheck() COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) [[ $COMPREPLY == *= ]] && compopt -o nospace else - _filedir @(cpp|cxx|cc|c++|c|tpp|txx) + _filedir @(cpp|cxx|cc|c++|c|h|hpp|hxx|h++|tpp|txx) fi } && complete -F _cppcheck cppcheck diff --git a/completions/cryptsetup b/completions/cryptsetup index 2bbdc952..fb390214 100644 --- a/completions/cryptsetup +++ b/completions/cryptsetup @@ -28,7 +28,7 @@ _cryptsetup() local arg _get_first_arg - if [ -z $arg ]; then + if [[ -z $arg ]]; then if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) [[ $COMPREPLY == *= ]] && compopt -o nospace diff --git a/completions/curl b/completions/curl index f0fc6acf..6b56aa57 100644 --- a/completions/curl +++ b/completions/curl @@ -6,18 +6,20 @@ _curl() _init_completion || return case $prev in - --ciphers|--connect-timeout|-C|--continue-at|--form|--form-string|\ + --ciphers|--connect-timeout|-C|--continue-at|-F|--form|--form-string|\ --ftp-account|--ftp-alternative-to-user|-P|--ftp-port|-H|--header|-h|\ --help|--hostpubmd5|--keepalive-time|--krb|--limit-rate|--local-port|\ --mail-from|--mail-rcpt|--max-filesize|--max-redirs|-m|--max-time|\ --pass|--proto|--proto-redir|--proxy-user|--proxy1.0|-Q|--quote|-r|\ --range|-X|--request|--retry|--retry-delay|--retry-max-time|\ --socks5-gssapi-service|-t|--telnet-option|--tftp-blksize|-z|\ - --time-cond|--url|-u|--user|-A|--user-agent|-V|--version|-w|--write-out) + --time-cond|--url|-u|--user|-A|--user-agent|-V|--version|-w|\ + --write-out|--resolve|--tlsuser|--tlspassword) return ;; -K|--config|-b|--cookie|-c|--cookie-jar|-D|--dump-header|--egd-file|\ - --key|--libcurl|-o|--output|--random-file|-T|--upload-file) + --key|--libcurl|-o|--output|--random-file|-T|--upload-file|--trace|\ + --trace-ascii|--netrc-file) _filedir return ;; @@ -45,6 +47,10 @@ _curl() fi return ;; + --delegation) + COMPREPLY=( $( compgen -W 'none policy always' -- "$cur" ) ) + return + ;; --engine) COMPREPLY=( $( compgen -W 'list' -- "$cur" ) ) return @@ -74,6 +80,10 @@ _curl() _filedir return ;; + --tlsauthtype) + COMPREPLY=( $( compgen -W 'SRP' -- "$cur" ) ) + return + ;; esac if [[ $cur == -* ]]; then diff --git a/completions/cvs b/completions/cvs index bafe1901..4613742a 100644 --- a/completions/cvs +++ b/completions/cvs @@ -13,7 +13,7 @@ _cvs_entries() _cvs_modules() { - if [ -n "$prefix" ]; then + if [[ -n $prefix ]]; then COMPREPLY=( $( command ls -d ${cvsroot}/${prefix}/!(CVSROOT) ) ) else COMPREPLY=( $( command ls -d ${cvsroot}/!(CVSROOT) ) ) @@ -39,9 +39,8 @@ _cvs_roots() { local -a cvsroots cvsroots=( $CVSROOT ) - [ -r ~/.cvspass ] && \ - cvsroots+=( $( awk '{ print $2 }' ~/.cvspass ) ) - [ -r CVS/Root ] && mapfile -tO ${#cvsroots[@]} cvsroots < CVS/Root + [[ -r ~/.cvspass ]] && cvsroots+=( $( awk '{ print $2 }' ~/.cvspass ) ) + [[ -r CVS/Root ]] && mapfile -tO ${#cvsroots[@]} cvsroots < CVS/Root COMPREPLY=( $( compgen -W '${cvsroots[@]}' -- "$cur" ) ) __ltrim_colon_completions "$cur" } @@ -56,12 +55,12 @@ _cvs() count=0 for i in "${words[@]}"; do - [ $count -eq $cword ] && break + [[ $count -eq $cword ]] && break # Last parameter was the CVSROOT, now go back to mode selection if [[ "${words[((count))]}" == "$cvsroot" && "$mode" == cvsroot ]]; then mode="" fi - if [ -z "$mode" ]; then + if [[ -z $mode ]]; then case $i in -H|--help) COMPREPLY=( $( compgen -W "$( _cvs_commands )" -- "$cur" ) ) @@ -152,7 +151,7 @@ _cvs() if [[ "$cur" != -* ]]; then _cvs_entries - [ -z "$cur" ] && files=( !(CVS) ) || \ + [[ -z $cur ]] && files=( !(CVS) ) || \ files=( $( command ls -d ${cur}* 2>/dev/null ) ) local f for i in ${!files[@]}; do @@ -221,7 +220,7 @@ _cvs() esac if [[ "$cur" != -* ]]; then - [ -z "$cvsroot" ] && cvsroot=$CVSROOT + [[ -z $cvsroot ]] && cvsroot=$CVSROOT COMPREPLY=( $( cvs -d "$cvsroot" co -c 2> /dev/null | \ awk '{print $1}' ) ) COMPREPLY=( $( compgen -W '${COMPREPLY[@]}' -- "$cur" ) ) @@ -244,7 +243,7 @@ _cvs() # 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 + 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 @@ -298,7 +297,7 @@ _cvs() esac if [[ "$cur" != -* ]]; then - [ -z "$cvsroot" ] && cvsroot=$CVSROOT + [[ -z $cvsroot ]] && cvsroot=$CVSROOT COMPREPLY=( $( cvs -d "$cvsroot" co -c | awk '{print $1}' ) ) COMPREPLY=( $( compgen -W '${COMPREPLY[@]}' -- "$cur" ) ) else @@ -318,9 +317,9 @@ _cvs() if [[ "$cur" != -* ]]; then # starts with same algorithm as checkout - [ -z "$cvsroot" ] && cvsroot=$CVSROOT + [[ -z $cvsroot ]] && cvsroot=$CVSROOT local prefix=${cur%/*} - if [ -r ${cvsroot}/${prefix} ]; then + if [[ -r ${cvsroot}/${prefix} ]]; then _cvs_modules COMPREPLY=( ${COMPREPLY[@]#$cvsroot} ) COMPREPLY=( ${COMPREPLY[@]#\/} ) @@ -337,7 +336,7 @@ _cvs() _cvs_entries # find out what files are missing for i in "${entries[@]}"; do - [ ! -r "$i" ] && miss+=( $i ) + [[ ! -r $i ]] && miss+=( $i ) done COMPREPLY=( $( compgen -W '${miss[@]:-}' -- "$cur" ) ) else diff --git a/completions/desktop-file-validate b/completions/desktop-file-validate new file mode 100644 index 00000000..faae6c37 --- /dev/null +++ b/completions/desktop-file-validate @@ -0,0 +1,23 @@ +# desktop-file-validate completion -*- shell-script -*- + +_desktop_file_validate() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) + return + fi + + _filedir desktop +} && +complete -F _desktop_file_validate desktop-file-validate + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/dict b/completions/dict index a31816d3..a2ecd9b1 100644 --- a/completions/dict +++ b/completions/dict @@ -17,17 +17,17 @@ _dict() case ${words[i]} in -h|--host) host=${words[i+1]} - [ -n "$host" ] && host="-h $host" + [[ -n $host ]] && host="-h $host" i=$((++i)) ;; -p|--port) port=${words[i+1]} - [ -n "$port" ] && port="-p $port" + [[ -n $port ]] && port="-p $port" i=$((++i)) ;; -d|--database) db=${words[i+1]} - [ -n "$db" ] && host="-d $db" + [[ -n $db ]] && host="-d $db" i=$((++i)) ;; *) @@ -54,8 +54,17 @@ _dict() esac local dictfile=/usr/share/dict/words - [ -r $dictfile ] && \ - COMPREPLY=( $( compgen -W '$( cat $dictfile )' -- "$cur" ) ) + if [[ -r $dictfile ]]; then + # Dictfile may be too large for practical compgen -W usage, so narrow + # it down with grep if $cur looks like something that's safe to embed + # in a pattern instead. + if [[ $cur == +([-A-Za-z0-9/.]) ]]; then + COMPREPLY=( $( compgen -W \ + '$( command grep "^${cur//./\\.}" $dictfile )' -- "$cur" ) ) + else + COMPREPLY=( $( compgen -W '$( cat $dictfile )' -- "$cur" ) ) + fi + fi } && complete -F _dict -o default dict rdict diff --git a/completions/dmesg b/completions/dmesg index 5fb28e45..7d73bf3a 100644 --- a/completions/dmesg +++ b/completions/dmesg @@ -8,17 +8,24 @@ _dmesg() _init_completion || return case $prev in - -s|-M|-N) + -h|--help|-V|--version|-s|--buffer-size|-M|-N) return ;; - -n) + -f|--facility) + COMPREPLY=( $( compgen -W 'kern user mail daemon auth syslog lpr + news' -- "$cur" ) ) + return + ;; + -l|--level|-n|--console-level) COMPREPLY=( $( compgen -W '{1..8}' -- "$cur" ) ) return ;; esac if [[ $cur == -* ]]; then - COMPREPLY=( $( compgen -W '$( _parse_usage "$1" )' -- "$cur" ) ) + local opts=$( _parse_help "$1" ) + [[ $opts ]] || opts=$( _parse_usage "$1" ) + COMPREPLY=( $( compgen -W "$opts" -- "$cur" ) ) return fi } && diff --git a/completions/dnsspoof b/completions/dnsspoof new file mode 100644 index 00000000..39bc47eb --- /dev/null +++ b/completions/dnsspoof @@ -0,0 +1,26 @@ +# dnsspoof completion -*- shell-script -*- + +_dnsspoof() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -i) + _interfaces + return 0 + ;; + -f) + _filedir + return 0 + ;; + esac + + if [[ "$cur" == -* ]]; then + COMPREPLY=( $( compgen -W '$( _parse_usage "$1" )' -- "$cur" ) ) + fi + +} && +complete -F _dnsspoof dnsspoof + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/dpkg b/completions/dpkg index 247171c5..b1b34e17 100644 --- a/completions/dpkg +++ b/completions/dpkg @@ -7,6 +7,22 @@ _comp_dpkg_installed_packages() } } || { _comp_dpkg_installed_packages() +{ + command grep -A 1 "Package: $1" /var/lib/dpkg/status | \ + command grep -B 1 -Ee "ok installed|half-installed|unpacked| \ + half-configured" \ + -Ee "^Essential: yes" | \ + command grep "Package: $1" | cut -d\ -f2 +} +} + +_have grep-status && { +_comp_dpkg_purgeable_packages() +{ + grep-status -P -e "^$1" -a -FStatus 'install ok installed' -o -FStatus 'deinstall ok config-files' -n -s Package +} +} || { +_comp_dpkg_purgeable_packages() { command grep -A 1 "Package: $1" /var/lib/dpkg/status | \ command grep -B 1 -Ee "ok installed|half-installed|unpacked| \ @@ -54,10 +70,14 @@ _dpkg() _filedir return 0 ;; - -r|-L|-P|--remove|--purge|--listfiles) + -r|--remove) COMPREPLY=( $( _comp_dpkg_installed_packages "$cur" ) ) return 0 ;; + -L|-P|--listfiles|--purge) + COMPREPLY=( $( _comp_dpkg_purgeable_packages "$cur" ) ) + return 0 + ;; esac $split && return diff --git a/completions/e2label b/completions/e2label index 86008d9f..94bcc1c8 100644 --- a/completions/e2label +++ b/completions/e2label @@ -5,7 +5,7 @@ _e2label() local cur prev words cword _init_completion || return - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then cur=${cur:=/dev/} _filedir fi diff --git a/completions/export b/completions/export index 557c52cb..42273a9e 100644 --- a/completions/export +++ b/completions/export @@ -3,23 +3,59 @@ _export() { local cur prev words cword - _init_completion || return + _init_completion -n = || return - case ${words[@]} in - *=\$*) - COMPREPLY=( $( compgen -v -P '$' -- "${cur#*=\$}" ) ) + local i action=variable remove=false + for (( i=1; i < cword; i++ )); do + case ${words[i]} in + -p) + return + ;; + -*f*) + action=function + ;;& + -*n*) + remove=true + ;; + -*) + continue + ;; + esac + break + done + + [[ $cur == *=\$* ]] && { cur=${cur#*=}; _variables; } && return + + case $cur in + *=) + local pval=$( quote "$( eval printf %s \"\$${cur%=}\" )" ) + # Complete previous value if it's not empty. + if [[ $pval != \'\' ]]; then + COMPREPLY=( "$pval" ) + else + cur=${cur#*=} + _filedir + fi ;; - *[^=]) - COMPREPLY=( $( compgen -v -S '=' -- "$cur" ) ) + *=*) + cur=${cur#*=} + _filedir ;; - *=) - COMPREPLY=( "$( eval echo -n \"$`echo ${cur%=}`\" | - ( echo -n \' - sed -e 's/'\''/'\''\\\'\'''\''/g' - echo -n \' ) )" ) + *) + if [[ $cword -eq 1 && $cur == -* ]]; then + COMPREPLY=( $( compgen -W \ + '-p $( _parse_usage "$1" )' -- "$cur" ) ) + return + fi + local suffix + if ! $remove; then + suffix+== + compopt -o nospace + fi + COMPREPLY=( $( compgen -A $action -S "$suffix" -- "$cur" ) ) ;; esac } && -complete -F _export -o default -o nospace export +complete -F _export export # ex: ts=4 sw=4 et filetype=sh diff --git a/completions/fbgs b/completions/fbgs index 672de7cd..93dbe392 100644 --- a/completions/fbgs +++ b/completions/fbgs @@ -28,8 +28,8 @@ _fbgs() esac if [[ "$cur" == -* ]]; then - COMPREPLY=( $(compgen -W '-l -xl -xxl -a --fitwidth -d -m -t -g -f -p \ - -h -c' -- "$cur") ) + COMPREPLY=( $( compgen -W '-l -xl -xxl -a --fitwidth -d -m -t -g -f -p + -h -c' -- "$cur" ) ) [[ $COMPREPLY ]] && return fi diff --git a/completions/fbi b/completions/fbi index f8f7a825..9516247b 100644 --- a/completions/fbi +++ b/completions/fbi @@ -11,12 +11,12 @@ _fbi() return ;; -r|--resolution) - COMPREPLY+=( $(compgen -W '{1..5}') ) + COMPREPLY+=( $( compgen -W '{1..5}' ) ) return ;; -f|--font) local IFS=$'\n' - COMPREPLY=( $( compgen -W '$( fc-list 2>/dev/null )' -- "$cur" ) ) + COMPREPLY=( $( compgen -W '$( fc-list 2> /dev/null )' -- "$cur" ) ) return ;; -m|--mode) @@ -36,13 +36,12 @@ _fbi() esac if [[ "$cur" == -* ]]; then - COMPREPLY=( $(compgen -W '--help --version --store --list --text \ - --autozoom --autoup --noautoup --autodown --noautodown --fitwidth \ - --nofitwidth --verbose --noverbose --random --norandom --comments \ - --nocomments --edit --noedit --backup --nobackup --preserve \ - --nopreserve --readahead --noreadahead --cachemem --blend --vt \ - --scroll --timeout --once --noonce --resolution --gamma --font \ - --device --mode' -- "$cur") ) + COMPREPLY=( $( compgen -W '--help --version --store --list --text + --autozoom --{,no}autoup --{,no}autodown --{,no}fitwidth + --{,no}verbose --{,no}random --{,no}comments --{,no}edit + --{,no}backup --{,no}preserve --{,no}readahead --cachemem --blend + --vt --scroll --timeout --{,no}once --resolution --gamma --font + --device --mode' -- "$cur" ) ) [[ $COMPREPLY ]] && return fi diff --git a/completions/feh b/completions/feh index e39b5c31..0f34f94b 100644 --- a/completions/feh +++ b/completions/feh @@ -25,12 +25,12 @@ _feh() -e|--font|-M|--menu-font|-@|--title-font) # expect string like "dejavu.ttf/12" if [[ "$cur" == */* ]]; then # expect integer value - COMPREPLY=( $(compgen -P "$cur" -W '{0..9}') ) + COMPREPLY=( $( compgen -P "$cur" -W '{0..9}' ) ) compopt -o nospace return fi local font_path - # font_path="$(imlib2-config --prefix 2> /dev/null)/share/imlib2/data/fonts" + # font_path="$( imlib2-config --prefix 2> /dev/null )/share/imlib2/data/fonts" # COMPREPLY=( $( cd "$font_path" 2> /dev/null; compgen -f \ # -X "!*.@([tT][tT][fF])" -S / -- "$cur" ) ) for (( i=${#words[@]}-1; i>0; i-- )); do @@ -46,7 +46,7 @@ _feh() -T|--theme) local conf_path=~/.config/feh/themes local theme_name theme_opts - [ -r "$conf_path" ] || return + [[ -r $conf_path ]] || return while read theme_name theme_opts; do if [[ "$theme_name" == '#'* || "$theme_name" == "" ]]; then continue @@ -63,15 +63,15 @@ _feh() -R|--reload|-H|--limit-height|-W|--limit-width|-E|--thumb-height|\ -y|--thumb-width|-J|--thumb-redraw) # expect integer value - COMPREPLY+=( $(compgen -W '{0..9}') ) + COMPREPLY+=( $( compgen -W '{0..9}' ) ) compopt -o nospace return ;; --zoom) # expect integer value or "max", "fill" - COMPREPLY=( $(compgen -W 'max fill' -- "$cur") ) + COMPREPLY=( $( compgen -W 'max fill' -- "$cur" ) ) if [[ ! $cur || ! $COMPREPLY ]]; then - COMPREPLY+=( $(compgen -W '{0..9}') ) + COMPREPLY+=( $( compgen -W '{0..9}' ) ) compopt -o nospace fi return @@ -95,7 +95,7 @@ _feh() if [[ $cur && "$cur" != *x* ]]; then COMPREPLY=( x ) fi - COMPREPLY+=( $(compgen -W "{0..9}") ) + COMPREPLY+=( $( compgen -W "{0..9}" ) ) compopt -o nospace return ;; diff --git a/completions/function b/completions/function index 6156e63d..e8e4d751 100644 --- a/completions/function +++ b/completions/function @@ -6,12 +6,12 @@ _function() _init_completion || return if [[ $1 == @(declare|typeset) ]]; then - if [ "$prev" = -f ]; then + if [[ $prev == -f ]]; then COMPREPLY=( $( compgen -A function -- "$cur" ) ) elif [[ "$cur" == -* ]]; then - COMPREPLY=( $( compgen -W '-a -f -F -i -r -x -p' -- "$cur" ) ) + COMPREPLY=( $( compgen -W '$( _parse_usage "$1" )' -- "$cur" ) ) fi - elif [ $cword -eq 1 ]; then + elif [[ $cword -eq 1 ]]; then COMPREPLY=( $( compgen -A function -- "$cur" ) ) else COMPREPLY=( "() $( type -- ${words[1]} | sed -e 1,2d )" ) diff --git a/completions/gcc b/completions/gcc index bafb81b7..c86fd7e6 100644 --- a/completions/gcc +++ b/completions/gcc @@ -38,17 +38,17 @@ _gcc() # sink stderr: # for C/C++/ObjectiveC it's useless # for FORTRAN/Java it's an error - COMPREPLY=( $( compgen -W "$( $cc --help 2>/dev/null | \ - tr '\t' ' ' | \ - sed -e '/^ *-/!d' -e 's/ *-\([^ ]*\).*/-\1/' | \ - sort -u )" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "$( $cc --help 2>/dev/null | tr '\t' ' ' |\ + sed -e '/^ *-/!d' -e 's/ *-\([^][ <>]*\).*/-\1/' )" -- "$cur" ) ) + [[ $COMPREPLY == *= ]] && compopt -o nospace else _filedir fi } && -complete -F _gcc gcc g++ c++ g77 gcj gpc - -[[ $OSTYPE == *cygwin* ]] || _userland GNU && _have gcc && \ - complete -F _gcc cc || : +complete -F _gcc gcc g++ g77 gcj gpc && +{ + cc --version 2>/dev/null | grep -q GCC && complete -F _gcc cc || : + c++ --version 2>/dev/null | grep -q GCC && complete -F _gcc c++ || : +} # ex: ts=4 sw=4 et filetype=sh diff --git a/completions/gdb b/completions/gdb index c24407b5..125d0b15 100644 --- a/completions/gdb +++ b/completions/gdb @@ -5,7 +5,7 @@ _gdb() local cur prev words cword _init_completion || return - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then local IFS compopt -o filenames if [[ "$cur" == */* ]]; then @@ -24,7 +24,7 @@ _gdb() -mindepth 1 -maxdepth 1 -not -type d -executable \ -printf "%f\\n" 2>/dev/null)' -- "$cur" ) ) fi - elif [ $cword -eq 2 ]; then + elif [[ $cword -eq 2 ]]; then COMPREPLY=( $( compgen -W "$( command ps axo comm,pid | \ awk '{if ($1 ~ /^'"${prev##*/}"'/) print $2}' )" -- "$cur" ) ) compopt -o filenames diff --git a/completions/gpg b/completions/gpg index 763086bc..f7efad3a 100644 --- a/completions/gpg +++ b/completions/gpg @@ -20,7 +20,7 @@ _gpg() -r|--recipient) COMPREPLY=( $( compgen -W "$( gpg --list-keys 2>/dev/null | \ sed -ne 's@^.*<\([^>]*\)>.*$@\1@p')" -- "$cur" )) - if [ -e ~/.gnupg/gpg.conf ]; then + if [[ -e ~/.gnupg/gpg.conf ]]; then COMPREPLY+=( $( compgen -W "$( sed -ne \ 's@^[ \t]*group[ \t][ \t]*\([^=]*\).*$@\1@p' \ ~/.gnupg/gpg.conf )" -- "$cur") ) diff --git a/completions/gpg2 b/completions/gpg2 index 03d2c5b8..85e9f38c 100644 --- a/completions/gpg2 +++ b/completions/gpg2 @@ -24,7 +24,7 @@ _gpg2() -r|--recipient) COMPREPLY=( $( compgen -W "$( gpg2 --list-keys 2>/dev/null | \ sed -ne 's@^.*<\([^>]*\)>.*$@\1@p')" -- "$cur" )) - if [ -e ~/.gnupg/gpg.conf ]; then + if [[ -e ~/.gnupg/gpg.conf ]]; then COMPREPLY+=( $( compgen -W "$( sed -ne \ 's@^[ \t]*group[ \t][ \t]*\([^=]*\).*$@\1@p' \ ~/.gnupg/gpg.conf)" -- "$cur")) diff --git a/completions/hcitool b/completions/hcitool index 417a0c99..0a743e48 100644 --- a/completions/hcitool +++ b/completions/hcitool @@ -2,7 +2,7 @@ _bluetooth_adresses() { - if [ -n "${COMP_BLUETOOTH_SCAN:-}" ]; then + if [[ -n ${COMP_BLUETOOTH_SCAN:-} ]]; then COMPREPLY+=( $( compgen -W "$( hcitool scan | \ awk '/^\t/{print $1}' )" -- "$cur" ) ) fi @@ -51,7 +51,7 @@ _hcitool() local arg _get_first_arg - if [ -z $arg ]; then + if [[ -z $arg ]]; then if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) else @@ -63,7 +63,7 @@ _hcitool() case $arg in name|info|dc|rssi|lq|afh|auth|key|clkoff|lst) _count_args - if [ $args -eq 2 ]; then + if [[ $args -eq 2 ]]; then _bluetooth_adresses fi ;; @@ -72,14 +72,14 @@ _hcitool() COMPREPLY=( $( compgen -W '--role --pkt-type' -- "$cur" ) ) else _count_args - if [ $args -eq 2 ]; then + if [[ $args -eq 2 ]]; then _bluetooth_adresses fi fi ;; sr) _count_args - if [ $args -eq 2 ]; then + if [[ $args -eq 2 ]]; then _bluetooth_adresses else COMPREPLY=( $( compgen -W 'master slave' -- "$cur" ) ) @@ -87,7 +87,7 @@ _hcitool() ;; cpt) _count_args - if [ $args -eq 2 ]; then + if [[ $args -eq 2 ]]; then _bluetooth_adresses else _bluetooth_packet_types @@ -95,7 +95,7 @@ _hcitool() ;; tpl|enc|clock) _count_args - if [ $args -eq 2 ]; then + if [[ $args -eq 2 ]]; then _bluetooth_adresses else COMPREPLY=( $( compgen -W '0 1' -- "$cur" ) ) @@ -122,7 +122,7 @@ _sdptool() local arg _get_first_arg - if [ -z $arg ]; then + if [[ -z $arg ]]; then if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) else @@ -206,7 +206,7 @@ _rfcomm() local arg _get_first_arg - if [ -z $arg ]; then + if [[ -z $arg ]]; then if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) else @@ -215,12 +215,12 @@ _rfcomm() fi else _count_args - if [ $args -eq 2 ]; then + if [[ $args -eq 2 ]]; then _bluetooth_devices else case $arg in connect|bind) - if [ $args -eq 3 ]; then + if [[ $args -eq 3 ]]; then _bluetooth_adresses fi ;; @@ -245,7 +245,7 @@ _ciptool() local arg _get_first_arg - if [ -z $arg ]; then + if [[ -z $arg ]]; then if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) else @@ -256,7 +256,7 @@ _ciptool() case $arg in connect|release|loopback) _count_args - if [ $args -eq 2 ]; then + if [[ $args -eq 2 ]]; then _bluetooth_adresses fi ;; @@ -302,7 +302,7 @@ _hciconfig() local arg _get_first_arg - if [ -z $arg ]; then + if [[ -z $arg ]]; then if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '--help --all' -- "$cur" ) ) else @@ -318,20 +318,20 @@ _hciconfig() case $arg in putkey|delkey) _count_args - if [ $args -eq 2 ]; then + if [[ $args -eq 2 ]]; then _bluetooth_adresses fi ;; lm) _count_args - if [ $args -eq 2 ]; then + if [[ $args -eq 2 ]]; then COMPREPLY=( $( compgen -W 'MASTER \ SLAVE NONE ACCEPT' -- "$cur" ) ) fi ;; ptype) _count_args - if [ $args -eq 2 ]; then + if [[ $args -eq 2 ]]; then _bluetooth_packet_types fi ;; diff --git a/completions/htop b/completions/htop new file mode 100644 index 00000000..7735f9b5 --- /dev/null +++ b/completions/htop @@ -0,0 +1,32 @@ +# htop(1) completion -*- shell-script -*- + +_htop() +{ + local cur prev words cword split + _init_completion -s || return + + case "$prev" in + -s|--sort-key) + COMPREPLY=( $( compgen -W '$( "$1" -s help )' -- "$cur" ) ) + return + ;; + -u|--user) + COMPREPLY=( $( compgen -u -- "$cur" ) ) + return + ;; + -d|--delay) + # argument required but no completions available + return + ;; + esac + + $split && return + + if [[ "$cur" == -* ]]; then + COMPREPLY=( $( compgen -W '$( _parse_help "$1" --help )' -- "$cur" ) ) + [[ $COMPREPLY == *= ]] && compopt -o nospace + return + fi +} && complete -F _htop htop + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/id b/completions/id new file mode 100644 index 00000000..c985c9eb --- /dev/null +++ b/completions/id @@ -0,0 +1,18 @@ +# id(1) completion -*- shell-script -*- + +_id() +{ + local cur prev words cword + _init_completion || return + + if [[ "$cur" == -* ]]; then + local opts=$( _parse_help "$1" ) + [[ $opts ]] || opts="-G -g -u" # POSIX fallback + COMPREPLY=( $( compgen -W "$opts" -- "$cur" ) ) + else + COMPREPLY=( $( compgen -u "$cur" ) ) + fi +} && +complete -F _id id + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/ifup b/completions/ifup index fee87d6b..fcd34994 100644 --- a/completions/ifup +++ b/completions/ifup @@ -7,7 +7,7 @@ _ifupdown() local cur prev words cword _init_completion || return - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then _configured_interfaces COMPREPLY=( $(compgen -W '${COMPREPLY[@]}' -- "$cur") ) fi diff --git a/completions/info b/completions/info index aa16be69..36550449 100644 --- a/completions/info +++ b/completions/info @@ -43,14 +43,14 @@ _info() local i infopath=/usr/share/info - if [ "${INFOPATH: -1:1}" == ':' ]; then + if [[ $INFOPATH == *: ]]; then infopath=${INFOPATH}${infopath} - elif [ ${INFOPATH:+set} ]; then + elif [[ ${INFOPATH:+set} ]]; then infopath=$INFOPATH fi infopath=$infopath: - if [ -n "$cur" ]; then + if [[ -n $cur ]]; then infopath="${infopath//://$cur* }" else infopath="${infopath//:// }" @@ -62,9 +62,7 @@ _info() COMPREPLY=( ${COMPREPLY[@]##*/?(:)} ) # weed out info dir file for (( i=0 ; i < ${#COMPREPLY[@]} ; ++i )); do - if [ "${COMPREPLY[$i]}" == 'dir' ]; then - unset COMPREPLY[$i] - fi + [[ ${COMPREPLY[$i]} == dir ]] && unset COMPREPLY[$i] done # strip suffix from info pages COMPREPLY=( ${COMPREPLY[@]%.@(gz|bz2|xz|lzma)} ) diff --git a/completions/invoke-rc.d b/completions/invoke-rc.d index fd2c1db0..d4e0d245 100644 --- a/completions/invoke-rc.d +++ b/completions/invoke-rc.d @@ -9,8 +9,8 @@ _invoke_rc_d() local sysvdir services options valid_options - [ -d /etc/rc.d/init.d ] && sysvdir=/etc/rc.d/init.d \ - || sysvdir=/etc/init.d + [[ -d /etc/rc.d/init.d ]] && sysvdir=/etc/rc.d/init.d \ + || sysvdir=/etc/init.d services=( $( printf '%s ' $sysvdir/!(README*|*.sh|$_backup_glob) ) ) services=( ${services[@]#$sysvdir/} ) @@ -24,7 +24,7 @@ _invoke_rc_d() | sort | uniq -u \ ) ) COMPREPLY=( $( compgen -W '${valid_options[@]} ${services[@]}' -- "$cur" ) ) - elif [ -x $sysvdir/$prev ]; then + elif [[ -x $sysvdir/$prev ]]; then COMPREPLY=( $( compgen -W '`sed -e "y/|/ /" \ -ne "s/^.*Usage:[ ]*[^ ]*[ ]*{*\([^}\"]*\).*$/\1/p" \ $sysvdir/$prev`' -- "$cur" ) ) diff --git a/completions/iperf b/completions/iperf new file mode 100644 index 00000000..721825e2 --- /dev/null +++ b/completions/iperf @@ -0,0 +1,63 @@ +# iperf(1) completion -*- shell-script -*- + +_iperf() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -h|--help|-v|--version|-i|--interval|-l|--len|-p|--port|-w|--window|\ + -M|--mss|-b|--bandwidth|-n|--num|-t|--time|-L|--listenport|-P|\ + --parallel|-T|--ttl|-Z|--linux-congestion) + return + ;; + -f|--format) + COMPREPLY=( $( compgen -W 'k m K M' -- "$cur" ) ) + return + ;; + -o|--output|-F|--fileinput) + _filedir + return + ;; + -B|--bind) + _available_interfaces -a + _ip_addresses + return + ;; + -c|--client) + _known_hosts_real "$cur" + return + ;; + -x|--reportexclude) + COMPREPLY=( $( compgen -W 'C D M S V' -- "$cur" ) ) + return + ;; + -y|--reportstyle) + COMPREPLY=( $( compgen -W 'C' -- "$cur" ) ) + return + ;; + esac + + $split && return + + # Filter mode specific options + local i filter=cat + for i in ${words[@]}; do + case $i in + -s|--server) + filter='sed -e /^Client.specific/,/^$/d' + ;; + -c|--client) + filter='sed -e /^Server.specific/,/^$/d' + ;; + esac + done + [[ $filter != cat ]] && filter+=' -e /--client/d -e /--server/d' + + COMPREPLY=( $( compgen -W \ + '$( "$1" --help 2>&1 | $filter | _parse_help - )' -- "$cur" ) ) + [[ $COMPREPLY == *= ]] && compopt -o nospace +} && +complete -F _iperf iperf + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/ipmitool b/completions/ipmitool index 81a6466f..281d9eac 100644 --- a/completions/ipmitool +++ b/completions/ipmitool @@ -71,11 +71,11 @@ _ipmitool() for (( i=1; i < ${#words[@]}-1; i++ )); do [[ -n $cmd ]] && subcmd=${words[i]} && break for c in ${cmds[@]}; do - [ ${words[i]} = $c ] && cmd=$c && break + [[ ${words[i]} == $c ]] && cmd=$c && break done done - if [ -z "$cmd" ]; then + if [[ -z $cmd ]]; then COMPREPLY=( $( compgen -W '${cmds[@]}' -- "$cur" ) ) return 0 fi @@ -100,11 +100,11 @@ _ipmitool() print|set) ;; alert) - [ "$prev" = alert ] && \ + [[ $prev == alert ]] && \ COMPREPLY=( $( compgen -W 'print set' -- "$cur" ) ) ;; stats) - [ "$prev" = stats ] && \ + [[ $prev == stats ]] && \ COMPREPLY=( $( compgen -W 'print set' -- "$cur" ) ) ;; *) @@ -161,7 +161,7 @@ _ipmitool() _filedir ;; time) - [ "$prev" = time ] && \ + [[ $prev == time ]] && \ COMPREPLY=( $( compgen -W 'get set' -- "$cur" ) ) ;; *) @@ -176,7 +176,7 @@ _ipmitool() summary|list|disable|enable|priv|test) ;; set) - [ "$prev" = set ] && \ + [[ $prev == set ]] && \ COMPREPLY=( $( compgen -W 'name password' -- "$cur" ) ) ;; *) @@ -187,7 +187,7 @@ _ipmitool() ;; set) - [ "$prev" = set ] && \ + [[ $prev == set ]] && \ COMPREPLY=( $( compgen -W 'hostname username password privlvl authtype localaddr targetaddr port csv verbose' \ -- "$cur" ) ) diff --git a/completions/ipsec b/completions/ipsec index 1a081028..a586a786 100644 --- a/completions/ipsec +++ b/completions/ipsec @@ -18,7 +18,7 @@ _ipsec_freeswan() local cur prev words cword _init_completion || return - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then COMPREPLY=( $( compgen -W 'auto barf eroute klipsdebug look manual \ pluto ranbits rsasigkey setup showdefaults showhostkey spi spigrp \ tncfg whack' -- "$cur" ) ) @@ -55,7 +55,7 @@ _ipsec_strongswan() local cur prev words cword _init_completion || return - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then COMPREPLY=( $( compgen -W 'down irdumm leases listaacerts listacerts \ listalgs listall listcacerts listcainfos listcards listcerts \ listcrls listgroups listocsp listocspcerts listpubkeys openac pki diff --git a/completions/iptables b/completions/iptables index b9314f23..5c4e0736 100644 --- a/completions/iptables +++ b/completions/iptables @@ -29,12 +29,12 @@ _iptables() `iptables $table -nL | sed -ne "$chain" \ -e "s/INPUT|OUTPUT|FORWARD|PREROUTING|POSTROUTING//"`' -- \ "$cur" ) ) - elif [ "$table" = "-t nat" ]; then + 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 + 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//"`' -- \ diff --git a/completions/isql b/completions/isql index 695654f3..43cd6dd3 100644 --- a/completions/isql +++ b/completions/isql @@ -6,7 +6,7 @@ _isql() local cur prev words cword _init_completion || return - [ -f "$ODBCINI" ] \ + [[ -f $ODBCINI ]] \ && COMPREPLY=( $( command grep \\["$cur" "$ODBCINI" | tr -d \\[\\] ) ) } && complete -F _isql isql diff --git a/completions/iwconfig b/completions/iwconfig index 81dda723..899f1493 100644 --- a/completions/iwconfig +++ b/completions/iwconfig @@ -13,7 +13,7 @@ _iwconfig() ;; essid) COMPREPLY=( $( compgen -W 'on off any' -- "$cur" ) ) - if [ -n "${COMP_IWLIST_SCAN:-}" ]; then + if [[ -n ${COMP_IWLIST_SCAN:-} ]]; then COMPREPLY+=( $( compgen -W \ "$( iwlist ${words[1]} scan | \ awk -F'\"' '/ESSID/ {print $2}' )" -- "$cur" ) ) @@ -37,7 +37,7 @@ _iwconfig() ;; ap) COMPREPLY=( $( compgen -W 'on off any' -- "$cur" ) ) - if [ -n "${COMP_IWLIST_SCAN:-}" ]; then + if [[ -n ${COMP_IWLIST_SCAN:-} ]]; then COMPREPLY+=( $( compgen -W \ "$( iwlist ${words[1]} scan | \ awk -F ': ' '/Address/ {print $2}' )" -- "$cur" ) ) @@ -73,7 +73,7 @@ _iwconfig() ;; esac - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '--help --version' -- "$cur" ) ) else diff --git a/completions/iwlist b/completions/iwlist index 39bfa0f1..7819b04d 100644 --- a/completions/iwlist +++ b/completions/iwlist @@ -5,7 +5,7 @@ _iwlist() local cur prev words cword _init_completion || return - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '--help --version' -- "$cur" ) ) else diff --git a/completions/iwpriv b/completions/iwpriv index b0d45043..05952c5e 100644 --- a/completions/iwpriv +++ b/completions/iwpriv @@ -16,7 +16,7 @@ _iwpriv() ;; esac - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '--help --version' -- "$cur" ) ) else diff --git a/completions/iwspy b/completions/iwspy index 4bffc76e..b59b0693 100644 --- a/completions/iwspy +++ b/completions/iwspy @@ -5,7 +5,7 @@ _iwspy() local cur prev words cword _init_completion || return - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '--help --version' -- "$cur" ) ) else diff --git a/completions/java b/completions/java index e02f7369..c302d1e5 100644 --- a/completions/java +++ b/completions/java @@ -21,10 +21,10 @@ _java_find_classpath() done # default to environment - [ -z "$classpath" ] && classpath=$CLASSPATH + [[ -z $classpath ]] && classpath=$CLASSPATH # default to current directory - [ -z "$classpath" ] && classpath=. + [[ -z $classpath ]] && classpath=. } # exact sourcepath determination @@ -41,7 +41,7 @@ _java_find_sourcepath() done # default to classpath - if [ -z "$sourcepath" ]; then + if [[ -z $sourcepath ]]; then local classpath _java_find_classpath sourcepath=$classpath @@ -69,7 +69,7 @@ _java_classes() command grep '^[^$]*\.class$' ) ) fi - elif [ -d $i ]; then + elif [[ -d $i ]]; then COMPREPLY+=( $( compgen -d -- "$i/$cur" | sed -e "s|^$i/\(.*\)|\1.|" ) $( compgen -f -X '!*.class' -- "$i/$cur" | \ @@ -101,7 +101,7 @@ _java_packages() cur=${cur//.//} # parse each sourcepath element for packages for i in ${sourcepath//:/ }; do - if [ -d $i ]; then + if [[ -d $i ]]; then COMPREPLY+=( $( command ls -F -d $i/$cur* 2>/dev/null | \ sed -e 's|^'$i'/||' ) ) fi diff --git a/completions/kcov b/completions/kcov index e0f37fdb..ebbd803c 100644 --- a/completions/kcov +++ b/completions/kcov @@ -1,4 +1,4 @@ -# kcov completion -*- shell-script -*- +# kcov(1) completion -*- shell-script -*- _kcov() { @@ -8,29 +8,29 @@ _kcov() case "$prev" in --pid|-p) _pids - return 0 + return ;; --sort-type|-s) COMPREPLY=( $( compgen -W 'filename percentage' -- "$cur" ) ) - return 0 + return ;; --include-path|--exclude-path) _filedir - return 0 + return ;; --limits|-l|--title|-t|--include-pattern|--exclude-pattern|\ --path-strip-level) # argument required but no completions available - return 0 + return ;; esac - $split && return 0 + $split && return if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '$( _parse_help "$1" --help )' -- "$cur" ) ) [[ $COMPREPLY == *= ]] && compopt -o nospace - return 0 + return fi _filedir diff --git a/completions/killall b/completions/killall index d2f6dd47..ed502f97 100644 --- a/completions/killall +++ b/completions/killall @@ -1,4 +1,6 @@ -# killall(1) and pkill(1) completion -*- shell-script -*- +# killall(1) completion -*- shell-script -*- + +[[ $OSTYPE == *@(linux|freebsd|darwin)* ]] || return 1 _killall() { @@ -10,7 +12,7 @@ _killall() return ;; -s|--signal) - [[ $1 == *killall ]] && _signals + _signals return ;; -u|--user) @@ -21,15 +23,14 @@ _killall() $split && return - if [[ $cword -eq 1 && "$cur" == -* ]]; then - _signals - - else - _pnames + if [[ $cur == -* ]]; then + COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) + [[ $cword -eq 1 ]] && _signals - + return fi - return 0 + _pnames } && -complete -F _killall pkill -[[ $OSTYPE == *@(linux|freebsd|darwin)* ]] && complete -F _killall killall || : +complete -F _killall killall # ex: ts=4 sw=4 et filetype=sh diff --git a/completions/kldload b/completions/kldload index 26ab0e19..f362db69 100644 --- a/completions/kldload +++ b/completions/kldload @@ -8,7 +8,7 @@ _kldload() _init_completion || return local moddir=/modules/ - [ -d $moddir ] || moddir=/boot/kernel/ + [[ -d $moddir ]] || moddir=/boot/kernel/ compopt -o filenames COMPREPLY=( $( compgen -f "$moddir$cur" ) ) diff --git a/completions/koji b/completions/koji new file mode 100644 index 00000000..f4bdeacf --- /dev/null +++ b/completions/koji @@ -0,0 +1,234 @@ +# koji completion -*- shell-script -*- + +_koji_search() +{ + COMPREPLY+=( $( compgen -W \ + '$( "$1" -q search $2 "$cur*" 2>/dev/null )' -- "$cur" ) ) +} + +_koji_build() +{ + _koji_search "$1" build +} + +_koji_package() +{ + _koji_search "$1" package +} + +_koji_user() +{ + _koji_search "$1" user +} + +_koji_tag() +{ + COMPREPLY+=( $( compgen -W '$( "$1" -q list-tags 2>/dev/null )' \ + -- "$cur" ) ) +} + +_koji_target() +{ + COMPREPLY+=( $( compgen -W '$( "$1" -q list-targets 2>/dev/null | + awk "{ print \$1 }" )' -- "$cur" ) ) +} + +_koji() +{ + local cur prev words cword split + _init_completion -s || return + + local commandix command + for (( commandix=1; commandix < cword; commandix++ )); do + if [[ ${words[commandix]} != -* ]]; then + command=${words[commandix]} + break + fi + done + + case $prev in + -h|--help|--help-commands) + return + ;; + -c|--config|--keytab|-o) + _filedir + return + ;; + --runas|--user|--editor|--by) + _koji_user "$1" + return + ;; + --authtype) + COMPREPLY=( $( compgen -W 'noauth ssl password kerberos' \ + -- "$cur" ) ) + return + ;; + --topdir) + _filedir -d + return + ;; + --type) + case $command in + latest-pkg|list-tagged) + COMPREPLY=( $( compgen -W 'maven' -- "$cur" ) ) + ;; + esac + return + ;; + --name) + case $command in + list-targets) + _koji_target "$1" + ;; + esac + return + ;; + --owner) + _koji_user "$1" + return + ;; + --tag|--latestfrom) + _koji_tag "$1" + return + ;; + --package) + _koji_package "$1" + return + ;; + --build) + _koji_build "$1" + return + ;; + --build-target) + _koji_target "$1" + return + ;; + esac + + $split && return + + if [[ $command ]]; then + if [[ $cur == -* ]]; then + COMPREPLY=( $( compgen -W \ + '$( _parse_help "$1" "$command --help" )' -- "$cur" ) ) + [[ $COMPREPLY == *= ]] && compopt -o nospace + return + fi + + # How many'th non-option arg (1-based) for $command are we completing? + local i nth=1 + for (( i=commandix+1; i < cword; i++ )); do + [[ ${words[i]} == -* ]] || (( nth++ )) + done + + case $command in + build|maven-build|win-build) + case $nth in + 1) + _koji_target "$1" + ;; + 2) + _filedir src.rpm + ;; + esac + ;; + cancel) + _koji_build "$1" + ;; + chain-build) + case $nth in + 1) + _koji_target "$1" + ;; + esac + ;; + download-build) + case $nth in + 1) + _koji_build "$1" + ;; + esac + ;; + import-comps) + case $nth in + 1) + _filedir xml + ;; + 2) + _koji_tag "$1" + ;; + esac + ;; + latest-by-tag) + _koji_package "$1" + ;; + latest-pkg|list-groups|list-tag-inheritance|show-groups|wait-repo) + case $nth in + 1) + _koji_tag "$1" + ;; + esac + ;; + list-tagged) + case $nth in + 1) + _koji_tag "$1" + ;; + 2) + _koji_package "$1" + ;; + esac + ;; + list-untagged) + case $nth in + 1) + _koji_package "$1" + ;; + esac + ;; + move-pkg) + case $nth in + 1|2) + _koji_tag "$1" + ;; + *) + _koji_package "$1" + ;; + esac + ;; + search) + case $nth in + 1) + COMPREPLY=( $( compgen -W 'package build tag target + user host rpm' -- "$cur" ) ) + ;; + esac + ;; + tag-pkg|untag-pkg) + case $nth in + 1) + _koji_tag "$1" + ;; + *) + _koji_package "$1" + ;; + esac + ;; + taginfo) + _koji_tag "$1" + ;; + esac + return + fi + + if [[ $cur == -* ]]; then + COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) + [[ $COMPREPLY == *= ]] && compopt -o nospace + elif [[ ! $command ]]; then + COMPREPLY=( $( compgen -W '$( "$1" --help-commands 2>/dev/null | \ + awk "/^( +|\t)/ { print \$1 }" )' -- "$cur" ) ) + fi +} && +complete -F _koji koji arm-koji ppc-koji s390-koji sparc-koji + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/links b/completions/links index a212fa5a..5adc7de3 100644 --- a/completions/links +++ b/completions/links @@ -18,7 +18,7 @@ _links() -source -version -help' -- "$cur" ) ) ;; *) - if [ -r ~/.links/links.his ]; then + if [[ -r ~/.links/links.his ]]; then COMPREPLY=( $( compgen -W '$( < ~/.links/links.his )' \ -- "$cur" ) ) fi diff --git a/completions/lintian b/completions/lintian index 65121151..8e470758 100644 --- a/completions/lintian +++ b/completions/lintian @@ -10,7 +10,7 @@ _lintian_tags() for item in $search; do match=$(grep -nE "^Tag: $item$" /usr/share/lintian/checks/*.desc \ | cut -d: -f1 ) - tags=$( echo $tags | sed -e "s/\<$item\>//g" ) + tags=$( sed -e "s/\<$item\>//g" <<<$tags ) done COMPREPLY+=( $(compgen -W "$tags") ) elif [[ "$cur" == *,* ]]; then @@ -35,7 +35,7 @@ _lintian_checks() todisable=$(grep -e ^Check-Script -e ^Abbrev $match | \ cut -d\ -f2 ) for name in $todisable; do - checks=$( echo $checks | sed -e "s/\<$name\>//g" ) + checks=$( sed -e "s/\<$name\>//g" <<<$checks ) done done COMPREPLY+=( $(compgen -W "$checks") ) @@ -58,7 +58,7 @@ _lintian_infos() for item in $search; do match=$( grep -nE "^Collector: $item$" \ /usr/share/lintian/collection/*.desc | cut -d: -f1 ) - infos=$( echo $infos | sed -e "s/\<$item\>//g" ) + infos=$( sed -e "s/\<$item\>//g" <<<$infos ) done COMPREPLY+=( $(compgen -W "$infos") ) elif [[ "$cur" == *,* ]]; then @@ -133,7 +133,6 @@ _lintian() # If we're here, the user is trying to complete on # --action tag,tag, # Only few actions permit that, re-complete them now. - echo $prev case "$prev" in -C|--check-part|-X|--dont-check-part) _lintian_checks diff --git a/completions/lrzip b/completions/lrzip index 1569dab4..d4106fb2 100644 --- a/completions/lrzip +++ b/completions/lrzip @@ -26,19 +26,12 @@ _lrzip() COMPREPLY=( $( compgen -W '{1..9}' -- "$cur" ) ) return 0 ;; - -T) - COMPREPLY=( $( compgen -W '{1..10}' -- "$cur" ) ) - return 0 - ;; -N) COMPREPLY=( $( compgen -W '{-20..19}' -- "$cur" ) ) return 0 ;; -p) - local var=NPROCESSORS_ONLN - [[ $OSTYPE == *linux* ]] && var=_$var - local n=$( getconf $var 2>/dev/null ) - COMPREPLY=( $( compgen -W "{1..${n:-1}}" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "{1..$(_ncpus)}" -- "$cur" ) ) return 0 ;; esac diff --git a/completions/lvm b/completions/lvm index 7b353114..b657e0bd 100644 --- a/completions/lvm +++ b/completions/lvm @@ -314,7 +314,7 @@ _vgcreate() --verbose --version' -- "$cur" ) ) else _args - if [ $args -eq 0 ]; then + if [[ $args -eq 0 ]]; then _volumegroups else _physicalvolumes @@ -373,7 +373,7 @@ _vgreduce() else _args - if [ $args -eq 0 ]; then + if [[ $args -eq 0 ]]; then _volumegroups else _physicalvolumes @@ -402,7 +402,7 @@ _vgextend() COMPREPLY=( $( compgen -W '$( _parse_usage "$1" --help )' -- "$cur" ) ) else _args - if [ $args -eq 0 ]; then + if [[ $args -eq 0 ]]; then _volumegroups else _physicalvolumes @@ -686,7 +686,7 @@ _lvcreate() COMPREPLY=( $( compgen -W '$( _parse_usage "$1" --help )' -- "$cur" ) ) else _args - if [ $args -eq 0 ]; then + if [[ $args -eq 0 ]]; then _volumegroups else _physicalvolumes @@ -779,7 +779,7 @@ _lvresize() COMPREPLY=( $( compgen -W '$( _parse_usage "$1" --help )' -- "$cur" ) ) else _args - if [ $args -eq 0 ]; then + if [[ $args -eq 0 ]]; then _logicalvolumes else _physicalvolumes @@ -808,7 +808,7 @@ _lvextend() COMPREPLY=( $( compgen -W '$( _parse_usage "$1" --help )' -- "$cur" ) ) else _args - if [ $args -eq 0 ]; then + if [[ $args -eq 0 ]]; then _logicalvolumes else _physicalvolumes @@ -822,7 +822,7 @@ _lvm() local cur prev words cword _init_completion || return - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then COMPREPLY=( $( compgen -W 'dumpconfig help lvchange \ lvcreate lvdisplay lvextend lvmchange \ lvmdiskscan lvmsadc lvmsar lvreduce \ diff --git a/completions/lzip b/completions/lzip new file mode 100644 index 00000000..9df55382 --- /dev/null +++ b/completions/lzip @@ -0,0 +1,44 @@ +# lzip(1) completion -*- shell-script -*- + +_lzip() +{ + local cur prev words cword split + _init_completion -s || return + + local decompress=false + + case $prev in + -h|--help|-V|--version|-b|--member-size|-m|--match-length|\ + -s|--dictionary-size|-S|--volume-size) + return + ;; + -d|--decompress) + decompress=true + ;; + -o|--output) + _filedir + return + ;; + esac + + $split && return + + if [[ "$cur" == -* ]]; then + COMPREPLY=( $( compgen -W '$( _parse_help "$1" ) {-1..-9}' \ + -- "$cur" ) ) + return + fi + + if $decompress; then + _filedir lz + return + fi + + local IFS=$'\n' + compopt -o filenames + COMPREPLY=( $( compgen -f -X "*.lz" -- "$cur" ) \ + $( compgen -d -- "$cur" ) ) +} && +complete -F _lzip lzip + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/make b/completions/make index d56e1962..399c4b00 100644 --- a/completions/make +++ b/completions/make @@ -24,6 +24,10 @@ _make() --eval|-D|-V|-x) return 0 ;; + --jobs|-j) + COMPREPLY=( $( compgen -W "{1..$(( $(_ncpus)*2 ))}" -- "$cur" ) ) + return 0 + ;; esac $split && return 0 @@ -54,8 +58,8 @@ _make() fi done - [ -n "$makef" ] && makef="-f ${makef}" - [ -n "$makef_dir" ] && makef_dir="-C ${makef_dir}" + [[ -n $makef ]] && makef="-f ${makef}" + [[ -n $makef_dir ]] && makef_dir="-C ${makef_dir}" COMPREPLY=( $( compgen -W "$( make -qp $makef $makef_dir 2>/dev/null | \ awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ \ diff --git a/completions/man b/completions/man index 5c134d33..a9de57c4 100644 --- a/completions/man +++ b/completions/man @@ -63,7 +63,7 @@ _man() manpath=$MANPATH fi - if [ -z "$manpath" ]; then + if [[ -z $manpath ]]; then COMPREPLY=( $( compgen -c -- "$cur" ) ) return 0 fi @@ -72,7 +72,7 @@ _man() [[ "$prev" == $mansect ]] && sect=$prev || sect='*' manpath=$manpath: - if [ -n "$cur" ]; then + if [[ -n $cur ]]; then manpath="${manpath//://*man$sect/$cur* } ${manpath//://*cat$sect/$cur* }" else manpath="${manpath//://*man$sect/ } ${manpath//://*cat$sect/ }" diff --git a/completions/minicom b/completions/minicom index 6bac50ba..cad90926 100644 --- a/completions/minicom +++ b/completions/minicom @@ -29,11 +29,10 @@ _minicom() return 0 else local confdir - [ -n "$( command ls /etc/minirc.* 2>/dev/null)" ] \ - && confdir=/etc - [ -n "$( command ls /etc/minicom/minirc.* 2>/dev/null)" ] \ + [[ -n $( command ls /etc/minirc.* 2>/dev/null ) ]] && confdir=/etc + [[ -n $( command ls /etc/minicom/minirc.* 2>/dev/null ) ]] \ && confdir=/etc/minicom - if [ -n "$confdir" ]; then + if [[ -n $confdir ]]; then COMPREPLY=( $( compgen -W '$( printf "%s\n" $confdir/minirc.* | \ sed -e "s|$confdir/minirc.||")' -- "$cur" ) ) return 0 diff --git a/completions/mount b/completions/mount index 48bc7b03..ffe6629a 100644 --- a/completions/mount +++ b/completions/mount @@ -1,79 +1,16 @@ # mount(8) completion -*- shell-script -*- + +if [[ $OSTYPE == *linux* ]]; then + . "$BASH_SOURCE.linux" + return +fi + # This will pull a list of possible mounts out of # /etc/{,v}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. # - -# Just like COMPREPLY=(`compgen -W "${COMPREPLY[*]}" -- "$cur"`), only better! -# -# This will correctly escape special characters in COMPREPLY. -_reply_compgen_array() -{ - # Create the argument for compgen -W by escaping twice. - # - # One round of escape is because we want to reply with escaped arguments. A - # second round is required because compgen -W will helpfully expand it's - # argument. - local i wlist - for i in ${!COMPREPLY[*]}; do - local q=$(quote "$(printf %q "${COMPREPLY[$i]}")") - wlist+=$q$'\n' - done - - # We also have to add another round of escaping to $cur. - local ecur="$cur" - ecur="${ecur//\\/\\\\}" - ecur="${ecur//\'/\'}" - - # Actually generate completions. - local oldifs=$IFS - IFS=$'\n' eval 'COMPREPLY=(`compgen -W "$wlist" -- "${ecur}"`)' - IFS=$oldifs -} - -# Unescape strings in the linux fstab(5) format (with octal escapes). -__linux_fstab_unescape() { - eval $1="'${!1//\'/\047}'" - eval $1="'${!1/%\\/\\\\}'" - eval "$1=$'${!1}'" -} - -# Complete linux fstab entries. -# -# Reads a file from stdin in the linux fstab(5) format; as used by /etc/fstab -# and /proc/mounts. -_linux_fstab() -{ - COMPREPLY=() - - # Read and unescape values into COMPREPLY - local fs_spec fs_file fs_other - local oldifs="$IFS" - while read -r fs_spec fs_file fs_other; do - if [[ $fs_spec = [#]* ]]; then continue; fi - if [[ $1 == -L ]]; then - local fs_label=${fs_spec/#LABEL=} - if [[ $fs_label != "$fs_spec" ]]; then - __linux_fstab_unescape fs_label - IFS=$'\0' - COMPREPLY+=("$fs_label") - IFS=$oldifs - fi - else - __linux_fstab_unescape fs_spec - __linux_fstab_unescape fs_file - IFS=$'\0' - [[ $fs_spec = */* ]] && COMPREPLY+=("$fs_spec") - [[ $fs_file = */* ]] && COMPREPLY+=("$fs_file") - IFS=$oldifs - fi - done - - _reply_compgen_array -} - _mount() { local cur prev words cword @@ -92,7 +29,7 @@ _mount() if [[ "$cur" == *:* ]]; then for sm in "$(type -P showmount)" {,/usr}/{,s}bin/showmount; do - [ -x "$sm" ] || continue + [[ -x $sm ]] || continue COMPREPLY=( $( compgen -W "$( "$sm" -e ${cur%%:*} | \ awk 'NR>1 {print $1}' )" -- "${cur#*:}" ) ) return 0 @@ -102,53 +39,23 @@ _mount() if [[ "$cur" == //* ]]; then host=${cur#//} host=${host%%/*} - if [ -n "$host" ]; then + if [[ -n $host ]]; then COMPREPLY=( $( compgen -P "//$host" -W \ "$( smbclient -d 0 -NL $host 2>/dev/null | sed -ne '/^['"$'\t '"']*Sharename/,/^$/p' | sed -ne '3,$s|^[^A-Za-z]*\([^'"$'\t '"']*\).*$|/\1|p' )" \ -- "${cur#//$host}" ) ) fi - elif [ -r /etc/vfstab ]; then + elif [[ -r /etc/vfstab ]]; then # Solaris COMPREPLY=( $( compgen -W "$( awk '! /^[ \t]*#/ {if ($3 ~ /\//) print $3}' /etc/vfstab )" -- "$cur" ) ) - elif [ ! -e /etc/fstab ]; then + elif [[ ! -e /etc/fstab ]]; then # probably Cygwin COMPREPLY=( $( compgen -W "$( mount | awk '! /^[ \t]*#/ {if ($3 ~ /\//) print $3}' )" -- "$cur" ) ) else - # probably Linux - if [ "$prev" = -L ]; then - _linux_fstab -L < /etc/fstab - elif [ "$prev" = -U ]; then - COMPREPLY=( $( compgen -W '$(sed -ne "s/^[[:space:]]*UUID=\([^[:space:]]*\).*/\1/p" /etc/fstab )' -- "$cur" ) ) - else - _linux_fstab < /etc/fstab - fi + COMPREPLY=( $( compgen -W "$( awk '! /^[ \t]*#/ {if ($3 ~ /\//) print $3}' /etc/fstab )" -- "$cur" ) ) fi - - return 0 } && complete -F _mount -o default -o dirnames mount -# umount(8) completion. This relies on the mount point being the third -# space-delimited field in the output of mount(8) -# -_umount() -{ - local cur prev words cword - _init_completion || return - - if [[ $OSTYPE == *linux* && -r /proc/mounts ]]; then - # Linux /proc/mounts is properly quoted. This is important when - # unmounting usb devices with pretty names. - _linux_fstab < /proc/mounts - else - local IFS=$'\n' - COMPREPLY=( $( compgen -W '$( mount | cut -d" " -f 3 )' -- "$cur" ) ) - fi - - return 0 -} && -complete -F _umount -o dirnames umount - # ex: ts=4 sw=4 et filetype=sh diff --git a/completions/mount.linux b/completions/mount.linux new file mode 100644 index 00000000..91594449 --- /dev/null +++ b/completions/mount.linux @@ -0,0 +1,224 @@ +# mount(8) completion -*- shell-script -*- + +_mount() +{ + local cur prev words cword + _init_completion -n =: || return + + local split=false + case "$prev" in + -t|--types) + # find /lib/modules/$(uname -r)/ -type f -path '*/fs/*.ko' -printf '%f\n' | cut -d. -f1 + # FIXME: no + if [[ "$cur" == ?*,* ]]; then + prev="${cur%,*}" + cur="${cur##*,}" + split=true + fi + COMPREPLY=( $(compgen -W 'auto adfs affs autofs btrfs cifs coda + cramfs debugfs devpts efs ext2 ext3 ext4 fuse hfs hfsplus hpfs + iso9660 jfs minix msdos ncpfs nfs nfs4 ntfs ntfs-3g proc qnx4 + ramfs reiserfs romfs squashfs smbfs sysv tmpfs ubifs udf ufs + umsdos usbfs vfat xfs' -- "$cur") ) + _fstypes + $split && COMPREPLY=( ${COMPREPLY[@]/#/$prev,} ) + return + ;; + --bind|-B|--rbind|-R) + _filedir -d + return + ;; + -p|--pass-fd) + COMPREPLY=( $(compgen -W '{0..9}') ) + compopt -o nospace + return + ;; + -L) + COMPREPLY=( $( cd "/dev/disk/by-label/" 2>/dev/null || return; \ + compgen -f -- "$cur" ) ) + return + ;; + -U) + COMPREPLY=( $( cd "/dev/disk/by-uuid/" 2>/dev/null || return; \ + compgen -f -- "$cur" ) ) + return + ;; + -O|--test-opts) + # argument required but no completions available + return + ;; + -o|--options) + local fstype=auto # default fstype + for (( i=${#words[@]}-1; i>0; i-- )); do + if [[ "${words[i]}" == -@(t|-types)* ]]; then + if [[ "${words[i]}" == *=* ]]; then + [[ "${words[i]}" == ?*,* ]] && break + fstype="${words[i]#-*=}" + else + [[ "${words[i+1]}" == ?*,* ]] && break + fstype="${words[i+1]}" + fi + break + fi + done + # no is not a real fstype, reset to "auto" + [[ "$fstype" == no?* ]] && fstype=auto + # split options list + if [[ "$cur" == ?*,* ]]; then + prev="${cur%,*}" + cur="${cur##*,}" + split=true + fi + # no completion if $cur is opt=smth + [[ "$cur" == *=* ]] && return + # mount options + COMPREPLY=( $(compgen -W 'loop async {,no}atime {,no}auto + {,fs,def,root}context= defaults {,no}dev {,no}diratime dirsync + {,no}exec group {,no}iversion {,no}mand _netdev nofail + {,no}relatime {,no}strictatime {,no}suid owner remount ro rw + sync {,no}user users' -- "$cur") ) + case "$fstype" in + adfs|auto) + COMPREPLY+=( $(compgen -W 'uid= gid= {own,oth}mask=' -- \ + "$cur") ) + ;;& + affs|auto) + COMPREPLY+=( $(compgen -W '{u,g}id= set{u,g}id= mode= protect + usemp verbose prefix= volume= reserved= root= bs= + {,no,usr,grp}quota' -- "$cur") ) + ;;& + btrfs|auto) + COMPREPLY+=( $(compgen -W 'degraded subvol= subvolid= device= + nodatasum nodatacow nobarrier max_inline= alloc_start= + thread_pool= compress= compress-force= ssd noacl notreelog + flushoncommit metadata_ratio= space_cache clear_cache + user_subvol_rm_allowed autodefrag inode_cache' -- "$cur") ) + ;;& + cifs|auto) + COMPREPLY+=( $(compgen -W 'user= password= credentials= {u,g}id= + force{u,g}id port= servern= netbiosname= {file,dir}_mode= + ip= domain= guest iocharset ro rw {,no}setuids {,no,dyn}perm + directio {,no}mapchars {,no}intr hard soft noacl nocase sec= + nobrl sfu {,no}serverino nounix nouser_xattr {r,w}size=' \ + -- "$cur") ) + ;;& + ext[2-4]|auto) + COMPREPLY+=( $(compgen -W '{,no}acl bsddf minixdf check= debug + errors= {,no}grpid {bsd,sysv}groups {,no,usr,grp}quota + nobh nouid32 oldalloc orlov res{u,g}id= sb= + {,no}user_xattr' -- "$cur") ) + ;;& + ext[34]|auto) + COMPREPLY+=( $(compgen -W 'journal= journal_dev= norecovery + noload data= barrier= commit=' -- "$cur") ) + ;;& + ext4|auto) + COMPREPLY+=( $(compgen -W 'journal_checksum journal_async_commit + nobarrier inode_readahead= stripe= {,no}delalloc abort + {max,min}_batch_time= journal_ioprio= {,no}auto_da_alloc + {,no}discard nouid32 resize {,no}block_validity + dioread_{,no}lock i_version' -- "$cur") ) + ;;& + msdos|umsdos|vfat|auto) + COMPREPLY+=( $(compgen -W 'blocksize= {u,g}id= {u,d,f}mask= + allow_utime= check= codepage= conv= cvf_format= cvf_option= + debug fat= iocharset= tz= quiet showexec sys_immutable flush + usefree {,no}dots dotsOK=' -- "$cur") ) + ;;& + vfat|auto) + COMPREPLY+=( $(compgen -W 'uni_xlate posix nonumtail utf8 + shortname=' -- "$cur") ) + ;;& + iso9660|auto) + COMPREPLY+=( $(compgen -W 'norock nojoliet check= {u,g}id= map= + mode= unhide block= conv= cruft session= sbsector= + iocharset= utf8' -- "$cur") ) + ;;& + jfs|auto) + COMPREPLY+=( $(compgen -W 'iocharset= resize= {,no}integrity + errors= {,no,usr,grp}quota' -- "$cur") ) + ;;& + ntfs-3g) + COMPREPLY+=( $(compgen -W '{u,g}id= {u,f,d}mask= usermapping= + permissions inherit ro locale= force {,no}recover + ignore_case remove_hiberfile {,no,rel}atime show_sys_files + hide_{hid,dot}_files windows_names allow_other max_read= + silent no_def_opts streams_interface= user_xattr efs_raw + {,no}compression debug no_detach' -- "$cur") ) + ;;& + proc|auto) + COMPREPLY+=( $(compgen -W '{u,g}id=' -- "$cur") ) + ;;& + reiserfs|auto) + COMPREPLY+=( $(compgen -W 'conv hash= {,no_un}hashed_relocation + noborder nolog notail replayonly resize= user_xattr acl + barrier=' -- "$cur") ) + ;;& + tmpfs|auto) + COMPREPLY+=( $(compgen -W 'size= nr_blocks= nr_inodes= mode= + {u,g}id= mpol=' -- "$cur") ) + ;;& + udf|auto) + COMPREPLY+=( $(compgen -W '{u,g}id= umask= unhide undelete + nostrict iocharset bs= novrs session= anchor= volume= + partition= lastblock= fileset= rootdir=' -- "$cur") ) + ;;& + usbfs|auto) + COMPREPLY+=( $(compgen -W 'dev{u,g}id= devmode= bus{u,g}id= + busmode= list{u,g}id= listmode=' -- "$cur") ) + ;;& + xfs|auto) + COMPREPLY+=( $(compgen -W 'allocsize= {,no}attr2 barrier dmapi + {,no}grpid {bsd,sysv}groups ihashsize= {,no}ikeep inode64 + {,no}largeio logbufs= logbsize= logdev= rtdev= mtpt= noalign + noatime norecovery nouuid osyncisosync {u,g,p}qnoenforce + {,u,usr,g,grp,p,prj}quota sunit= swidth= swalloc' \ + -- "$cur") ) + ;;& + esac + # COMP_WORDBREAKS is a real pain in the ass + prev="${prev##*[$COMP_WORDBREAKS]}" + $split && COMPREPLY=( ${COMPREPLY[@]/#/"$prev,"} ) + [[ $COMPREPLY == *= ]] && compopt -o nospace + return + ;; + esac + + if [[ "$cur" == -* ]]; then + COMPREPLY=( $( compgen -W '--version --help --verbose --all --fork + --fake --internal-only -l --no-mtab --no-canonicalize --pass-fd -s + --read-only --rw -L -U --types --test-opts --options --bind --rbind + --move' -- "$cur" ) ) + [[ $COMPREPLY ]] && return + fi + + [[ "$cur" == \\ ]] && cur="/" + + local sm host + + if [[ "$cur" == *:* ]]; then + for sm in "$(type -P showmount)" {,/usr}/{,s}bin/showmount; do + [[ -x $sm ]] || continue + COMPREPLY=( $( compgen -W "$( "$sm" -e ${cur%%:*} | \ + awk 'NR>1 {print $1}' )" -- "${cur#*:}" ) ) + return 0 + done + fi + + if [[ "$cur" == //* ]]; then + host=${cur#//} + host=${host%%/*} + if [[ -n $host ]]; then + COMPREPLY=( $( compgen -P "//$host" -W \ + "$( smbclient -d 0 -NL $host 2>/dev/null | + sed -ne '/^['"$'\t '"']*Sharename/,/^$/p' | + sed -ne '3,$s|^[^A-Za-z]*\([^'"$'\t '"']*\).*$|/\1|p' )" \ + -- "${cur#//$host}" ) ) + fi + fi + + _filedir +} && +complete -F _mount mount + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/mplayer b/completions/mplayer index cd39d309..be852a5a 100644 --- a/completions/mplayer +++ b/completions/mplayer @@ -30,7 +30,7 @@ _mplayer() return 0 ;; -font|-subfont) - if [ "$prev" = -font ]; then + if [[ $prev == -font ]]; then _filedir '@(desc|ttf)' else _filedir ttf @@ -67,7 +67,7 @@ _mplayer() # if you don't have installed mplayer in /usr you # may want to set the MPLAYER_SKINS_DIR global variable local -a dirs - if [ -n "$MPLAYER_SKINS_DIR" ]; then + if [[ -n $MPLAYER_SKINS_DIR ]]; then dirs=($MPLAYER_SKINS_DIR) else dirs=(/usr/share/mplayer/skins /usr/local/share/mplayer/skins) diff --git a/completions/mtx b/completions/mtx index 0dae92ae..0cb63251 100644 --- a/completions/mtx +++ b/completions/mtx @@ -20,7 +20,7 @@ _mtx() drives=${drives//:Full} drives=${drives//:Empty} - if [ $cword -gt 1 ]; then + if [[ $cword -gt 1 ]]; then case $prev in load) COMPREPLY=( $( compgen -W "$tapes" -- "$cur" ) ) diff --git a/completions/mutt b/completions/mutt index 70699a15..acab9c86 100644 --- a/completions/mutt +++ b/completions/mutt @@ -21,23 +21,23 @@ _muttrc() { # Search COMP_WORDS for '-F muttrc' or '-Fmuttrc' argument set -- "${words[@]}" - while [ $# -gt 0 ]; do - if [ "${1:0:2}" = -F ]; then - if [ ${#1} -gt 2 ]; then + while [[ $# -gt 0 ]]; do + if [[ $1 == -F* ]]; then + if [[ ${#1} -gt 2 ]]; then muttrc="$(dequote "${1:2}")" else shift - [ "$1" ] && muttrc="$(dequote "$1")" + [[ $1 ]] && muttrc="$(dequote "$1")" fi break fi shift done - if [ -z "$muttrc" ]; then - if [ -f ~/.${muttcmd}rc ]; then + if [[ -z $muttrc ]]; then + if [[ -f ~/.${muttcmd}rc ]]; then muttrc="~/.${muttcmd}rc" - elif [ -f ~/.${muttcmd}/${muttcmd}rc ]; then + elif [[ -f ~/.${muttcmd}/${muttcmd}rc ]]; then muttrc="~/.${muttcmd}/${muttcmd}rc" fi fi @@ -57,11 +57,10 @@ _muttconffiles() sofar=" $1 " shift while [[ "$1" ]]; do - newconffiles=( $(sed -n 's|^source[[:space:]]\{1,\}\([^[:space:]]\{1,\}\).*$|\1|p' $(eval echo $1) ) ) + newconffiles=( $(sed -n 's|^source[[:space:]]\{1,\}\([^[:space:]]\{1,\}\).*$|\1|p' $(eval printf %s $1) ) ) for file in "${newconffiles[@]}"; do __expand_tilde_by_ref file - [[ ! -f "$file" || "${sofar/ ${file} / }" != "$sofar" ]] && - continue + [[ ! -f "$file" || $sofar == *\ $file\ * ]] && continue sofar+=" $file" sofar=" $(eval _muttconffiles \"$sofar\" $file) " done @@ -78,7 +77,7 @@ _muttaliases() local -a conffiles aliases muttrc=$(_muttrc) - [ -z "$muttrc" ] && return 0 + [[ -z $muttrc ]] && return 0 conffiles=( $(eval _muttconffiles $muttrc $muttrc) ) aliases=( $( sed -n 's|^alias[[:space:]]\{1,\}\([^[:space:]]\{1,\}\).*$|\1|p' \ @@ -126,10 +125,10 @@ _muttfiledir() COMPREPLY=( $( compgen -f -- "$folder/${cur:1}" ) ) COMPREPLY=( ${COMPREPLY[@]#$folder/} ) return 0 - elif [ "$cur" == !* ]; then + elif [[ $cur == !* ]]; then spoolfile="$( $muttcmd -F "$muttrc" -Q spoolfile 2>/dev/null | \ sed -e 's|^spoolfile=\"\(.*\)\"$|\1|' )" - [ ! -z "$spoolfile" ] && eval cur="${cur/^!/$spoolfile}" + [[ ! -z $spoolfile ]] && eval cur="${cur/^!/$spoolfile}" fi _filedir diff --git a/completions/mysql b/completions/mysql index effd313c..c41c1667 100644 --- a/completions/mysql +++ b/completions/mysql @@ -20,7 +20,7 @@ _mysql() return 0 ;; --default-character-set) - [ -d /usr/share/mysql/charsets ] && \ + [[ -d /usr/share/mysql/charsets ]] && \ COMPREPLY=( $( compgen -W "$(command ls /usr/share/mysql/charsets|sed -e '/^\(README\|Index\.xml\)$/d' -e 's/.xml$//') utf8" -- "$cur" ) ) return 0 ;; diff --git a/completions/nethogs b/completions/nethogs new file mode 100644 index 00000000..937edf1f --- /dev/null +++ b/completions/nethogs @@ -0,0 +1,25 @@ +# bash completion for nethogs(8) -*- shell-script -*- + +_nethogs() +{ + local cur prev words cword + _init_completion || return + + case "$prev" in + -d) + # expect integer value + COMPREPLY+=( $( compgen -W '{0..9}' ) ) + compopt -o nospace + return + ;; + esac + + if [[ "$cur" == -* ]]; then + COMPREPLY=( $( compgen -W '$( _parse_usage "$1" -h )' -- "$cur" ) ) + return + fi + + _available_interfaces -a +} && complete -F _nethogs nethogs + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/openssl b/completions/openssl index 68a13c2a..b63d215d 100644 --- a/completions/openssl +++ b/completions/openssl @@ -13,14 +13,14 @@ _openssl_sections() done # if no config given, check some usual default locations - if [ -z "$config" ]; then + if [[ -z $config ]]; then for f in /etc/ssl/openssl.cnf /etc/pki/tls/openssl.cnf \ /usr/share/ssl/openssl.cnf; do - [ -f $f ] && config=$f && break + [[ -f $f ]] && config=$f && break done fi - [ ! -f "$config" ] && return 0 + [[ ! -f $config ]] && return 0 COMPREPLY=( $( compgen -W "$( awk '/\[.*\]/ {print $2}' $config )" \ -- "$cur" ) ) @@ -48,7 +48,7 @@ _openssl() rc2-40-cbc rc2-64-cbc rc2-cbc rc2-cfb rc2-ecb rc2-ofb rc4 \ rc4-40' - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then COMPREPLY=( $( compgen -W "$commands" -- "$cur" ) ) else command=${words[1]} diff --git a/completions/p4 b/completions/p4 index 59d1bcd9..d0d984b2 100644 --- a/completions/p4 +++ b/completions/p4 @@ -14,9 +14,9 @@ _p4() uresource uxbinary xbinary xltext xtempobj xtext \ text binary resource" - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then COMPREPLY=( $( compgen -W "$p4commands" -- "$cur" ) ) - elif [ $cword -eq 2 ]; then + elif [[ $cword -eq 2 ]]; then case $prev in help) COMPREPLY=( $( compgen -W "simple commands \ @@ -29,7 +29,7 @@ _p4() *) ;; esac - elif [ $cword -gt 2 ]; then + elif [[ $cword -gt 2 ]]; then case $prev in -t) case ${words[$cword-2]} in diff --git a/completions/perl b/completions/perl index a67c7699..8b296377 100644 --- a/completions/perl +++ b/completions/perl @@ -99,16 +99,22 @@ _perldoc() local perl="${1%doc}" [[ $perl == $1 ]] || ! type $perl &>/dev/null && perl= - # complete builtin perl functions case $prev in + -h|-V|-n|-o|-M|-w|-L) + return 0 + ;; + -d) + _filedir + return 0 + ;; -f) _perlfunctions $perl - return 0 + return 0 ;; esac if [[ "$cur" == -* ]]; then - COMPREPLY=( $( compgen -W '-h -v -t -u -m -l -F -X -f -q' -- "$cur" )) + COMPREPLY=( $( compgen -W '$( _parse_help "$1" -h )' -- "$cur" ) ) else # return available modules (unless it is clearly a file) if [[ "$cur" != @(*/|[.~])* ]]; then diff --git a/completions/pgrep b/completions/pgrep index 9e66fb95..0a1c862f 100644 --- a/completions/pgrep +++ b/completions/pgrep @@ -1,4 +1,4 @@ -# pgrep(1) completion -*- shell-script -*- +# pgrep(1) and pkill(1) completion -*- shell-script -*- _pgrep() { @@ -6,13 +6,21 @@ _pgrep() _init_completion || return case $prev in - -d|-g|-s|-t) + -c|-d|-g|-J|-M|-N|-s|-t|-T|-z) + return + ;; + -F) + _filedir return ;; -G) _gids return ;; + -j) + COMPREPLY=( $( compgen -W 'any none' -- "$cur" ) ) + return + ;; -P) _pids return @@ -24,15 +32,15 @@ _pgrep() esac if [[ $cur == -* ]]; then - COMPREPLY=( $( compgen -W '$( _parse_usage "$1" )' -- "$cur" ) ) + COMPREPLY=( $( compgen -W '$( "$1" --usage 2>&1 | + sed -e "s/\[-signal\]//" -e "s/\[-SIGNAL\]//" | + _parse_usage - )' -- "$cur" ) ) + [[ $cword -eq 1 && $1 == *pkill ]] && _signals - return fi _pnames } && -complete -F _pgrep pgrep - -# Linux pidof(8) completion. -[[ $OSTYPE == *linux* ]] && complete -F _pgrep pidof +complete -F _pgrep pgrep pkill # ex: ts=4 sw=4 et filetype=sh diff --git a/completions/pidof b/completions/pidof new file mode 100644 index 00000000..12ac9a79 --- /dev/null +++ b/completions/pidof @@ -0,0 +1,19 @@ +# pidof(8) completion -*- shell-script -*- + +_pidof() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -o) + _pids + return + ;; + esac + + _pnames +} && +complete -F _pidof pidof + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/plague-client b/completions/plague-client new file mode 100644 index 00000000..b5385467 --- /dev/null +++ b/completions/plague-client @@ -0,0 +1,14 @@ +# bash completion for plague-client -*- shell-script -*- + +_plague_client() +{ + local cur prev words cword + _init_completion || return + + [[ $cword -eq 1 ]] && \ + COMPREPLY=( $( compgen -W 'build detail finish help is_paused kill list + list_builders pause requeue unpause update_builders' -- "$cur" ) ) +} && +complete -F _plague_client plague-client + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/povray b/completions/povray index e5ef9df6..fa2f9812 100644 --- a/completions/povray +++ b/completions/povray @@ -40,7 +40,7 @@ _povray() *.ini\[|*.ini\[*[^]]) # sections in .ini files cur="${povcur#*\[}" pfx="${povcur%\["$cur"}" # prefix == filename - [ -r "$pfx" ] || return 0 + [[ -r $pfx ]] || return 0 COMPREPLY=( $(sed -e 's/^[[:space:]]*\[\('"$cur"'[^]]*\]\).*$/\1/' \ -e 't' -e 'd' -- "$pfx") ) # to prevent [bar] expand to nothing. can be done more easily? diff --git a/completions/psql b/completions/psql index 7e4276bc..186177a3 100644 --- a/completions/psql +++ b/completions/psql @@ -13,7 +13,7 @@ _pg_users() # -w was introduced in 8.4, https://launchpad.net/bugs/164772 COMPREPLY=( $( compgen -W "$( psql -Atqwc 'select usename from pg_user' \ template1 2>/dev/null )" -- "$cur" ) ) - [ ${#COMPREPLY[@]} -eq 0 ] && COMPREPLY=( $( compgen -u -- "$cur" ) ) + [[ ${#COMPREPLY[@]} -eq 0 ]] && COMPREPLY=( $( compgen -u -- "$cur" ) ) } # createdb(1) completion diff --git a/completions/puppet b/completions/puppet index 776c8492..66a81b3b 100644 --- a/completions/puppet +++ b/completions/puppet @@ -2,7 +2,7 @@ _puppet_logdest() { - if [ -z "$cur" ]; then + if [[ -z $cur ]]; then COMPREPLY=( $( compgen -W 'syslog console /' -- "$cur" ) ) else COMPREPLY=( $( compgen -W 'syslog console' -- "$cur" ) ) diff --git a/completions/qdbus b/completions/qdbus index 5ed6bf89..a098fbc9 100644 --- a/completions/qdbus +++ b/completions/qdbus @@ -5,7 +5,7 @@ _qdbus() local cur prev words cword _init_completion || return - [ -n "$cur" ] && unset words[${#words[@]}-1] + [[ -n $cur ]] && unset words[${#words[@]}-1] COMPREPLY=( $( compgen -W '$( command ${words[@]} 2>/dev/null | \ sed s/\(.*\)// )' -- "$cur" ) ) } && diff --git a/completions/rcs b/completions/rcs index a8eac85b..67c1c9d8 100644 --- a/completions/rcs +++ b/completions/rcs @@ -11,7 +11,7 @@ _rcs() dir=${cur%/*} # deal with relative directory - [ "$file" = "$dir" ] && dir=. + [[ $file == $dir ]] && dir=. COMPREPLY=( $( compgen -f "$dir/RCS/$file" ) ) diff --git a/completions/removepkg b/completions/removepkg index 5b3d8273..287952cb 100644 --- a/completions/removepkg +++ b/completions/removepkg @@ -5,13 +5,17 @@ _removepkg() local cur prev words cword _init_completion || return if [[ "$cur" == -* ]]; then - COMPREPLY=( $( compgen -W '-copy -keep -preserve -warn' \ - -- "$cur" ) ) - return 0 + COMPREPLY=( $( compgen -W '-copy -keep -preserve -warn' -- "$cur" ) ) + return + fi + + if [[ "$cur" == */* ]]; then + _filedir + return fi local root=${ROOT:-/} - COMPREPLY=( $( cd "$root/var/log/packages" 2> /dev/null || return 1 ; \ + COMPREPLY=( $( cd "$root/var/log/packages" 2> /dev/null || return 1; \ compgen -f -- "$cur" ) ) } && complete -F _removepkg removepkg diff --git a/completions/ri b/completions/ri index 70756325..43f6408a 100644 --- a/completions/ri +++ b/completions/ri @@ -5,10 +5,10 @@ ri_get_methods() { local regex - if [ "$ri_version" = integrated ]; then - if [ -z "$separator" ]; then + if [[ $ri_version == integrated ]]; then + if [[ -z $separator ]]; then regex="(Instance|Class)" - elif [ "$separator" = "#" ]; then + elif [[ $separator == "#" ]]; then regex=Instance else regex=Class @@ -45,7 +45,7 @@ _ri() # -W0 is required here to stop warnings from older versions of ri # from being captured when used with Ruby 1.8.1 and later ri_version="$(ruby -W0 $ri_path -v 2>&1)" || ri_version=integrated - [ "$ri_version" != "${ri_version%200*}" ] && ri_version=integrated + [[ $ri_version != ${ri_version%200*} ]] && ri_version=integrated # need to also split on commas IFS=$', \n\t' @@ -60,11 +60,11 @@ _ri() return 0 fi - if [ "$ri_version" = integrated ]; then + if [[ $ri_version == integrated ]]; then # integrated ri from Ruby 1.9 classes=( $( ri -c 2>/dev/null | ruby -ne 'if /^\s*$/..$stdin.eof then \ if /, [A-Z]+/ then print; end; end' 2>/dev/null ) ) - elif [ "$ri_version" = "ri 1.8a" ]; then + elif [[ $ri_version == "ri 1.8a" ]]; then classes=( $( ruby -W0 $ri_path | \ ruby -ne 'if /^'"'"'ri'"'"' has/..$stdin.eof then \ if /^ .*[A-Z]/ then print; end; end' )) diff --git a/completions/route b/completions/route index 14fc2599..40d4f490 100644 --- a/completions/route +++ b/completions/route @@ -7,7 +7,7 @@ _route() local cur prev words cword _init_completion || return - if [ "$prev" = dev ]; then + if [[ $prev == dev ]]; then _available_interfaces return 0 fi @@ -18,7 +18,7 @@ _route() dyn reinstate dev default gw; do found=false for (( i=1; i < ${#words[@]}-1; i++ )); do - [ "${words[i]}" = "$opt" ] && found=true && break + [[ ${words[i]} == $opt ]] && found=true && break done $found || COMPREPLY[${#COMPREPLY[@]}]="$opt" done diff --git a/completions/rpcdebug b/completions/rpcdebug index 6d4acf52..3501af13 100644 --- a/completions/rpcdebug +++ b/completions/rpcdebug @@ -11,7 +11,7 @@ _rpcdebug_flags() fi done - if [ -n "$module" ]; then + if [[ -n $module ]]; then COMPREPLY=( $( compgen -W "$( rpcdebug -vh 2>&1 | \ sed -ne 's/^'$module'[[:space:]]\{1,\}//p' )" -- "$cur" ) ) fi diff --git a/completions/rpm b/completions/rpm index c7e67705..b7b59e0e 100644 --- a/completions/rpm +++ b/completions/rpm @@ -48,12 +48,12 @@ _rpm() local cur prev words cword split _init_completion -s || return - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then # first parameter on line case $cur in --*) COMPREPLY=( $( compgen -W '--help --version --initdb \ - --checksig --resign --addsign --rebuilddb --showrc \ + --checksig --addsign --delsign --rebuilddb --showrc \ --setperms --setugids --eval --install --upgrade --query \ --freshen --erase --verify --querytags --import' \ -- "$cur" ) ) @@ -67,7 +67,7 @@ _rpm() fi case $prev in - --dbpath|--excludepath|--prefix|--relocate|--root) + --dbpath|--excludepath|--prefix|--relocate|--root|-r) _filedir -d return 0 ;; @@ -214,7 +214,7 @@ _rpm() _rpm_installed_packages $1 fi ;; - --resign|--addsign) + --resign|--addsign|--delsign) _filedir '[rs]pm' ;; --setperms|--setgids) diff --git a/completions/rpm2tgz b/completions/rpm2tgz index 0b4510c7..34e54a5a 100644 --- a/completions/rpm2tgz +++ b/completions/rpm2tgz @@ -7,10 +7,10 @@ _rpm2tgz() if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '-s -S -n -r -d -c' -- "$cur" ) ) - return 0 + return fi - COMPREPLY=( $(compgen -f -X "!*.rpm" -- "$cur") ) -} && complete -F _rpm2tgz -o plusdirs rpm2tgz rpm2txz rpm2targz + _filedir "rpm" +} && complete -F _rpm2tgz rpm2tgz rpm2txz rpm2targz # ex: ts=4 sw=4 et filetype=sh diff --git a/completions/rrdtool b/completions/rrdtool index 9280d8f5..8170c9fe 100644 --- a/completions/rrdtool +++ b/completions/rrdtool @@ -5,7 +5,7 @@ _rrdtool () local cur prev words cword _init_completion || return - if [ ${#words[@]} -eq 2 ]; then + if [[ ${#words[@]} -eq 2 ]]; then COMPREPLY=( $( compgen -W 'create update updatev graph dump restore \ last lastupdate first info fetch tune resize xport' -- "$cur" ) ) else diff --git a/completions/rsync b/completions/rsync index e8b75b1a..e3f0f10e 100644 --- a/completions/rsync +++ b/completions/rsync @@ -74,7 +74,7 @@ _rsync() break fi done - [ "$shell" = ssh ] && _xfunc ssh _scp_remote_files + [[ $shell == ssh ]] && _xfunc ssh _scp_remote_files ;; *) _known_hosts_real -c -a "$cur" diff --git a/completions/sbopkg b/completions/sbopkg index 647355b0..0c812faa 100644 --- a/completions/sbopkg +++ b/completions/sbopkg @@ -6,33 +6,33 @@ _sbopkg() _init_completion || return if [[ "$cur" == -* ]]; then - COMPREPLY=( $( compgen -W '-b -c -d -e -f -g -h -i -k -l \ - -o -P -p -q -R -r -s -u -V -v' -- "$cur" ) ) - return 0 + COMPREPLY=( $( compgen -W '-b -c -d -e -f -g -h -i -k -l -o + -P -p -q -R -r -s -u -V -v' -- "$cur" ) ) + return fi case "$prev" in -e) COMPREPLY=( $( compgen -W 'ask continue stop' -- "$cur" ) ) - return 0 + return ;; -f) _filedir - return 0 + return ;; -d) _filedir -d - return 0 + return ;; -V) COMPREPLY=( $( compgen -W "? \ - $(sbopkg -V ? 2>&1 | cut -s -f1)" -- "$cur" ) ) - return 0 + $( sbopkg -V ? 2>&1 | cut -s -f1 )" -- "$cur" ) ) + return ;; -i|-b) ;; *) - return 0 + return ;; esac @@ -45,8 +45,8 @@ _sbopkg() fi done - if [ ! -r "$config" ]; then - return 0 + if [[ ! -r "$config" ]]; then + return fi . $config @@ -63,8 +63,8 @@ _sbopkg() esac done - if [ ! -r "$REPO_ROOT/$REPO_NAME/$REPO_BRANCH/SLACKBUILDS.TXT" ]; then - return 0 + if [[ ! -r $REPO_ROOT/$REPO_NAME/$REPO_BRANCH/SLACKBUILDS.TXT ]]; then + return fi COMPREPLY=( $( sed -ne "/^SLACKBUILD NAME: $cur/{s/^SLACKBUILD NAME: //;p}"\ $REPO_ROOT/$REPO_NAME/$REPO_BRANCH/SLACKBUILDS.TXT ) diff --git a/completions/service b/completions/service deleted file mode 100644 index f008770e..00000000 --- a/completions/service +++ /dev/null @@ -1,34 +0,0 @@ -# service(8) and /etc/init.d/* completion -*- shell-script -*- - -# This completes on a list of all available service scripts for the -# 'service' command and/or the SysV init.d directory, followed by -# that script's available commands - -_service() -{ - local cur prev words cword - _init_completion || return - - # don't complete past 2nd token - [ $cword -gt 2 ] && return 0 - - if [[ $cword -eq 1 && $prev == ?(*/)service ]]; then - _services - else - local sysvdir - [ -d /etc/rc.d/init.d ] && \ - sysvdir=/etc/rc.d/init.d || sysvdir=/etc/init.d - COMPREPLY=( $( compgen -W '`sed -e "y/|/ /" \ - -ne "s/^.*\(U\|msg_u\)sage.*{\(.*\)}.*$/\2/p" \ - $sysvdir/${prev##*/} 2>/dev/null` start stop' -- "$cur" ) ) - fi - - return 0 -} && -complete -F _service service -for svc in /etc/init.d/!($_backup_glob) /etc/rc.d/init.d/!($_backup_glob); do - [ -x "$svc" ] && complete -F _service $svc -done -unset svc - -# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/sitecopy b/completions/sitecopy index 1f18514a..12480e97 100644 --- a/completions/sitecopy +++ b/completions/sitecopy @@ -40,7 +40,7 @@ _sitecopy() ;; esac - if [ -r ~/.sitecopyrc ]; then + if [[ -r ~/.sitecopyrc ]]; then COMPREPLY=( $( compgen -W "$($1 -v | \ command sed -n '/^Site:/s/Site: //p')" -- "$cur" ) ) fi diff --git a/completions/slackpkg b/completions/slackpkg index 1d5759cb..b4223e71 100644 --- a/completions/slackpkg +++ b/completions/slackpkg @@ -17,34 +17,34 @@ _slackpkg() -delall|-checkmd5|-checkgpg|-checksize|-postinst|-onoff|-download_all|\ -dialog|-batch|-only_new_dotnew|-use_includes|-spinning) COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) ) - return 0 + return ;; -default_answer) COMPREPLY=( $( compgen -W 'yes no' -- "$cur" ) ) - return 0 + return ;; -dialog_maxargs|-mirror) # argument required but no completions available - return 0 + return ;; esac - $split && return 0 + $split && return if [[ "$cur" == -* ]]; then compopt -o nospace - COMPREPLY=( $( compgen -W '-delall= -checkmd5= -checkgpg= \ - -checksize= -postinst= -onoff= -download_all= -dialog= \ - -dialog_maxargs= -batch= -only_new_dotnew= -use_includes= \ + COMPREPLY=( $( compgen -W '-delall= -checkmd5= -checkgpg= + -checksize= -postinst= -onoff= -download_all= -dialog= + -dialog_maxargs= -batch= -only_new_dotnew= -use_includes= -spinning= -default_answer= -mirror=' -- "$cur" ) ) - return 0 + return fi local confdir="/etc/slackpkg" local config="$confdir/slackpkg.conf" - if [ ! -r "$config" ]; then - return 0 + if [[ ! -r "$config" ]]; then + return fi . "$config" @@ -59,47 +59,47 @@ _slackpkg() case "$action" in generate-template|search|file-search) # argument required but no completions available - return 0 + return ;; install-template|remove-template) - if [ -e "$confdir/templates" ]; then + if [[ -e $confdir/templates ]]; then COMPREPLY=( $( cd "$confdir/templates"; \ compgen -f -X "!*.template" -- "$cur" ) ) COMPREPLY=( ${COMPREPLY[@]%.template} ) fi - return 0 + return ;; remove) _filedir - COMPREPLY+=( $( compgen -W 'a ap d e f k kde kdei l n t tcl x \ + COMPREPLY+=( $( compgen -W 'a ap d e f k kde kdei l n t tcl x xap y' -- "$cur" ) ) COMPREPLY+=( $( cd /var/log/packages; compgen -f -- "$cur" ) ) - return 0 + return ;; install|reinstall|upgrade|blacklist|download) _filedir - COMPREPLY+=( $( compgen -W 'a ap d e f k kde kdei l n t tcl x \ + COMPREPLY+=( $( compgen -W 'a ap d e f k kde kdei l n t tcl x xap y' -- "$cur" ) ) - COMPREPLY+=( $( cut -f 6 -d\ ${WORKDIR}/pkglist 2> /dev/null | \ + COMPREPLY+=( $( cut -f 6 -d\ "${WORKDIR}/pkglist" 2> /dev/null | \ grep "^$cur" ) ) - return 0 + return ;; info) - COMPREPLY+=( $( cut -f 6 -d\ ${WORKDIR}/pkglist 2> /dev/null | \ + COMPREPLY=( $( cut -f 6 -d\ "${WORKDIR}/pkglist" 2> /dev/null | \ grep "^$cur" ) ) - return 0 + return ;; update) # we should complete the same as the next `list` + "gpg" COMPREPLY=( $( compgen -W 'gpg' -- "$cur" ) ) ;& *) - COMPREPLY+=( $( compgen -W 'install reinstall upgrade remove \ - blacklist download update install-new upgrade-all \ - clean-system new-config check-updates help generate-template \ + COMPREPLY+=( $( compgen -W 'install reinstall upgrade remove + blacklist download update install-new upgrade-all + clean-system new-config check-updates help generate-template install-template remove-template search file-search info' -- \ "$cur" ) ) - return 0 + return ;; esac diff --git a/completions/slapt-get b/completions/slapt-get index 99b50384..02f007ec 100644 --- a/completions/slapt-get +++ b/completions/slapt-get @@ -8,18 +8,18 @@ _slapt_get() case "$prev" in --config|-c) _filedir - return 0 + return ;; --retry|--search) # argument required but no completions available - return 0 + return ;; esac if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '$( _parse_help "$1" --help )' -- "$cur" ) ) [[ $COMPREPLY == *= ]] && compopt -o nospace - [[ $COMPREPLY ]] && return 0 + [[ $COMPREPLY ]] && return fi local i t @@ -48,7 +48,7 @@ _slapt_get() break fi done - if [ ! -r "$config" ]; then + if [[ ! -r "$config" ]]; then return fi @@ -59,21 +59,21 @@ _slapt_get() local name=${cur%%-*} COMPREPLY=( $( slapt-get -c $config --search "^$name" 2>/dev/null |\ sed -ne "/^$cur/{s/ .*$//;p}" ) ) - return 0 + return ;; avl) # --install|-i| COMPREPLY=( $( slapt-get -c $config --available 2>/dev/null | \ - sed -ne "/^$cur/{s/ .*$//;p}") ) - return 0 + sed -ne "/^$cur/{s/ .*$//;p}" ) ) + return ;; ins) # --remove|--filelist COMPREPLY=( $( cd /var/log/packages; compgen -f -- "$cur" ) ) - return 0 + return ;; set) # --install-set - COMPREPLY=( $( compgen -W 'a ap d e f k kde kdei l n t tcl x \ + COMPREPLY=( $( compgen -W 'a ap d e f k kde kdei l n t tcl x xap y' -- "$cur" ) ) - return 0 + return ;; esac } && complete -F _slapt_get slapt-get diff --git a/completions/slapt-src b/completions/slapt-src index 976ef65e..6234eaa8 100644 --- a/completions/slapt-src +++ b/completions/slapt-src @@ -8,18 +8,18 @@ _slapt_src() case "$prev" in --config|-c) _filedir - return 0 + return ;; --search|-s|--postprocess|-p) # argument required but no completions available - return 0 + return ;; esac if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '$( _parse_help "$1" --help )' -- "$cur" ) ) [[ $COMPREPLY == *= ]] && compopt -o nospace - [[ $COMPREPLY ]] && return 0 + [[ $COMPREPLY ]] && return fi local i t @@ -30,8 +30,8 @@ _slapt_src() break fi done - if [ "$t" != "all" ]; then - return 0 + if [[ $t != all ]]; then + return fi local config="/etc/slapt-get/slapt-srcrc" # default config location @@ -42,18 +42,18 @@ _slapt_src() break fi done - if [ ! -r "$config" ]; then - return 0 + if [[ ! -r "$config" ]]; then + return fi if [[ "$cur" == *:* ]]; then local name=${cur%:*} local version=${cur##*:} - COMPREPLY=( $( slapt-src --config $config --search "^$name" 2> \ + COMPREPLY=( $( slapt-src --config "$config" --search "^$name" 2> \ /dev/null | sed -ne "/^$cur/{s/^$name:\([^ ]*\) .*$/\1/;p}" ) ) else - COMPREPLY=( $( slapt-src --config $config --search "^$cur" 2>/dev/null \ - | sed -ne "/^$cur/{s/ .*$//;p}" ) ) + COMPREPLY=( $( slapt-src --config "$config" --search "^$cur" 2> \ + /dev/null | sed -ne "/^$cur/{s/ .*$//;p}" ) ) fi } && complete -F _slapt_src slapt-src diff --git a/completions/smbclient b/completions/smbclient index ceda7bbf..b7371907 100644 --- a/completions/smbclient +++ b/completions/smbclient @@ -7,14 +7,14 @@ _samba_resolve_order() _samba_domains() { - if [ -n "${COMP_SAMBA_SCAN:-}" ]; then + if [[ -n ${COMP_SAMBA_SCAN:-} ]]; then COMPREPLY=( $( compgen -W '$( smbtree -N -D )' -- "$cur" ) ) fi } _samba_hosts() { - if [ -n "${COMP_SAMBA_SCAN:-}" ]; then + if [[ -n ${COMP_SAMBA_SCAN:-} ]]; then COMPREPLY=( $( compgen -W "$( smbtree -N -S | \ sed -ne 's/^[[:space:]]*\\\\*\([^[:space:]]*\).*/\1/p' \ )" -- $cur ) ) diff --git a/completions/sqlite3 b/completions/sqlite3 index 1207823d..e97c2e9e 100644 --- a/completions/sqlite3 +++ b/completions/sqlite3 @@ -18,9 +18,7 @@ _sqlite3() esac if [[ "$cur" == -* ]]; then - COMPREPLY=( $( compgen -W '-help -init -echo -header -noheader -bail - -interactive -batch -column -csv -html -line -list -separator - -nullvalue -version' -- "$cur" ) ) + COMPREPLY=( $( compgen -W '$( _parse_help "$1" -help )' -- "$cur" ) ) return 0 fi diff --git a/completions/ssh b/completions/ssh index e30b9153..a18ba494 100644 --- a/completions/ssh +++ b/completions/ssh @@ -157,20 +157,20 @@ _ssh() else # Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument set -- "${words[@]}" - while [ $# -gt 0 ]; do - if [ "${1:0:2}" = -F ]; then - if [ ${#1} -gt 2 ]; then + while [[ $# -gt 0 ]]; do + if [[ $1 == -F* ]]; then + if [[ ${#1} -gt 2 ]]; then configfile="$(dequote "${1:2}")" else shift - [ "$1" ] && configfile="$(dequote "$1")" + [[ $1 ]] && configfile="$(dequote "$1")" fi break fi shift done _known_hosts_real -a -F "$configfile" "$cur" - if [ $cword -ne 1 ]; then + if [[ $cword -ne 1 ]]; then compopt -o filenames COMPREPLY+=( $( compgen -c -- "$cur" ) ) fi @@ -220,13 +220,13 @@ _sftp() else # Search COMP_WORDS for '-F configfile' argument set -- "${words[@]}" - while [ $# -gt 0 ]; do - if [ "${1:0:2}" = -F ]; then - if [ ${#1} -gt 2 ]; then + while [[ $# -gt 0 ]]; do + if [[ $1 == -F* ]]; then + if [[ ${#1} -gt 2 ]]; then configfile="$(dequote "${1:2}")" else shift - [ "$1" ] && configfile="$(dequote "$1")" + [[ $1 ]] && configfile="$(dequote "$1")" fi break fi @@ -258,12 +258,12 @@ _scp_remote_files() path=$( sed -e 's/\\\\\\\('$_scp_path_esc'\)/\\\1/g' <<<"$path" ) # default to home dir of specified user on remote host - if [ -z "$path" ]; then + if [[ -z $path ]]; then path=$(ssh -o 'Batchmode yes' $userhost pwd 2>/dev/null) fi local files - if [ "$1" = -d ] ; then + if [[ $1 == -d ]]; then # escape problematic characters; remove non-dirs files=$( ssh -o 'Batchmode yes' $userhost \ command ls -aF1d "$path*" 2>/dev/null | \ @@ -288,7 +288,7 @@ _scp_local_files() local IFS=$'\n' local dirsonly=false - if [ "$1" = -d ]; then + if [[ $1 == -d ]]; then dirsonly=true shift fi @@ -350,13 +350,13 @@ _scp() else # Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument set -- "${words[@]}" - while [ $# -gt 0 ]; do - if [ "${1:0:2}" = -F ]; then - if [ ${#1} -gt 2 ]; then + while [[ $# -gt 0 ]]; do + if [[ $1 == -F* ]]; then + if [[ ${#1} -gt 2 ]]; then configfile="$(dequote "${1:2}")" else shift - [ "$1" ] && configfile="$(dequote "$1")" + [[ $1 ]] && configfile="$(dequote "$1")" fi break fi diff --git a/completions/strace b/completions/strace index 0ac4163a..9d28a54e 100644 --- a/completions/strace +++ b/completions/strace @@ -21,7 +21,7 @@ _strace() break done - if [ $offset -gt 0 ]; then + if [[ $offset -gt 0 ]]; then _command_offset $offset else diff --git a/completions/tar b/completions/tar index 9d1c56a4..45f3ff36 100644 --- a/completions/tar +++ b/completions/tar @@ -7,7 +7,7 @@ _tar() local ext regex tar untar - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then COMPREPLY=( $( compgen -W 'c t x u r d A' -- "$cur" ) ) return 0 fi diff --git a/completions/udevadm b/completions/udevadm new file mode 100644 index 00000000..e8db7142 --- /dev/null +++ b/completions/udevadm @@ -0,0 +1,76 @@ +# udevadm(8) completion -*- shell-script -*- + +_udevadm() +{ + local cur prev words cword split + _init_completion -s || return + + local i udevcmd + for (( i=1; i < cword; i++ )); do + if [[ ${words[i]} != -* ]]; then + udevcmd=${words[i]} + break + fi + done + + case $prev in + --help|--version|--property|--children-max|--timeout|--seq-start|\ + --seq-end|--attr-match|--attr-nomatch|--parent-match|--property-match|\ + --tag-match|--subsystem-match|--subsystem-nomatch|--sysname-match|\ + --path) + return + ;; + --log-priority) + COMPREPLY=( $( compgen -W 'err info debug' -- "$cur" ) ) + return + ;; + --query) + COMPREPLY=( $( compgen -W 'name symlink path property all' \ + -- "$cur" ) ) + return + ;; + --name) + cur=${cur:=/dev/} + _filedir + return + ;; + --device-id-of-file|--exit-if-exists) + _filedir + return + ;; + --action) + COMPREPLY=( $( compgen -W 'add change remove' -- "$cur" ) ) + return + ;; + --type) + COMPREPLY=( $( compgen -W 'devices subsystems failed' -- "$cur" ) ) + return + ;; + esac + + $split && return + + if [[ -z $udevcmd ]]; then + case $cur in + -*) + COMPREPLY=( $( compgen -W '--help --version --debug' -- \ + "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$( "$1" --help 2>/dev/null | + awk '/^[[:space:]]+/ { print $1 }' )" -- "$cur" ) ) + ;; + esac + return + fi + + if [[ $cur == -* ]]; then + COMPREPLY=( $( compgen -W \ + '$( "$1" $udevcmd --help 2>/dev/null | _parse_help - )' \ + -- "$cur" ) ) + [[ $COMPREPLY == *= ]] && compopt -o nospace + fi +} && +complete -F _udevadm udevadm + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/umount b/completions/umount new file mode 100644 index 00000000..6c15182b --- /dev/null +++ b/completions/umount @@ -0,0 +1,21 @@ +# umount(8) completion -*- shell-script -*- + +if [[ $OSTYPE == *linux* ]]; then + . "$BASH_SOURCE.linux" + return +fi + +# umount(8) completion. This relies on the mount point being the third +# space-delimited field in the output of mount(8) +# +_umount() +{ + local cur prev words cword + _init_completion || return + + local IFS=$'\n' + COMPREPLY=( $( compgen -W '$( mount | cut -d" " -f 3 )' -- "$cur" ) ) +} && +complete -F _umount -o dirnames umount + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/umount.linux b/completions/umount.linux new file mode 100644 index 00000000..97231807 --- /dev/null +++ b/completions/umount.linux @@ -0,0 +1,140 @@ +# umount(8) completion -*- shell-script -*- + +# Just like COMPREPLY=(`compgen -W "${COMPREPLY[*]}" -- "$cur"`), only better! +# +# This will correctly escape special characters in COMPREPLY. +_reply_compgen_array() +{ + # Create the argument for compgen -W by escaping twice. + # + # One round of escape is because we want to reply with escaped arguments. A + # second round is required because compgen -W will helpfully expand it's + # argument. + local i wlist + for i in ${!COMPREPLY[*]}; do + local q=$(quote "$(printf %q "${COMPREPLY[$i]}")") + wlist+=$q$'\n' + done + + # We also have to add another round of escaping to $cur. + local ecur="$cur" + ecur="${ecur//\\/\\\\}" + ecur="${ecur//\'/\'}" + + # Actually generate completions. + local oldifs=$IFS + IFS=$'\n' eval 'COMPREPLY=(`compgen -W "$wlist" -- "${ecur}"`)' + IFS=$oldifs +} + +# Unescape strings in the linux fstab(5) format (with octal escapes). +__linux_fstab_unescape() { + eval $1="'${!1//\'/\047}'" + eval $1="'${!1/%\\/\\\\}'" + eval "$1=$'${!1}'" +} + +# Complete linux fstab entries. +# +# Reads a file from stdin in the linux fstab(5) format; as used by /etc/fstab +# and /proc/mounts. +_linux_fstab() +{ + COMPREPLY=() + + # Read and unescape values into COMPREPLY + local fs_spec fs_file fs_other + local oldifs="$IFS" + while read -r fs_spec fs_file fs_other; do + if [[ $fs_spec = [#]* ]]; then continue; fi + if [[ $1 == -L ]]; then + local fs_label=${fs_spec/#LABEL=} + if [[ $fs_label != "$fs_spec" ]]; then + __linux_fstab_unescape fs_label + IFS=$'\0' + COMPREPLY+=("$fs_label") + IFS=$oldifs + fi + else + __linux_fstab_unescape fs_spec + __linux_fstab_unescape fs_file + IFS=$'\0' + [[ $fs_spec = */* ]] && COMPREPLY+=("$fs_spec") + [[ $fs_file = */* ]] && COMPREPLY+=("$fs_file") + IFS=$oldifs + fi + done + + # Add relative paths to COMPREPLY + if [[ $cur && $cur != /* ]]; then + local realcur + [[ $cur == */ ]] && # don't let readlink drop last / from path + realcur="$( readlink -f "$cur." 2> /dev/null )/" || + realcur=$( readlink -f "$cur" 2> /dev/null ) + if [[ $realcur ]]; then + local dirrealcur= dircur= basecur + if [[ $cur == */* ]]; then + dirrealcur="${realcur%/*}/" + dircur="${cur%/*}/" + fi + basecur=${cur#"$dircur"} + local i n=${#COMPREPLY[@]} + for (( i=0; i < $n; i++ )); do + [[ "${COMPREPLY[i]}" == "$realcur"* ]] && + COMPREPLY+=( $( cd "$dircur" 2> /dev/null && + compgen -f -d -P "$dircur" \ + -X "!${COMPREPLY[i]##"$dirrealcur"}" -- "$basecur" ) ) + done + fi + fi + + _reply_compgen_array +} + +_umount() +{ + local cur prev words cword + _init_completion || return + + case "$prev" in + -t) + # FIXME: no + local split=false + if [[ "$cur" == ?*,* ]]; then + prev="${cur%,*}" + cur="${cur##*,}" + split=true + fi + COMPREPLY=( $(compgen -W 'adfs affs autofs btrfs cifs coda + cramfs debugfs devpts efs ext2 ext3 ext4 fuse hfs hfsplus hpfs + iso9660 jfs minix msdos ncpfs nfs nfs4 ntfs ntfs-3g proc qnx4 + ramfs reiserfs romfs squashfs smbfs sysv tmpfs ubifs udf ufs + umsdos usbfs vfat xfs' -- "$cur") ) + _fstypes + $split && COMPREPLY=( ${COMPREPLY[@]/#/$prev,} ) + return + ;; + -O) + # argument required but no completions available + return + ;; + esac + + if [[ "$cur" == -* ]]; then + COMPREPLY=( $( compgen -W '-V -h -v -n -r -d -i -a -t -O -f -l + --no-canonicalize --fake' -- "$cur" ) ) + [[ $COMPREPLY ]] && return + fi + + if [[ -r /proc/mounts ]]; then + # Linux /proc/mounts is properly quoted. This is important when + # unmounting usb devices with pretty names. + _linux_fstab < /proc/mounts + else + local IFS=$'\n' + COMPREPLY=( $( compgen -W '$( mount | cut -d" " -f 3 )' -- "$cur" ) ) + fi +} && +complete -F _umount -o dirnames umount + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/unace b/completions/unace index 4ce5e370..369417ce 100644 --- a/completions/unace +++ b/completions/unace @@ -5,10 +5,10 @@ _unace() local cur prev words cword _init_completion || return - if [[ "$cur" == -* ]] ; then + if [[ $cur == -* ]]; then COMPREPLY=( $( compgen -W '-c -c- -f -f- -o -o- -p -y -y-' -- "$cur" ) ) else - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then COMPREPLY=( $( compgen -W 'e l t v x' -- "$cur" ) ) else _filedir ace diff --git a/completions/unrar b/completions/unrar index d99e62fe..67a316ff 100644 --- a/completions/unrar +++ b/completions/unrar @@ -5,12 +5,12 @@ _unrar() local cur prev words cword _init_completion || return - if [[ "$cur" == -* ]] ; then + if [[ $cur == -* ]]; then COMPREPLY=( $( compgen -W '-ad -ap -av- -c- -cfg- -cl -cu \ -dh -ep -f -idp -ierr -inul -kb -o+ -o- -ow -p -p- -r -ta \ -tb -tn -to -u -v -ver -vp -x -x@ -y' -- "$cur" ) ) else - if [ $cword -eq 1 ]; then + if [[ $cword -eq 1 ]]; then COMPREPLY=( $( compgen -W 'e l lb lt p t v vb vt x' -- "$cur" ) ) else _filedir rar diff --git a/completions/update-alternatives b/completions/update-alternatives index 523e1de5..051b1142 100644 --- a/completions/update-alternatives +++ b/completions/update-alternatives @@ -5,7 +5,7 @@ _installed_alternatives() local admindir # find the admin dir for i in alternatives dpkg/alternatives rpm/alternatives; do - [ -d /var/lib/$i ] && admindir=/var/lib/$i && break + [[ -d /var/lib/$i ]] && admindir=/var/lib/$i && break done for (( i=1; i < cword; i++ )); do if [[ "${words[i]}" == --admindir ]]; then diff --git a/completions/update-rc.d b/completions/update-rc.d index b1d21e86..3dbad2e5 100644 --- a/completions/update-rc.d +++ b/completions/update-rc.d @@ -9,8 +9,8 @@ _update_rc_d() local sysvdir services options valid_options - [ -d /etc/rc.d/init.d ] && sysvdir=/etc/rc.d/init.d \ - || sysvdir=/etc/init.d + [[ -d /etc/rc.d/init.d ]] && sysvdir=/etc/rc.d/init.d \ + || sysvdir=/etc/init.d services=( $(printf '%s ' $sysvdir/!(README*|*.sh|$_backup_glob)) ) services=( ${services[@]#$sysvdir/} ) diff --git a/completions/upgradepkg b/completions/upgradepkg index 06dbe571..f9fa23ab 100644 --- a/completions/upgradepkg +++ b/completions/upgradepkg @@ -6,9 +6,21 @@ _upgradepkg() _init_completion || return if [[ "$cur" == -* ]]; then - COMPREPLY=( $( compgen -W '--dry-run --install-new --reinstall \ - --verbose' -- "$cur") ) - return 0 + COMPREPLY=( $( compgen -W '--dry-run --install-new --reinstall + --verbose' -- "$cur" ) ) + return + fi + + if [[ "$cur" == ?*%* ]]; then + prev="${cur%%?(\\)%*}" + cur="${cur#*%}" + local nofiles IFS=$'\n' + compopt -o filenames + COMPREPLY=( $( compgen -P "$prev%" -f -X "!*.@(t[bgxl]z)" -- "$cur" ) ) + [[ $COMPREPLY ]] || nofiles=1 + COMPREPLY+=( $( compgen -P "$prev%" -S '/' -d -- "$cur" ) ) + [[ $nofiles ]] && compopt -o nospace + return fi _filedir "t[bglx]z" diff --git a/completions/valgrind b/completions/valgrind new file mode 100644 index 00000000..1930c21b --- /dev/null +++ b/completions/valgrind @@ -0,0 +1,104 @@ +# valgrind(1) completion -*- shell-script -*- + +_valgrind() +{ + local cur prev words cword split + _init_completion -s || return + + local i + # Note: intentionally using COMP_WORDS and COMP_CWORD instead of + # words and cword here due to splitting on = causing index differences + # (_command_offset assumes the former). + for (( i=1; i <= COMP_CWORD; i++ )); do + if [[ ${COMP_WORDS[i]} != @([-=])* && ${COMP_WORDS[i-1]} != = ]]; then + _command_offset $i + return + fi + done + + local tool + for (( i=1; i < ${#words[@]}; i++ )); do + if [[ ${words[i]} == --tool=?* ]]; then + tool=${words[i]} + break + fi + done + + case $prev in + -h|--help|--help-debug|--version) + return + ;; + --tool) + # Tools seem to be named e.g. like memcheck-amd64-linux from which + # we want to grab memcheck. + COMPREPLY=( $( compgen -W '$( + for f in /usr{,/local}/lib{,64}/valgrind/*; do + [[ $f != *.so && -x $f ]] && + sed -ne "s/^.*\/\(.*\)-\([^-]*\)-\([^-]*\)/\1/p" <<<$f + done )' -- "$cur" ) ) + return + ;; + --sim-hints) + COMPREPLY=( $( compgen -W 'lax-ioctls enable-outer' -- "$cur" ) ) + return + ;; + --kernel-variant) + COMPREPLY=( $( compgen -W 'bproc' -- "$cur" ) ) + return + ;; + # callgrind: + --callgrind-out-file) + _filedir + return + ;; + # exp-dhat: + --sort-by) + COMPREPLY=( $( compgen -W 'max-bytes-live tot-bytes-allocd + max-blocks-live' -- "$cur" ) ) + return + ;; + # massif: + --time-unit) + COMPREPLY=( $( compgen -W 'i ms B' -- "$cur" ) ) + return + ;; + # generic cases parsed from --help output + --+([-A-Za-z0-9_])) + local value=$( $1 --help-debug $tool 2>/dev/null | \ + sed -ne "s|^[$' \t']*$prev=\([^$' \t']\{1,\}\).*|\1|p" ) + case $value in + \) + _filedir + return + ;; + \) + COMPREPLY=( $( compgen -c -- "$cur" ) ) + return + ;; + \<+([0-9])..+([0-9])\>) + COMPREPLY=( $( compgen -W "{${value:1:((${#value}-2))}}" \ + -- "$cur" ) ) + return + ;; + # "yes", "yes|no", etc (but not "string", "STR", + # "hint1,hint2,...") + yes|+([-a-z0-9])\|+([-a-z0-9\|])) + COMPREPLY=( $( IFS='|' compgen -W '$value' -- "$cur" ) ) + return + ;; + esac + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=( $( compgen -W '$( _parse_help "$1" "--help $tool" )' \ + -- "$cur" ) ) + [[ $COMPREPLY == *= ]] && compopt -o nospace + return + fi +} && +complete -F _valgrind valgrind + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/wine b/completions/wine new file mode 100644 index 00000000..c02c97f0 --- /dev/null +++ b/completions/wine @@ -0,0 +1,20 @@ +# bash completion for wine(1) -*- shell-script -*- + +_wine() +{ + local cur prev words cword + _init_completion || return + + if [[ $cword -eq 1 ]]; then + if [[ "$cur" == -* ]]; then + COMPREPLY=( $( compgen -W '--help --version' -- "$cur" ) ) + [[ $COMPREPLY ]] && return + fi + _filedir '[eE][xX][eE]?(.[sS][oO])|[cC][oO][mM]|[sS][cC][rR]' + else + _filedir + fi +} && +complete -F _wine wine + +# ex: ts=4 sw=4 et filetype=sh diff --git a/completions/wodim b/completions/wodim index 3bc304d1..b6ce2aa6 100644 --- a/completions/wodim +++ b/completions/wodim @@ -67,8 +67,8 @@ _cdrecord() -copy -nocopy -scms isrc= index= padsize= pregap= tsize= ) # look if previous was either a file or a track option track_mode=0 - if [ $cword -gt 1 ]; then - if [ -f "$prev" ]; then + if [[ $cword -gt 1 ]]; then + if [[ -f $prev ]]; then track_mode=1 else for (( i=0; i < ${#track_options[@]}; i++ )); do @@ -85,7 +85,7 @@ _cdrecord() # track options are always available COMPREPLY+=( $( compgen -W '${track_options[@]}' -- "$cur" ) ) # general options are no more available after file or track option - if [ $track_mode -eq 0 ]; then + if [[ $track_mode -eq 0 ]]; then COMPREPLY+=( $( compgen -W '${generic_options[@]}' -- "$cur" ) ) fi [[ $COMPREPLY == *= ]] && compopt -o nospace diff --git a/completions/wtf b/completions/wtf index b176d09b..cc8352f4 100644 --- a/completions/wtf +++ b/completions/wtf @@ -6,19 +6,19 @@ _wtf() local cur prev words cword _init_completion || return - [ "$prev" = -f ] && _filedir && return 0 - [[ "$cur" == -* ]] && COMPREPLY=( -f ) && return 0 + [[ $prev == -f ]] && _filedir && return 0 + [[ $cur == -* ]] && COMPREPLY=( -f ) && return 0 local db set -- "${words[@]}" - while [ $# -gt 0 ]; do - if [ "$1" = -f ]; then + while [[ $# -gt 0 ]]; do + if [[ $1 == -f ]]; then shift ; db=$1 ; break fi shift done - [ -z $db ] && db=${ACRONYMDB:-/usr/share/misc/acronyms*} + [[ -z $db ]] && db=${ACRONYMDB:-/usr/share/misc/acronyms*} COMPREPLY=( $( compgen -W "$( cut -f 1 -s $db ) -f" -- "${cur^^}" ) ) } && diff --git a/completions/xgamma b/completions/xgamma index 4c434cfe..c5b8a76b 100644 --- a/completions/xgamma +++ b/completions/xgamma @@ -7,9 +7,9 @@ _xgamma() case "$prev" in -screen) - local screens=$(xrandr --query 2>/dev/null | \ - sed -n '/^Screen /s|^Screen \{1,\}\(.*\):.*$|\1|p' 2>/dev/null) - COMPREPLY=( $(compgen -W "$screens" -- "$cur")) + local screens=$( xrandr --query 2>/dev/null | sed -n \ + '/^Screen /s|^Screen \{1,\}\(.*\):.*$|\1|p' 2>/dev/null ) + COMPREPLY=( $( compgen -W "$screens" -- "$cur" ) ) return ;; -gamma|-rgamma|-ggamma|-bgamma) @@ -17,7 +17,7 @@ _xgamma() if [[ $cur && "$cur" != *.* ]]; then COMPREPLY=( . ) fi - COMPREPLY+=( $(compgen -W "{0..9}") ) + COMPREPLY+=( $( compgen -W "{0..9}" ) ) compopt -o nospace return ;; @@ -26,14 +26,15 @@ _xgamma() if [[ "$cur" == :* && "$cur" != :*.* ]]; then # FIXME: where to get local display numbers? local display=${cur#:} - COMPREPLY=( $(compgen -W "${display:-0}.") ) + COMPREPLY=( $( compgen -W "${display:-0}." ) ) compopt -o nospace elif [[ "$cur" == :*.* ]]; then # local screen numbers - local t screens=$(xrandr --query 2>/dev/null | sed -n \ - -e '/^Screen /s|^Screen \{1,\}\(.*\):.*$|\1|p' 2>/dev/null) + local t screens=$( xrandr --query 2>/dev/null | sed -ne \ + '/^Screen /s|^Screen \{1,\}\(.*\):.*$|\1|p' 2>/dev/null ) t="${cur#:}" - COMPREPLY=( $(compgen -P "${t%.*}." -W "$screens" -- "${cur##*.}")) + COMPREPLY=( $( compgen -P "${t%.*}." -W "$screens" -- \ + "${cur##*.}" ) ) elif [[ "$cur" != *:* ]]; then # complete hostnames _known_hosts_real -c "$cur" diff --git a/completions/xhost b/completions/xhost index 397ca9ce..22839e4f 100644 --- a/completions/xhost +++ b/completions/xhost @@ -10,8 +10,6 @@ _xhost () -*) _known_hosts_real -p- "${cur:1}" ;; *) _known_hosts_real "$cur" ;; esac - - return 0 } && complete -F _xhost xhost diff --git a/completions/xrandr b/completions/xrandr index 36164298..332be812 100644 --- a/completions/xrandr +++ b/completions/xrandr @@ -7,52 +7,50 @@ _xrandr() local output modes - case $prev in + case "$prev" in --output|--left-of|--right-of|--above|--below|--same-as) - local outputs=$(xrandr|awk '/connected/ {print $1}') - COMPREPLY=( $(compgen -W "$outputs" -- "$cur")) - return 0 + local outputs=$( xrandr | awk '/connected/ {print $1}' ) + COMPREPLY=( $( compgen -W "$outputs" -- "$cur" ) ) + return ;; --mode) for(( i = 1; i < cword; i++ )); do - if [[ "${words[i]}" == "--output" ]]; then + if [[ "${words[i]}" == --output ]]; then output=${words[i+1]} break fi done - modes=$(xrandr|sed -e "1,/$output/ d" \ - -e "/connected/,$ d"|awk '{print $1}') - COMPREPLY=( $( compgen -W "$modes" -- "$cur")) - return 0 + modes=$( xrandr | sed -e "1,/$output/ d" \ + -e "/connected/,$ d" | awk '{print $1}' ) + COMPREPLY=( $( compgen -W "$modes" -- "$cur" ) ) + return ;; -o|--orientation) COMPREPLY=( $( compgen -W 'normal inverted left right 0 1 2 3' -- \ "$cur" ) ) - return 0 + return ;; --reflect) - COMPREPLY=( $( compgen -W 'normal x y xy' -- \ - "$cur" ) ) - return 0 + COMPREPLY=( $( compgen -W 'normal x y xy' -- "$cur" ) ) + return ;; --rotate) - COMPREPLY=( $( compgen -W 'normal inverted left right' -- \ - "$cur" ) ) - return 0 + COMPREPLY=( $( compgen -W 'normal inverted left right' -- "$cur" ) ) + return ;; esac case $cur in *) - COMPREPLY=( $(compgen -W '-display -help --orientation --query \ - --size --rate --version -x -y --screen --verbose --dryrun \ - --q1 --q12 --nograb --prop --properties --fb --fbmm --dpi \ - --output --auto --mode --preferred --pos --rate --refresh \ - --reflect --rotate --left-of --right-of --above --below \ - --same-as --set --scale --transform --off --crtc --panning \ - --gamma --brightness --primary --noprimary --newmode --rmmode \ - --addmode --delmode' -- "$cur") ) - return 0 + COMPREPLY=( $( compgen -W '-display -help --orientation --query + --size --rate --version -x -y --screen --verbose --dryrun + --q1 --q12 --nograb --prop --properties --fb --fbmm --dpi + --output --auto --mode --preferred --pos --rate --refresh + --reflect --rotate --left-of --right-of --above --below + --same-as --set --scale --transform --off --crtc --panning + --gamma --brightness --primary --noprimary --newmode --rmmode + --addmode --delmode' -- "$cur" ) ) + return ;; esac } && diff --git a/configure b/configure index 87947fff..6300efce 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for bash-completion 1.90. +# Generated by GNU Autoconf 2.68 for bash-completion 1.99. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='bash-completion' PACKAGE_TARNAME='bash-completion' -PACKAGE_VERSION='1.90' -PACKAGE_STRING='bash-completion 1.90' +PACKAGE_VERSION='1.99' +PACKAGE_STRING='bash-completion 1.99' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1175,7 +1175,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures bash-completion 1.90 to adapt to many kinds of systems. +\`configure' configures bash-completion 1.99 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1241,7 +1241,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of bash-completion 1.90:";; + short | recursive ) echo "Configuration of bash-completion 1.99:";; esac cat <<\_ACEOF @@ -1308,7 +1308,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -bash-completion configure 1.90 +bash-completion configure 1.99 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1325,7 +1325,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by bash-completion $as_me 1.90, which was +It was created by bash-completion $as_me 1.99, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2140,7 +2140,7 @@ fi # Define the identity of the package. PACKAGE='bash-completion' - VERSION='1.90' + VERSION='1.99' cat >>confdefs.h <<_ACEOF @@ -2193,7 +2193,7 @@ fi compatdir=$sysconfdir/bash_completion.d -ac_config_files="$ac_config_files Makefile completions/Makefile helpers/Makefile test/Makefile bash-completion.pc" +ac_config_files="$ac_config_files Makefile completions/Makefile doc/Makefile helpers/Makefile test/Makefile bash-completion.pc" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -2750,7 +2750,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by bash-completion $as_me 1.90, which was +This file was extended by bash-completion $as_me 1.99, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -2803,7 +2803,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -bash-completion config.status 1.90 +bash-completion config.status 1.99 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" @@ -2918,6 +2918,7 @@ do case $ac_config_target in "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "completions/Makefile") CONFIG_FILES="$CONFIG_FILES completions/Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "helpers/Makefile") CONFIG_FILES="$CONFIG_FILES helpers/Makefile" ;; "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; "bash-completion.pc") CONFIG_FILES="$CONFIG_FILES bash-completion.pc" ;; diff --git a/configure.ac b/configure.ac index 7d77e582..999f6539 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ AC_PREREQ([2.59]) -AC_INIT([bash-completion], [1.90]) +AC_INIT([bash-completion], [1.99]) AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip -Wall -Werror]) AC_PROG_LN_S AC_SUBST(compatdir, $sysconfdir/bash_completion.d) -AC_CONFIG_FILES([Makefile completions/Makefile helpers/Makefile test/Makefile bash-completion.pc]) +AC_CONFIG_FILES([Makefile completions/Makefile doc/Makefile helpers/Makefile test/Makefile bash-completion.pc]) AC_OUTPUT diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 00000000..6930b9cb --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,8 @@ +EXTRA_DIST = \ + bash_completion.txt \ + bashrc \ + inputrc \ + main.txt \ + makeHtml.sh \ + styleguide.txt \ + testing.txt diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 00000000..8e2fe930 --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,309 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = doc +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +am__leading_dot = @am__leading_dot@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +compatdir = @compatdir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = \ + bash_completion.txt \ + bashrc \ + inputrc \ + main.txt \ + makeHtml.sh \ + styleguide.txt \ + testing.txt + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign doc/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic distclean \ + distclean-generic distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/doc/bash_completion.txt b/doc/bash_completion.txt new file mode 100644 index 00000000..c6e53d4c --- /dev/null +++ b/doc/bash_completion.txt @@ -0,0 +1,59 @@ +Bash completion +=============== + +Configuration files +------------------- + +*~/.bash_completion*:: + Sourced late by bash_completion, pretty much after everything else. + Use this file for example to load additional completions, and to remove + and override ones installed by bash_completion. + +*$XDG_CONFIG_HOME/bash_completion*:: + Sourced by the bash_completion.sh profile.d script. This file is + suitable for definitions of all `COMP_*` environment variables + below. If `$XDG_CONFIG_HOME` is unset or null, `~/.config` is + used instead of it. + +Environment variables +--------------------- + +*COMP_CONFIGURE_HINTS*:: + If set and not null, `configure` completion will return the entire option + string (e.g. `--this-option=DESCRIPTION`) so one can see what kind of data + is required and then simply delete the descriptive text and add one's own + data. If unset or null (default), `configure` completion will strip + everything after the '=' when returning completions. + +*COMP_CVS_REMOTE*:: + If set and not null, `cvs commit` completion will try to complete on + remotely checked-out files. This requires passwordless access to the + remote repository. Default is unset. + +*COMP_FILEDIR_FALLBACK*:: + If set and not null, completions that look for filenames based on their + "extensions" will fall back to suggesting all files if there are none + matching the sought ones. + +*COMP_IWLIST_SCAN*:: + If set and not null, `iwconfig` completion will try to complete on + available wireless networks identifiers. Default is unset. + +*COMP_KNOWN_HOSTS_WITH_HOSTFILE*:: + If set and not null (default), known hosts completion will complement + hostnames from ssh's known_hosts files with hostnames taken from the file + specified by the HOSTFILE shell variable (compgen -A hostname). If null, + known hosts completion will omit hostnames from HOSTFILE. Omitting + hostnames from HOSTFILE is useful if HOSTFILE contains many entries for + local web development or ad-blocking. + +*COMP_KNOWN_HOSTS_WITH_AVAHI*:: + If set and not null, known hosts completion will try to use `avahi-browse` + for additional completions. This may be a slow operation in some setups. + Default is unset. + +*COMP_TAR_INTERNAL_PATHS*:: + If set and not null *before* sourcing bash_completion, `tar` completion + will do correct path completion for tar file contents. If unset or null, + `tar' completion will do correct completion for paths to tar files. See + also README. diff --git a/doc/bashrc b/doc/bashrc new file mode 100644 index 00000000..fd72b816 --- /dev/null +++ b/doc/bashrc @@ -0,0 +1,41 @@ +# bashrc file for DejaGnu testsuite + + # Use emacs key bindings +set -o emacs + # Use bash strict mode +set -o posix + # Unset `command_not_found_handle' as defined on Debian/Ubuntu, because this + # troubles and slows down testing +unset -f command_not_found_handle + # Set fixed prompt `/@' +TESTDIR=$(pwd) +export PS1='/@' +export PS2='> ' + # Configure readline +export INPUTRC=$SRCDIR/config/inputrc + # When not running via cron, avoid escape junk at beginning of line from + # readline, see e.g. http://bugs.gentoo.org/246091 +[ "$CRON" ] || export TERM=dummy + # Ensure enough columns so expect doesn't have to care about line breaks +stty columns 150 + # Also test completions of system administrator commands, which are + # installed via the same PATH expansion in `bash_completion.have()' +export PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin + + # Make sure default settings are in effect +unset -v \ + COMP_CONFIGURE_HINTS \ + COMP_CVS_REMOTE \ + COMP_KNOWN_HOSTS_WITH_HOSTFILE \ + COMP_TAR_INTERNAL_PATHS + + # Load bash testsuite helper functions +. $SRCDIR/lib/library.sh + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/doc/inputrc b/doc/inputrc new file mode 100644 index 00000000..33134da6 --- /dev/null +++ b/doc/inputrc @@ -0,0 +1,21 @@ +# Readline init file for DejaGnu testsuite +# See: info readline + + # Press TAB once (instead of twice) to auto-complete +set show-all-if-ambiguous on + # No bell. No ^G in output +set bell-style none + # Don't query user about viewing the number of possible completions +set completion-query-items -1 + # Display completions sorted horizontally, not vertically +set print-completions-horizontally on + # Don't use pager when showing completions +set page-completions off + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/doc/main.txt b/doc/main.txt new file mode 100644 index 00000000..d8a3076a --- /dev/null +++ b/doc/main.txt @@ -0,0 +1,18 @@ +Bash-completion +=============== +Freddy Vulto (FVu) +v1.0, Mar 2009 + +Preface +======= +Bash completion extends bashs standard completion behavior to achieve +complex command lines with just a few keystrokes. This project was +conceived to produce programmable completion routines for the most +common Linux/UNIX commands, reducing the amount of typing sysadmins +and programmers need to do on a daily basis. + +// include::intro.txt[] +include::bash_completion.txt[] + +include::styleguide.txt[] +include::testing.txt[] diff --git a/doc/makeHtml.sh b/doc/makeHtml.sh new file mode 100755 index 00000000..79780eb6 --- /dev/null +++ b/doc/makeHtml.sh @@ -0,0 +1,4 @@ +#!/bin/bash -eu + +[ -d html~ ] || mkdir html~ +a2x -D html~ -d book -f xhtml --asciidoc-opts="--unsafe" main.txt diff --git a/doc/styleguide.txt b/doc/styleguide.txt new file mode 100644 index 00000000..31ad4469 --- /dev/null +++ b/doc/styleguide.txt @@ -0,0 +1,111 @@ +Coding Style Guide +================== + +Introduction +------------ +This document attempts to explain the basic styles and patterns that +are used in the bash completion. New code should try to conform to +these standards so that it is as easy to maintain as existing code. +Of course every rule has an exception, but it's important to know +the rules nonetheless! + +This is particularly directed at people new to the bash completion +codebase, who are in the process of getting their code reviewed. +Before getting a review, please read over this document and make +sure your code conforms to the recommendations here. + +Indentation +----------- +Indent step should be 4 spaces, no tabs. + +Globbing in case labels +----------------------- + +Avoid "fancy" globbing in case labels, just use traditional style when +possible. For example, do "--foo|--bar)" instead of "--@(foo|bar))". +Rationale: the former is easier to read, often easier to grep, and +doesn't confuse editors as bad as the latter, and is concise enough. + +[[ ]] vs [ ] +---------------- + +Always use [[ ]] instead of [ ]. Rationale: the former is less error +prone, more featureful, and slightly faster. + +Line wrapping +------------- + +Try to wrap lines at 79 characters. Never go past this limit, unless +you absolutely need to (example: a long sed regular expression, or the +like). This also holds true for the documentation and the testsuite. +Other files, like ChangeLog, or COPYING, are exempt from this rule. + +$(...) vs \`...` +---------------- + +When you need to do some code substitution in your completion script, +you *MUST* use the $(...) construct, rather than the \`...`. The former +is preferable because anyone, with any keyboard layout, is able to +type it. Backticks aren't always available, without doing strange +key combinations. + +-o filenames +------------ + +As a rule of thumb, do not use "complete -o filenames". Doing it makes +it take effect for all completions from the affected function, which +may break things if some completions from the function must not be +escaped as filenames. Instead, use "compopt -o filenames" to turn on +"-o filenames" behavior dynamically when returning completions that +need that kind of processing (e.g. file and command names). The +_filedir and _filedir_xspec helpers do this automatically whenever +they return some completions. + +[[ $COMPREPLY == *= ]] && compopt -o nospace +------------------------------------------------ + +The above is functionally a shorthand for: +---- +if [[ ${#COMPREPLY[@]} -eq 1 && ${COMPREPLY[0]} == *= ]]; then + compopt -o nospace +fi +---- +It is used to ensure that long options' name won't get a space +appended after the equal sign. Calling compopt -o nospace makes sense +in case completion actually occurs: when only one completion is +available in COMPREPLY. + +$split && return +---------------- + +Should be used in completions using the -s flag of _init_completion, +or other similar cases where _split_longopt has been invoked, after +$prev has been managed but before $cur is considered. If $cur of the +form --foo=bar was split into $prev=--foo and $cur=bar and the $prev +block did not process the option argument completion, it makes sense +to return immediately after the $prev block because --foo obviously +takes an argument and the remainder of the completion function is +unlikely to provide meaningful results for the required argument. +Think of this as a catch-all for unknown options requiring an +argument. + +Note that even when using this, options that are known to require an +argument but for which we don't have argument completion should be +explicitly handled (non-completed) in the $prev handling block because +--foo=bar options can often be written without the equals sign, and in +that case the long option splitting does not occur. + +///////////////////////////////////////// +case/esac vs if +--------------- + +quoting +------- + +awk vs cut for simple cases +--------------------------- + +variable and function naming +---------------------------- + +///////////////////////////////////////// diff --git a/doc/testing.txt b/doc/testing.txt new file mode 100644 index 00000000..c4b7cf18 --- /dev/null +++ b/doc/testing.txt @@ -0,0 +1,573 @@ +Automated testing +================= + +Introduction +------------ +The bash-completion package contains an automated test suite. Running the +tests should help verifying that bash-completion works as expected. The tests +are also very helpful in uncovering software regressions at an early stage. + +The bash-completion test suite is written on top of the +http://www.gnu.org/software/dejagnu/[DejaGnu] testing framework. DejaGnu is +written in http://expect.nist.gov[Expect], which in turn uses +http://tcl.sourceforge.net[Tcl] -- Tool command language. + + +Coding Style Guide +------------------ + +The bash-completion test suite tries to adhere to this +http://wiki.tcl.tk/708[Tcl Style Guide]. + + +Installing dependencies +----------------------- + +Installing dependencies should be easy using your local package manager. + + +Debian/Ubuntu +~~~~~~~~~~~~~ + +On Debian/Ubuntu you can use `apt-get`: +------------- +sudo apt-get install dejagnu tcllib +------------- +This should also install the necessary `expect` and `tcl` packages. + +Fedora/RHEL/CentOS +~~~~~~~~~~~~~~~~~~ + +On Fedora and RHEL/CentOS (with EPEL) you can use `yum`: +------------- +sudo yum install dejagnu tcllib +------------- +This should also install the necessary `expect` and `tcl` packages. + + + +Structure +--------- + + +Main areas (DejaGnu tools) +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The tests are grouped into different areas, called _tool_ in DejaGnu: + +*completion*:: + Functional tests per completion. +*install*:: + Functional tests for installation and caching of the main bash-completion + package. +*unit*:: + Unit tests for bash-completion helper functions. + +Each tool has a slightly different way of loading the test fixtures, see +<> below. + + +Completion +~~~~~~~~~~ + +Completion tests are spread over two directories: `completion/\*.exp` calls +completions in `lib/completions/\*.exp`. This two-file system stems from +bash-completion-lib (http://code.google.com/p/bash-completion-lib/, containing +dynamic loading of completions) where tests are run twice per completion; once +before dynamic loading and a second time after to confirm that all dynamic +loading has gone well. + +For example: + +---- +set test "Completion via comp_load() should be installed" +set cmd "complete -p awk" +send "$cmd\r" +expect { + -re "^$cmd\r\ncomplete -o filenames -F comp_load awk\r\n/@$" { pass "$test" } + -re /@ { fail "$test at prompt" } +} + + +source "lib/completions/awk.exp" + + +set test "Completion via _longopt() should be installed" +set cmd "complete -p awk" +send "$cmd\r" +expect { + -re "^$cmd\r\ncomplete -o filenames -F _longopt awk\r\n/@$" { pass "$test" } + -re /@ { fail "$test at prompt" } +} + + +source "lib/completions/awk.exp" +---- + +Looking to the completion tests from a broader perspective, every test for a +command has two stages which are now reflected in the two files: + +. Tests concerning the command completions' environment (typically in +`test/completion/foo`) +. Tests invoking actual command completion (typically in +`test/lib/completions/foo`) + + +Running the tests +----------------- + +The tests are run by calling `runtest` command in the test directory: +----------------------- +runtest --outdir log --tool completion +runtest --outdir log --tool install +runtest --outdir log --tool unit +----------------------- +The commands above are already wrapped up in shell scripts within the `test` +directory: +----------------------- +./runCompletion +./runInstall +./runUnit +----------------------- +To run a particular test, specify file name of your test as an argument to +`runCompletion` script: +----------------------- +./runCompletion ssh.exp +----------------------- +That will run `test/completion/ssh.exp`. + + +Running tests via cron +~~~~~~~~~~~~~~~~~~~~~~ + +The test suite requires a connected terminal (tty). When invoked via cron, no +tty is connected and the test suite may respond with this error: +--------------------------------------------- +can't read "multipass_name": no such variable +--------------------------------------------- + +To run the tests successfully via cron, connect a terminal by redirecting +stdin from a tty, e.g. /dev/tty40. (In Linux, you can press alt-Fx or +ctrl-alt-Fx to switch the console from /dev/tty1 to tty7. There are many more +/dev/tty* which are not accessed via function keys. To be safe, use a tty +greater than tty7) + +---------------------- +./runUnit < /dev/tty40 +---------------------- + +If the process doesn't run as root (recommended), root will have to change the +owner and permissions of the tty: +------------------------- +sudo chmod o+r /dev/tty40 +------------------------- + +To make this permission permanent (at least on Debian) - and not revert back on +reboot - create the file `/etc/udev/rules.d/10-mydejagnu.rules`, containing: +---------------------------- +KERNEL=="tty40", MODE="0666" +---------------------------- + +To start the test at 01:00, set the crontab to this: +---------------------------- +* 1 * * * cd bash-completion/test && ./cron.sh < /dev/tty40 +---------------------------- + +Here's an example batch file `cron.sh`, to be put in the bash-completion `test` +directory. This batch file only e-mails the output of each test-run if the +test-run fails. + +[source,bash] +--------------------------------------------------------------------- +#!/bin/sh + +set -e # Exit if simple command fails +set -u # Error if variable is undefined + +CRON=running +LOG=/tmp/bash-completion.log~ + + # Retrieve latest sources +git pull + + # Run tests on bash-4 + +./runUnit --outdir log/bash-4 --tool_exec /opt/bash-4.0/bin/bash > $LOG || cat $LOG +./runCompletion --outdir log/bash-4 --tool_exec /opt/bash-4.0/bin/bash > $LOG || cat $LOG + + # Clean up log file +[ -f $LOG ] && rm $LOG +--------------------------------------------------------------------- + +Specifying bash binary +~~~~~~~~~~~~~~~~~~~~~~ + +The test suite standard uses `bash` as found in the tcl path (/bin/bash). +Using `--tool_exec` you can specify which bash binary you want to run the test +suite against, e.g.: + +---------------- +./runUnit --tool_exec /opt/bash-4.0/bin/bash +---------------- + + + + +Maintenance +----------- + + +Adding a completion test +~~~~~~~~~~~~~~~~~~~~~~~~ + +You can run `cd test && ./generate cmd` to add a test for the `cmd` command. +This will add two files with a very basic tests: +---------------------------------- +test/completion/cmd.exp +test/lib/completions/cmd.exp +---------------------------------- +Place any additional tests into `test/lib/completions/cmd.exp`. + + +Fixing a completion test +~~~~~~~~~~~~~~~~~~~~~~~~ +Let's consider this real-life example where an ssh completion bug is fixed. +First you're triggered by unsuccessful tests: + +---------------------------------- +$ ./runCompletion +... + === completion Summary === + +# of expected passes 283 +# of unexpected failures 8 +# of unresolved testcases 2 +# of unsupported tests 47 +---------------------------------- + +Take a look in `log/completion.log` to find out which specific command is +failing. + +----------------------- +$ vi log/completion.log +----------------------- + +Search for `UNRESOLVED` or `FAIL`. From there scroll up to see which `.exp` +test is failing: + +--------------------------------------------------------- +/@Running ./completion/ssh.exp ... +... +UNRESOLVED: Tab should complete ssh known-hosts at prompt +--------------------------------------------------------- + +In this case it appears `ssh.exp` is causing the problem. Isolate the `ssh` +tests by specifying just `ssh.exp` to run. Furthermore add the `--debug` flag, +so output gets logged in `dbg.log`: + +---------------------------------- +$ ./runCompletion ssh.exp --debug +... + === completion Summary === + +# of expected passes 1 +# of unresolved testcases 1 +---------------------------------- + +Now we can have a detailed look in `dbg.log` to find out what's going wrong. +Open `dbg.log` and search for `UNRESOLVED` (or `FAIL` if that's what you're +looking for): + +--------------------------------------------------------- +UNRESOLVED: Tab should complete ssh known-hosts at prompt +--------------------------------------------------------- + +From there, search up for the first line saying: + +------------------------------------------------- +expect: does "..." match regular expression "..." +------------------------------------------------- + +This tells you where the actual output differs from the expected output. In +this case it looks like the test "ssh -F fixtures/ssh/config " is +expecting just hostnames, whereas the actual completion is containing commands +- but no hostnames. +So what should be expected after "ssh -F fixtures/ssh/config " are *both* +commands and hostnames. This means both the test and the completion need +fixing. Let's start with the test. + +---------------------------- +$ vi lib/completions/ssh.exp +---------------------------- + +Search for the test "Tab should complete ssh known-hosts". Here you could've +seen that what was expected were hostnames ($hosts): + +----------------------------------------- +set expected "^$cmd\r\n$hosts\r\n/@$cmd$" +----------------------------------------- + +Adding *all* commands (which could well be over 2000) to 'expected', seems a +bit overdone so we're gonna change things here. Lets expect the unit test for +`_known_hosts` assures all hosts are returned. Then all we need to do here is +expect one host and one command, just to be kind of sure that both hosts and +commands are completed. + +Looking in the fixture for ssh: + +----------------------------- +$ vi fixtures/ssh/known_hosts +----------------------------- + +it looks like we can add an additional host 'ls_known_host'. Now if we would +perform the test "ssh -F fixtures/ssh/config ls" both the command `ls` and +the host `ls_known_host` should come up. Let's modify the test so: + +-------------------------------------------------------- +$ vi lib/completions/ssh.exp +... +set expected "^$cmd\r\n.*ls.*ls_known_host.*\r\n/@$cmd$" +-------------------------------------------------------- + +Running the test reveals we still have an unresolved test: + +---------------------------------- +$ ./runCompletion ssh.exp --debug +... + === completion Summary === + +# of expected passes 1 +# of unresolved testcases 1 +---------------------------------- + +But if now look into the log file `dbg.log` we can see the completion only +returns commands starting with 'ls' but fails to match our regular expression +which also expects the hostname `ls_known_host': + +----------------------- +$ vi dbg.log +... +expect: does "ssh -F fixtures/ssh/config ls\r\nls lsattr lsb_release lshal lshw lsmod lsof lspci lspcmcia lspgpot lss16toppm\r\nlsusb\r\n/@ssh -F fixtures/ssh/config ls" (spawn_id exp9) match regular expression "^ssh -F fixtures/ssh/config ls\r\n.*ls.*ls_known_host.*\r\n/@ssh -F fixtures/ssh/config ls$"? no +----------------------- + +Now let's fix ssh completion: + +------------------- +$ vi ../contrib/ssh +... +------------------- + +until the test shows: + +---------------------------------- +$ ./runCompletion ssh.exp +... + === completion Summary === + +# of expected passes 2 +---------------------------------- + +Fixing a unit test +~~~~~~~~~~~~~~~~~~ +Now let's consider a unit test failure. First you're triggered by unsuccessful +tests: + +---------------------------------- +$ ./runUnit +... + === unit Summary === + +# of expected passes 1 +# of unexpected failures 1 +---------------------------------- + +Take a look in `log/unit.log` to find out which specific command is failing. + +----------------- +$ vi log/unit.log +----------------- + +Search for `UNRESOLVED` or `FAIL`. From there scroll up to see which `.exp` +test is failing: + +------------------------------------------ +/@Running ./unit/_known_hosts_real.exp ... +... +FAIL: Environment should stay clean +------------------------------------------ + +In this case it appears `_known_hosts_real.exp` is causing the problem. +Isolate the `_known_hosts_real` test by specifying just `_known_hosts_real.exp` +to run. Furthermore add the `--debug` flag, so output gets logged in +`dbg.log`: + +---------------------------------- +$ ./runUnit _known_hosts_real.exp --debug +... + === completion Summary === + +# of expected passes 1 +# of unexpected failures 1 +---------------------------------- + +Now, if we haven't already figured out the problem, we can have a detailed look +in `dbg.log` to find out what's going wrong. Open `dbg.log` and search for +`UNRESOLVED` (or `FAIL` if that's what you're looking for): + +----------------------------------- +FAIL: Environment should stay clean +----------------------------------- + +From there, search up for the first line saying: + +------------------------------------------------- +expect: does "..." match regular expression "..." +------------------------------------------------- + +This tells you where the actual output differs from the expected output. In +this case it looks like the the function `_known_hosts_real` is unexpectedly +modifying global variables `cur` and `flag`. In case you need to modify the +test: + +----------------------------------- +$ vi lib/unit/_known_hosts_real.exp +----------------------------------- + +Rationale +--------- + + +Naming conventions +~~~~~~~~~~~~~~~~~~ + +Test suite or testsuite +^^^^^^^^^^^^^^^^^^^^^^^ +The primary Wikipedia page is called +http://en.wikipedia.org/wiki/Test_suite[test suite] and not testsuite, so +that's what this document sticks to. + +script/generate +^^^^^^^^^^^^^^^ +The name and location of this code generation script come from Ruby on Rails' +http://en.wikibooks.org/wiki/Ruby_on_Rails/Tools/Generators[script/generate]. + + + + +== Reference + +Within test scripts the following library functions can be used: + +[[Test_context]] +== Test context + +The test environment needs to be put to fixed states when testing. For +instance the bash prompt (PS1) is set to the current test directory, followed +by an at sign (@). The default settings for `bash` reside in `config/bashrc` +and `config/inputrc`. + +For each tool (completion, install, unit) a slightly different context is in +effect. + +=== What happens when tests are run? + +==== completion + +When the completions are tested, invoking DejaGnu will result in a call to +`completion_start()` which in turn will start `bash --rcfile config/bashrc`. + +.What happens when completion tests are run? +---- + | runtest --tool completion + V + +----------+-----------+ + | lib/completion.exp | + | lib/library.exp | + | config/default.exp | + +----------+-----------+ + : + V + +----------+-----------+ +---------------+ +----------------+ + | completion_start() +<---+ config/bashrc +<---| config/inputrc | + | (lib/completion.exp) | +---------------+ +----------------+ + +----------+-----------+ + | ,+----------------------------+ + | ,--+-+ "Actual completion tests" | + V / +------------------------------+ + +----------+-----------+ +-----------------------+ + | completion/*.exp +<---| lib/completions/*.exp | + +----------+-----------+ +-----------------------+ + | \ ,+--------------------------------+ + | `----------------------+-+ "Completion invocation tests" | + V +----------------------------------+ + +----------+-----------+ + | completion_exit() | + | (lib/completion.exp) | + +----------------------+ +---- +Setting up bash once within `completion_start()` has the speed advantage that +bash - and bash-completion - need only initialize once when testing multiple +completions, e.g.: +---- + runtest --tool completion alias.exp cd.exp +---- +==== install + +.What happens when install tests are run? +---- + | runtest --tool install + V + +----+----+ + | DejaGnu | + +----+----+ + | + V + +------------+---------------+ + | (file: config/default.exp) | + +------------+---------------+ + | + V + +------------+------------+ + | (file: lib/install.exp) | + +-------------------------+ +---- + +==== unit + +.What happens when unit tests are run? +---- + | runtest --tool unit + V + +----+----+ + | DejaGnu | + +----+----+ + | + V + +----------+-----------+ + | - | + | (file: lib/unit.exp) | + +----------------------+ +---- + +=== bashrc + +This is the bash configuration file (bashrc) used for testing: + +[source,bash] +--------------------------------------------------------------------- +include::bashrc[] +--------------------------------------------------------------------- + + +=== inputrc + +This is the readline configuration file (inputrc) used for testing: + +[source,bash] +--------------------------------------------------------------------- +include::inputrc[] +--------------------------------------------------------------------- + + +Index +===== diff --git a/test/completion/ccache.exp b/test/completion/ccache.exp new file mode 100644 index 00000000..4d88bf98 --- /dev/null +++ b/test/completion/ccache.exp @@ -0,0 +1 @@ +assert_source_completions ccache diff --git a/test/completion/desktop-file-validate.exp b/test/completion/desktop-file-validate.exp new file mode 100644 index 00000000..e026a68c --- /dev/null +++ b/test/completion/desktop-file-validate.exp @@ -0,0 +1 @@ +assert_source_completions desktop-file-validate diff --git a/test/completion/export.exp b/test/completion/export.exp new file mode 100644 index 00000000..bab517a9 --- /dev/null +++ b/test/completion/export.exp @@ -0,0 +1 @@ +assert_source_completions export diff --git a/test/completion/htop.exp b/test/completion/htop.exp new file mode 100644 index 00000000..c5372475 --- /dev/null +++ b/test/completion/htop.exp @@ -0,0 +1 @@ +assert_source_completions htop diff --git a/test/completion/iperf.exp b/test/completion/iperf.exp new file mode 100644 index 00000000..f5f19ef5 --- /dev/null +++ b/test/completion/iperf.exp @@ -0,0 +1 @@ +assert_source_completions iperf diff --git a/test/completion/koji.exp b/test/completion/koji.exp new file mode 100644 index 00000000..4d85dfc2 --- /dev/null +++ b/test/completion/koji.exp @@ -0,0 +1 @@ +assert_source_completions koji diff --git a/test/completion/lzip.exp b/test/completion/lzip.exp new file mode 100644 index 00000000..faa83a41 --- /dev/null +++ b/test/completion/lzip.exp @@ -0,0 +1 @@ +assert_source_completions lzip diff --git a/test/completion/nethogs.exp b/test/completion/nethogs.exp new file mode 100644 index 00000000..4d501ace --- /dev/null +++ b/test/completion/nethogs.exp @@ -0,0 +1 @@ +assert_source_completions nethogs diff --git a/test/completion/pidof.exp b/test/completion/pidof.exp new file mode 100644 index 00000000..c66ee9f9 --- /dev/null +++ b/test/completion/pidof.exp @@ -0,0 +1 @@ +assert_source_completions pidof diff --git a/test/completion/plague-client.exp b/test/completion/plague-client.exp new file mode 100644 index 00000000..6f9a9373 --- /dev/null +++ b/test/completion/plague-client.exp @@ -0,0 +1 @@ +assert_source_completions plague-client diff --git a/test/completion/udevadm.exp b/test/completion/udevadm.exp new file mode 100644 index 00000000..69c980ff --- /dev/null +++ b/test/completion/udevadm.exp @@ -0,0 +1 @@ +assert_source_completions udevadm diff --git a/test/completion/umount.exp b/test/completion/umount.exp new file mode 100644 index 00000000..39c4d114 --- /dev/null +++ b/test/completion/umount.exp @@ -0,0 +1 @@ +assert_source_completions umount diff --git a/test/completion/valgrind.exp b/test/completion/valgrind.exp new file mode 100644 index 00000000..aadd5a52 --- /dev/null +++ b/test/completion/valgrind.exp @@ -0,0 +1 @@ +assert_source_completions valgrind diff --git a/test/completion/vi.exp b/test/completion/vi.exp new file mode 100644 index 00000000..b0191404 --- /dev/null +++ b/test/completion/vi.exp @@ -0,0 +1 @@ +assert_source_completions vi diff --git a/test/completion/wine.exp b/test/completion/wine.exp new file mode 100644 index 00000000..ddb1e6f1 --- /dev/null +++ b/test/completion/wine.exp @@ -0,0 +1 @@ +assert_source_completions wine diff --git a/test/fixtures/_known_hosts_real/config_tilde b/test/fixtures/_known_hosts_real/config_tilde index 1068e299..0893515b 100644 --- a/test/fixtures/_known_hosts_real/config_tilde +++ b/test/fixtures/_known_hosts_real/config_tilde @@ -1,4 +1,4 @@ # With quotes and tilde UserKnownHostsFile "~/fixtures/_known_hosts_real/known_hosts2" -# Without quotes, with tilde -UserKnownHostsFile ~/fixtures/_known_hosts_real/known_hosts3 +# Without quotes, with tilde, and another on the same line +UserKnownHostsFile ~/fixtures/_known_hosts_real/known_hosts3 fixtures/_known_hosts_real/known_hosts4 diff --git a/test/fixtures/_known_hosts_real/known_hosts b/test/fixtures/_known_hosts_real/known_hosts index f655eaa3..0d6f5025 100644 --- a/test/fixtures/_known_hosts_real/known_hosts +++ b/test/fixtures/_known_hosts_real/known_hosts @@ -3,7 +3,7 @@ doo ike ssh-rsa qwerty1234/Qwerty+1234== jub,10.0.0.1 -kyl,100.0.0.2 +@cert-authority kyl,100.0.0.2 xxxfoo [10.10.0.3]:10022 [blah]:1234 fd00:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:5555 diff --git a/test/fixtures/_known_hosts_real/known_hosts2 b/test/fixtures/_known_hosts_real/known_hosts2 index f719efd4..2eb4d4f7 100644 --- a/test/fixtures/_known_hosts_real/known_hosts2 +++ b/test/fixtures/_known_hosts_real/known_hosts2 @@ -1 +1 @@ -two +two,two2,two3,two*,t?o,two4 diff --git a/test/fixtures/_known_hosts_real/known_hosts4 b/test/fixtures/_known_hosts_real/known_hosts4 new file mode 100644 index 00000000..85106651 --- /dev/null +++ b/test/fixtures/_known_hosts_real/known_hosts4 @@ -0,0 +1 @@ +four diff --git a/test/fixtures/make/Makefile b/test/fixtures/make/Makefile new file mode 100644 index 00000000..1a6416cd --- /dev/null +++ b/test/fixtures/make/Makefile @@ -0,0 +1,16 @@ +NAME := sample + +.PHONY: all +all: $(NAME) + +$(NAME): sample.c + cc -o $@ $^ + +.PHONY: install +install: all + mkdir -p /usr/bin + install -m 755 $(NAME) /usr/bin + +.PHONY: clean +clean: + -rm -f $(NAME) diff --git a/test/fixtures/make/empty_dir/.nothing_here b/test/fixtures/make/empty_dir/.nothing_here new file mode 100644 index 00000000..e69de29b diff --git a/test/fixtures/make/sample.c b/test/fixtures/make/sample.c new file mode 100644 index 00000000..2be4600f --- /dev/null +++ b/test/fixtures/make/sample.c @@ -0,0 +1,7 @@ +#include + +int main(void) +{ + puts("Hello, world!"); + return 0; +} diff --git a/test/fixtures/shared/ld.so.conf.d/foo.txt b/test/fixtures/shared/ld.so.conf.d/foo.txt new file mode 100644 index 00000000..e69de29b diff --git a/test/fixtures/shared/ld.so.conf.d/libfoo.conf b/test/fixtures/shared/ld.so.conf.d/libfoo.conf new file mode 100644 index 00000000..e69de29b diff --git a/test/fixtures/shared/ld.so.conf.d/libfoo.so b/test/fixtures/shared/ld.so.conf.d/libfoo.so new file mode 100644 index 00000000..e69de29b diff --git a/test/fixtures/shared/ld.so.conf.d/libfoo.so.1 b/test/fixtures/shared/ld.so.conf.d/libfoo.so.1 new file mode 100644 index 00000000..e69de29b diff --git a/test/lib/completions/ccache.exp b/test/lib/completions/ccache.exp new file mode 100644 index 00000000..156c881a --- /dev/null +++ b/test/lib/completions/ccache.exp @@ -0,0 +1,18 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified +} + + +setup + + +assert_complete_any "ccache -" +sync_after_int + + +teardown diff --git a/test/lib/completions/cppcheck.exp b/test/lib/completions/cppcheck.exp index 4acd709a..80b6e7b6 100644 --- a/test/lib/completions/cppcheck.exp +++ b/test/lib/completions/cppcheck.exp @@ -27,4 +27,16 @@ assert_no_complete "cppcheck -D " sync_after_int +assert_complete "--enable=all" "cppcheck --enable=al" +sync_after_int + + +assert_complete "--enable=xx,style" "cppcheck --enable=xx,styl" +sync_after_int + + +assert_complete "--enable=xx,yy,style" "cppcheck --enable=xx,yy,styl" +sync_after_int + + teardown diff --git a/test/lib/completions/desktop-file-validate.exp b/test/lib/completions/desktop-file-validate.exp new file mode 100644 index 00000000..40cbf82f --- /dev/null +++ b/test/lib/completions/desktop-file-validate.exp @@ -0,0 +1,20 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified +} + + +setup + + +assert_complete_any "desktop-file-validate " + + +sync_after_int + + +teardown diff --git a/test/lib/completions/export.exp b/test/lib/completions/export.exp new file mode 100644 index 00000000..84cb9170 --- /dev/null +++ b/test/lib/completions/export.exp @@ -0,0 +1,55 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified { + /OLDPWD=/d + } +} + + +setup + + +assert_complete_any "export BASH" +sync_after_int + + +assert_complete_any "export -n BASH" +sync_after_int + + +assert_no_complete "export -p " +sync_after_int + + +assert_complete_dir {bar "bar bar.d/" foo foo.d/} "export FOO=" \ + fixtures/shared/default +sync_after_int + + +assert_complete_dir {foo foo.d/} "export FOO=f" fixtures/shared/default "" \ + -expect-cmd-minus f +sync_after_int + + +# Functions: _export, _expand, ... +assert_complete_any "export -fn _ex" +sync_after_int + + +assert_complete_any "export -f -n _ex" +sync_after_int + + +assert_complete_any "export FOO=\$BASH" +sync_after_int + + +assert_complete_any "export -" +sync_after_int + + +teardown diff --git a/test/lib/completions/htop.exp b/test/lib/completions/htop.exp new file mode 100644 index 00000000..d3e94d10 --- /dev/null +++ b/test/lib/completions/htop.exp @@ -0,0 +1,20 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified +} + + +setup + + +assert_complete_any "htop -" + + +sync_after_int + + +teardown diff --git a/test/lib/completions/iperf.exp b/test/lib/completions/iperf.exp new file mode 100644 index 00000000..66a0ba3b --- /dev/null +++ b/test/lib/completions/iperf.exp @@ -0,0 +1,20 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified +} + + +setup + + +assert_complete_any "iperf " + + +sync_after_int + + +teardown diff --git a/test/lib/completions/killall.exp b/test/lib/completions/killall.exp index 1ee3ade8..feec9337 100644 --- a/test/lib/completions/killall.exp +++ b/test/lib/completions/killall.exp @@ -17,7 +17,7 @@ assert_complete_any "killall " sync_after_int -assert_complete [get_signals -] "killall -" +assert_complete [get_signals] "killall --signal " sync_after_int diff --git a/test/lib/completions/koji.exp b/test/lib/completions/koji.exp new file mode 100644 index 00000000..a9673807 --- /dev/null +++ b/test/lib/completions/koji.exp @@ -0,0 +1,22 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified +} + + +setup + + +assert_complete_any "koji " +sync_after_int + + +assert_complete_any "koji -" +sync_after_int + + +teardown diff --git a/test/lib/completions/lzip.exp b/test/lib/completions/lzip.exp new file mode 100644 index 00000000..fd92af62 --- /dev/null +++ b/test/lib/completions/lzip.exp @@ -0,0 +1,20 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified +} + + +setup + + +assert_complete_any "lzip " + + +sync_after_int + + +teardown diff --git a/test/lib/completions/make.exp b/test/lib/completions/make.exp index 64a393da..977485d2 100644 --- a/test/lib/completions/make.exp +++ b/test/lib/completions/make.exp @@ -4,14 +4,39 @@ proc setup {} { proc teardown {} { - assert_env_unmodified + assert_env_unmodified {/OLDPWD=/d} } setup -assert_complete_any "make " +set test "-f Ma should complete \"Makefile\"" +set dir $::srcdir/fixtures/make +assert_complete_dir "Makefile" "make -f Ma" $dir $test + + +sync_after_int + + +set test "\"make \" should complete targets" +set dir $::srcdir/fixtures/make +set targets "all sample install clean" +assert_complete_dir $targets "make " $dir $test + + +sync_after_int + + +set test "\"make \" should not show anything in directory without makefile" +set dir $::srcdir/fixtures/make/empty_dir +assert_complete_dir "" "make " $dir $test + + +sync_after_int + + +assert_complete_any "make -j " sync_after_int diff --git a/test/lib/completions/nethogs.exp b/test/lib/completions/nethogs.exp new file mode 100644 index 00000000..d6234070 --- /dev/null +++ b/test/lib/completions/nethogs.exp @@ -0,0 +1,20 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified +} + + +setup + + +assert_complete_any "nethogs " + + +sync_after_int + + +teardown diff --git a/test/lib/completions/perldoc.exp b/test/lib/completions/perldoc.exp index 9a9d9fbf..a745b55d 100644 --- a/test/lib/completions/perldoc.exp +++ b/test/lib/completions/perldoc.exp @@ -24,17 +24,10 @@ expect { -re /@ { unresolved "$test" } default { unresolved "$test" } } - - sync_after_int -set test "- should complete options" -set options { - -h -v -t -u -m -l -F -X -f -q -} -assert_complete $options "perldoc -" $test - +assert_complete_any "perldoc -" sync_after_int diff --git a/test/lib/completions/pidof.exp b/test/lib/completions/pidof.exp new file mode 100644 index 00000000..8fdab978 --- /dev/null +++ b/test/lib/completions/pidof.exp @@ -0,0 +1,20 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified +} + + +setup + + +assert_complete_any "pidof " + + +sync_after_int + + +teardown diff --git a/test/lib/completions/plague-client.exp b/test/lib/completions/plague-client.exp new file mode 100644 index 00000000..ddcc8491 --- /dev/null +++ b/test/lib/completions/plague-client.exp @@ -0,0 +1,20 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified +} + + +setup + + +assert_complete_any "plague-client " + + +sync_after_int + + +teardown diff --git a/test/lib/completions/ssh.exp b/test/lib/completions/ssh.exp index 1599dccc..3ef0bb69 100644 --- a/test/lib/completions/ssh.exp +++ b/test/lib/completions/ssh.exp @@ -60,7 +60,7 @@ sync_after_int set test "First argument should complete partial hostname" -assert_complete_partial [get_hosts] ssh "" $test -ltrim-colon-completions +assert_complete_partial [get_known_hosts] ssh "l" $test -ltrim-colon-completions sync_after_int diff --git a/test/lib/completions/udevadm.exp b/test/lib/completions/udevadm.exp new file mode 100644 index 00000000..bef16f0b --- /dev/null +++ b/test/lib/completions/udevadm.exp @@ -0,0 +1,20 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified +} + + +setup + + +assert_complete_any "udevadm " + + +sync_after_int + + +teardown diff --git a/test/lib/completions/umount.exp b/test/lib/completions/umount.exp new file mode 100644 index 00000000..21a2dfa5 --- /dev/null +++ b/test/lib/completions/umount.exp @@ -0,0 +1,20 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified +} + + +setup + + +assert_complete_any "umount " + + +sync_after_int + + +teardown diff --git a/test/lib/completions/upgradepkg.exp b/test/lib/completions/upgradepkg.exp index 860dde9e..4783aec3 100644 --- a/test/lib/completions/upgradepkg.exp +++ b/test/lib/completions/upgradepkg.exp @@ -36,4 +36,16 @@ assert_complete_dir $files "upgradepkg " $dir $test sync_after_int +set test "should complete *.t\[gbxl\]z files and dirs after % sign" +set oldpkg "xx-2.0-i486-2" +set dir $::srcdir/fixtures/slackware/home +set files [split [exec bash -c "cd $dir && find . -mindepth 1 -maxdepth 1 \ + \\( -type d -printf '$oldpkg%%%P/\\n' \\) -o \ + \\( -type f -name '*.t\[bglx\]z' -printf '$oldpkg%%%P\\n' \\)"] "\n"] +assert_complete_dir $files "upgradepkg $oldpkg%" $dir $test + + +sync_after_int + + teardown diff --git a/test/lib/completions/valgrind.exp b/test/lib/completions/valgrind.exp new file mode 100644 index 00000000..6e3702b6 --- /dev/null +++ b/test/lib/completions/valgrind.exp @@ -0,0 +1,50 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified {/OLDPWD=/d} +} + + +setup + + +# b: assuming we have at least bash that starts with b in $PATH +assert_complete_any "valgrind b" + + +sync_after_int + + +assert_complete_any "valgrind -" + + +sync_after_int + + +set test "--tool=memche should complete \"memcheck\"" +assert_complete "--tool=memcheck" "valgrind --tool=memche" $test + + +sync_after_int + + +set test "--tool=helgrind --history-l should complete \"--history-level=\"" +assert_complete "--history-level=" "valgrind --tool=helgrind --history-l" $test -nospace + + +sync_after_int + + +set test "it should be possible to complete file paths" +set dir $::srcdir/fixtures/shared +set files [split [exec bash -c "cd $dir/bin && ls -p"] "\n"] +assert_complete_dir $files "valgrind --log-file=v\\ 0.log ./bin/" $dir $test + + +sync_after_int + + +teardown diff --git a/test/lib/completions/vi.exp b/test/lib/completions/vi.exp new file mode 100644 index 00000000..db3e3deb --- /dev/null +++ b/test/lib/completions/vi.exp @@ -0,0 +1,22 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified +} + + +setup + + +assert_complete_any "vi " +sync_after_int + + +assert_complete {libfoo.conf foo.txt} "vi $::srcdir/fixtures/shared/ld.so.conf.d/" +sync_after_int + + +teardown diff --git a/test/lib/completions/wine.exp b/test/lib/completions/wine.exp new file mode 100644 index 00000000..2cc60c48 --- /dev/null +++ b/test/lib/completions/wine.exp @@ -0,0 +1,31 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified {/OLDPWD=/d} +} + + +setup + + +set test "should complete *.exe, *.com files and dirs" +set dir $::srcdir/fixtures/shared/default +assert_complete_dir {"bar bar.d/" foo.d/} "wine " $dir $test + + +sync_after_int + + +set test "should complete any files and dirs after executable" +set dir $::srcdir/fixtures/shared/default +set files {bar "bar bar.d/" foo foo.d/} +assert_complete_dir $files "wine notepad " $dir $test + + +sync_after_int + + +teardown diff --git a/test/lib/library.exp b/test/lib/library.exp index f6e9f21a..b2233258 100644 --- a/test/lib/library.exp +++ b/test/lib/library.exp @@ -357,8 +357,9 @@ proc assert_complete_any {cmd {test ""} {prompt /@}} { } -# Make sure the expected files are returned by TAB-completing the -# specified command in the specified subdirectory. +# Make sure the expected files are returned by TAB-completing the specified +# command in the specified subdirectory. Be prepared to filter out OLDPWD +# changes when calling assert_env_unmodified() after using this procedure. # @param list $expected # @param string $cmd Command given to generate items # @param string $dir Subdirectory to attempt completion in. The directory must be relative from the $TESTDIR and without a trailing slash. E.g. `fixtures/evince' @@ -368,7 +369,7 @@ proc assert_complete_any {cmd {test ""} {prompt /@}} { proc assert_complete_dir {expected cmd dir {test ""} {args {}}} { set prompt "/@" assert_bash_exec "cd $dir" "" $prompt - assert_complete $expected $cmd $test $args + eval assert_complete \$expected \$cmd \$test $args sync_after_int $prompt assert_bash_exec {cd "$TESTDIR"} } diff --git a/test/unit/_get_comp_words_by_ref.exp b/test/unit/_get_comp_words_by_ref.exp index f5c7ab38..c113f6df 100644 --- a/test/unit/_get_comp_words_by_ref.exp +++ b/test/unit/_get_comp_words_by_ref.exp @@ -115,6 +115,14 @@ assert_bash_list {"b\\ c a"} $cmd $test sync_after_int +set test {a\ b a\ b| should return a\ b}; # | = cursor position +set cmd {COMP_WORDS=('a\ b' 'a\ b'); COMP_CWORD=1; COMP_LINE='a\ b a\ b'; COMP_POINT=9; _get_comp_words_by_ref cur prev; echo "$cur $prev"} +assert_bash_list {"a\\ b a\\ b"} $cmd $test + + +sync_after_int + + set test {a b\| c should return b\ }; # | = cursor position set cmd {COMP_WORDS=(a 'b\ c'); COMP_CWORD=1; COMP_LINE='a b\ c'; COMP_POINT=4; _get_comp_words_by_ref cur prev; echo "$cur $prev"} assert_bash_list {"b\\ a"} $cmd $test diff --git a/test/unit/_known_hosts_real.exp b/test/unit/_known_hosts_real.exp index 0e381fa7..30ede41c 100644 --- a/test/unit/_known_hosts_real.exp +++ b/test/unit/_known_hosts_real.exp @@ -52,8 +52,8 @@ set test "Files containing consecutive spaces should work" set hosts [get_hosts -unsorted] set hosts_orig $hosts # Hosts `gee' and `hus' are defined in `./fixtures/_known_hosts_real/spaced conf' - # Host `two' is defined in ./fixtures/_known_hosts_real/known_hosts2 -lappend hosts gee hus two + # Hosts `two*' are defined in ./fixtures/_known_hosts_real/known_hosts2 +lappend hosts gee hus two two2 two3 two4 set hosts_config $hosts # Hosts `doo' and `ike' are defined in `./fixtures/_known_hosts_/spaced known_hosts' lappend hosts doo ike @@ -78,9 +78,10 @@ sync_after_int set test "Files starting with tilde (~) should work" set hosts [get_hosts -unsorted] - # Host `two' is defined in ./fixtures/_known_hosts_real/known_hosts2 + # Hosts `two*' are defined in ./fixtures/_known_hosts_real/known_hosts2 # Host `three' is defined in ./fixtures/_known_hosts_real/known_hosts3 -lappend hosts two three + # Host `four' is defined in ./fixtures/_known_hosts_real/known_hosts4 +lappend hosts two two2 two3 two4 three four set hosts [join [bash_sort $hosts] "\\s+"] # Setup environment set cmd {OLDHOME=$HOME; HOME=$SRCDIRABS} diff --git a/test/unit/_parse_help.exp b/test/unit/_parse_help.exp index a6d58d5a..43c5dc29 100644 --- a/test/unit/_parse_help.exp +++ b/test/unit/_parse_help.exp @@ -7,6 +7,7 @@ proc setup {} { proc teardown {} { assert_env_unmodified { /declare -f fn/d + /PIPESTATUS=/d } } @@ -129,5 +130,9 @@ set cmd {fn() { printf '%s\n' "-f or --foo"; }; _parse_help fn} assert_bash_list "--foo" $cmd "-f or --foo" sync_after_int +set cmd { printf '%s\n' "-f or --foo" | _parse_help - } +assert_bash_list "--foo" $cmd "from stdin" +sync_after_int + teardown diff --git a/test/unit/_parse_usage.exp b/test/unit/_parse_usage.exp index 0069848d..5a40b1fe 100644 --- a/test/unit/_parse_usage.exp +++ b/test/unit/_parse_usage.exp @@ -5,6 +5,7 @@ proc setup {} { proc teardown {} { assert_env_unmodified { /declare -f fn/d + /PIPESTATUS=/d } } @@ -55,5 +56,9 @@ set cmd {fn() { printf '%s\n' "----\n---foo\n----- bar"; }; _parse_usage fn} assert_bash_list "" $cmd "many dashes" sync_after_int +set cmd { printf '%s\n' "[-duh]" | _parse_usage - } +assert_bash_list "-d -u -h" $cmd "from stdin" +sync_after_int + teardown diff --git a/test/unit/quote.exp b/test/unit/quote.exp new file mode 100644 index 00000000..afe670a2 --- /dev/null +++ b/test/unit/quote.exp @@ -0,0 +1,69 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified +} + + +setup + + +set cmd {quote "a b"} +set test {quote "a b" should output 'a b'} +send "$cmd\r" +expect -ex "$cmd\r\n" +expect { + -re {'a b'} { pass $test } + default { fail $test } +} +sync_after_int + + +set cmd {quote "a b"} +set test {quote "a b" should output 'a b'} +send "$cmd\r" +expect -ex "$cmd\r\n" +expect { + -re {'a b'} { pass $test } + default { fail $test } +} +sync_after_int + + +set cmd {quote " a "} +set test {quote " a " should output ' a '} +send "$cmd\r" +expect -ex "$cmd\r\n" +expect { + -re {' a '} { pass $test } + default { fail $test } +} +sync_after_int + + +set cmd {quote "a'b'c"} +set test {quote "a'b'c" should output 'a'\''b'\''c'} +send "$cmd\r" +expect -ex "$cmd\r\n" +expect { + -re {'a'\\''b'\\''c'} { pass $test } + default { fail $test } +} +sync_after_int + + +set cmd {quote "a'"} +set test {quote "a'" should output 'a'\'''} +send "$cmd\r" +expect -ex "$cmd\r\n" +expect { + -re {'a'\\'''} { pass $test } + default { fail $test } +} +sync_after_int + + +teardown -- cgit v1.2.1