summaryrefslogtreecommitdiff
path: root/bash_completion
diff options
context:
space:
mode:
authorDavid Paleino <dapal@debian.org>2011-02-06 21:26:41 +0100
committerDavid Paleino <dapal@debian.org>2011-02-06 21:26:41 +0100
commit9920a8faedf704420571d8072ccab27e9dac40ba (patch)
tree733edf3b07be06c130d04aaa1884213326722cad /bash_completion
parentf9748115fb4b2950fb4df7535fb723c4affde078 (diff)
downloadbash-completion-9920a8faedf704420571d8072ccab27e9dac40ba.tar.gz
Imported Upstream version 1.3upstream/1.3
Diffstat (limited to 'bash_completion')
-rw-r--r--bash_completion447
1 files changed, 248 insertions, 199 deletions
diff --git a/bash_completion b/bash_completion
index e7a4b6ec..66019379 100644
--- a/bash_completion
+++ b/bash_completion
@@ -2,7 +2,7 @@
# bash_completion - programmable completion functions for bash 3.2+
#
# Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>
-# © 2009-2010, Bash Completion Maintainers
+# © 2009-2011, Bash Completion Maintainers
# <bash-completion-devel@lists.alioth.debian.org>
#
# This program is free software; you can redistribute it and/or modify
@@ -23,7 +23,7 @@
#
# http://bash-completion.alioth.debian.org/
#
-# RELEASE: 1.1
+# RELEASE: 1.3
if [[ $- == *v* ]]; then
BASH_COMPLETION_ORIGINAL_V_VALUE="-v"
@@ -70,41 +70,42 @@ complete -d pushd
# START exclude -- do NOT remove this line
# bzcmp, bzdiff, bz*grep, bzless, bzmore intentionally not here, see Debian: #455510
complete -f -X '!*.?(t)bz?(2)' bunzip2 bzcat pbunzip2 pbzcat
-complete -f -X '!*.@(zip|ZIP|[ejw]ar|[EJW]AR|exe|EXE|pk3|wsz|zargo|xpi|sxw|o[tx]t|od[fgpst]|epub)' unzip zipinfo
+complete -f -X '!*.@(zip|[ejw]ar|exe|pk3|wsz|zargo|xpi|sxw|o[tx]t|od[fgpst]|epub|apk)' unzip zipinfo
complete -f -X '*.Z' compress znew
# zcmp, zdiff, z*grep, zless, zmore intentionally not here, see Debian: #455510
complete -f -X '!*.@(Z|[gGd]z|t[ag]z)' gunzip zcat unpigz
complete -f -X '!*.Z' uncompress
# lzcmp, lzdiff intentionally not here, see Debian: #455510
-complete -f -X '!*.lzma' lzcat lzegrep lzfgrep lzgrep lzless lzmore unlzma
-complete -f -X '!*.@(xz|lzma)' unxz xzcat
-complete -f -X '!*.@(gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx|GIF|JP?(E)G|MIFF|TIF?(F)|PN[GM]|P[BGP]M|BMP|XPM|ICO|XWD|TGA|PCX)' ee
-complete -f -X '!*.@(gif|jp?(e)g|tif?(f)|png|p[bgp]m|bmp|x[bp]m|rle|rgb|pcx|fits|pm|GIF|JPG|JP?(E)G|TIF?(F)|PNG|P[BGP]M|BMP|X[BP]M|RLE|RGB|PCX|FITS|PM)' xv qiv
+complete -f -X '!*.@(tlz|lzma)' lzcat lzegrep lzfgrep lzgrep lzless lzmore unlzma
+complete -f -X '!*.@(?(t)xz|tlz|lzma)' unxz xzcat
+complete -f -X '!*.lrz' lrunzip
+complete -f -X '!*.@(gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx)' ee
+complete -f -X '!*.@(gif|jp?(e)g|tif?(f)|png|p[bgp]m|bmp|x[bp]m|rle|rgb|pcx|fits|pm)' xv qiv
complete -f -X '!*.@(@(?(e)ps|?(E)PS|pdf|PDF)?(.gz|.GZ|.bz2|.BZ2|.Z))' gv ggv kghostview
-complete -f -X '!*.@(dvi|DVI)?(.@(gz|Z|bz2))' xdvi
-complete -f -X '!*.@(dvi|DVI)?(.@(gz|Z|bz2))' kdvi
-complete -f -X '!*.@(dvi|DVI)' dvips dviselect dvitype dvipdf advi dvipdfm dvipdfmx
-complete -f -X '!*.@(pdf|PDF)' acroread gpdf xpdf
-complete -f -X '!*.@(?(e)ps|?(E)PS|pdf|PDF)' kpdf
-complete -f -X '!*.@(@(?(e)ps|?(E)PS|pdf|PDF|dvi|DVI)?(.gz|.GZ|.bz2|.BZ2)|cb[rz]|CB[RZ]|djv?(u)|DJV?(U)|dvi|DVI|gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx|GIF|JP?(E)G|MIFF|TIF?(F)|PN[GM]|P[BGP]M|BMP|XPM|ICO|XWD|TGA|PCX|fdf|FDF)' evince
-complete -f -X '!*.@(okular|@(?(e|x)ps|?(E|X)PS|pdf|PDF|dvi|DVI|cb[rz]|CB[RZ]|djv?(u)|DJV?(U)|dvi|DVI|gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx|GIF|JP?(E)G|MIFF|TIF?(F)|PN[GM]|P[BGP]M|BMP|XPM|ICO|XWD|TGA|PCX|epub|EPUB|odt|ODT|fb|FB|mobi|MOBI|g3|G3|chm|CHM|fdf|FDF)?(.?(gz|GZ|bz2|BZ2)))' okular
-complete -f -X '!*.@(?(e)ps|?(E)PS|pdf|PDF)' ps2pdf ps2pdf12 ps2pdf13 ps2pdf14 ps2pdfwr
+complete -f -X '!*.@(dvi|DVI)?(.@(gz|Z|bz2))' xdvi kdvi
+complete -f -X '!*.dvi' dvips dviselect dvitype dvipdf advi dvipdfm dvipdfmx
+complete -f -X '!*.[pf]df' acroread gpdf xpdf
+complete -f -X '!*.@(?(e)ps|pdf)' kpdf
+complete -f -X '!*.@(@(?(e)ps|?(E)PS|[pf]df|[PF]DF|dvi|DVI)?(.gz|.GZ|.bz2|.BZ2)|cb[rz]|djv?(u)|gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx|fdf)' evince
+complete -f -X '!*.@(okular|@(?(e|x)ps|?(E|X)PS|pdf|PDF|dvi|DVI|cb[rz]|CB[RZ]|djv?(u)|DJV?(U)|dvi|DVI|gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx|GIF|JP?(E)G|MIFF|TIF?(F)|PN[GM]|P[BGP]M|BMP|XPM|ICO|XWD|TGA|PCX|epub|EPUB|odt|ODT|fb?(2)|FB?(2)|mobi|MOBI|g3|G3|chm|CHM|fdf|FDF)?(.?(gz|GZ|bz2|BZ2)))' okular
+complete -f -X '!*.@(?(e)ps|pdf)' ps2pdf ps2pdf12 ps2pdf13 ps2pdf14 ps2pdfwr
complete -f -X '!*.texi*' makeinfo texi2html
-complete -f -X '!*.@(?(la)tex|?(LA)TEX|texi|TEXI|dtx|DTX|ins|INS|ltx|LTX)' tex latex slitex jadetex pdfjadetex pdftex pdflatex texi2dvi
-complete -f -X '!*.@(mp3|MP3)' mpg123 mpg321 madplay
-complete -f -X '!*@(.@(mp?(e)g|MP?(E)G|wma|avi|AVI|asf|vob|VOB|bin|dat|divx|DIVX|vcd|ps|pes|fli|flv|FLV|fxm|FXM|viv|rm|ram|yuv|mov|MOV|qt|QT|wmv|mp[234]|MP[234]|m4[pv]|M4[PV]|mkv|MKV|og[gmv]|OG[GMV]|t[ps]|T[PS]|wav|WAV|flac|FLAC|asx|ASX|mng|MNG|srt|m[eo]d|M[EO]D|s[3t]m|S[3T]M|it|IT|xm|XM)|+([0-9]).@(vdr|VDR))' xine aaxine fbxine kaffeine dragon
+complete -f -X '!*.@(?(la)tex|texi|dtx|ins|ltx)' tex latex slitex jadetex pdfjadetex pdftex pdflatex texi2dvi
+complete -f -X '!*.mp3' mpg123 mpg321 madplay
+complete -f -X '!*@(.@(mp?(e)g|MP?(E)G|wma|avi|AVI|asf|vob|VOB|bin|dat|divx|DIVX|vcd|ps|pes|fli|flv|FLV|fxm|FXM|viv|rm|ram|yuv|mov|MOV|qt|QT|wmv|mp[234]|MP[234]|m4[pv]|M4[PV]|mkv|MKV|og[gmv]|OG[GMV]|t[ps]|T[PS]|m2t?(s)|M2T?(S)|wav|WAV|flac|FLAC|asx|ASX|mng|MNG|srt|m[eo]d|M[EO]D|s[3t]m|S[3T]M|it|IT|xm|XM)|+([0-9]).@(vdr|VDR))?(.part)' xine aaxine fbxine
+complete -f -X '!*@(.@(mp?(e)g|MP?(E)G|wma|avi|AVI|asf|vob|VOB|bin|dat|divx|DIVX|vcd|ps|pes|fli|flv|FLV|fxm|FXM|viv|rm|ram|yuv|mov|MOV|qt|QT|wmv|mp[234]|MP[234]|m4[pv]|M4[PV]|mkv|MKV|og[gmv]|OG[GMV]|t[ps]|T[PS]|m2t?(s)|M2T?(S)|wav|WAV|flac|FLAC|asx|ASX|mng|MNG|srt|m[eo]d|M[EO]D|s[3t]m|S[3T]M|it|IT|xm|XM|iso|ISO)|+([0-9]).@(vdr|VDR))?(.part)' kaffeine dragon
complete -f -X '!*.@(avi|asf|wmv)' aviplay
complete -f -X '!*.@(rm?(j)|ra?(m)|smi?(l))' realplay
complete -f -X '!*.@(mpg|mpeg|avi|mov|qt)' xanim
-complete -f -X '!*.@(ogg|OGG|m3u|flac|spx)' ogg123
-complete -f -X '!*.@(mp3|MP3|ogg|OGG|pls|m3u)' gqmpeg freeamp
+complete -f -X '!*.@(ogg|m3u|flac|spx)' ogg123
+complete -f -X '!*.@(mp3|ogg|pls|m3u)' gqmpeg freeamp
complete -f -X '!*.fig' xfig
-complete -f -X '!*.@(mid?(i)|MID?(I)|cmf|CMF)' playmidi
-complete -f -X '!*.@(mid?(i)|MID?(I)|rmi|RMI|rcp|RCP|[gr]36|[GR]36|g18|G18|mod|MOD|xm|XM|it|IT|x3m|X3M|s[3t]m|S[3T]M|kar|KAR)' timidity
-complete -f -X '!*.@(m[eo]d|M[EO]D|s[3t]m|S[3T]M|xm|XM|it|IT)' modplugplay modplug123
-complete -f -X '*.@(o|so|so.!(conf)|a|rpm|gif|GIF|jp?(e)g|JP?(E)G|mp3|MP3|mp?(e)g|MPG|avi|AVI|asf|ASF|ogg|OGG|class|CLASS)' vi vim gvim rvim view rview rgvim rgview gview emacs xemacs sxemacs kate kwrite
+complete -f -X '!*.@(mid?(i)|cmf)' playmidi
+complete -f -X '!*.@(mid?(i)|rmi|rcp|[gr]36|g18|mod|xm|it|x3m|s[3t]m|kar)' timidity
+complete -f -X '!*.@(m[eo]d|s[3t]m|xm|it)' modplugplay modplug123
+complete -f -X '*.@(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
complete -f -X '!*.@([eE][xX][eE]?(.[sS][oO])|[cC][oO][mM]|[sS][cC][rR])' wine
-complete -f -X '!*.@(zip|ZIP|z|Z|gz|GZ|tgz|TGZ)' bzme
+complete -f -X '!*.@(zip|z|gz|tgz)' bzme
# konqueror not here on purpose, it's more than a web/html browser
complete -f -X '!*.@(?([xX]|[sS])[hH][tT][mM]?([lL]))' netscape mozilla lynx opera galeon dillo elinks amaya firefox mozilla-firefox iceweasel google-chrome chromium-browser epiphany
complete -f -X '!*.@(sxw|stw|sxg|sgl|doc?([mx])|dot?([mx])|rtf|txt|htm|html|odt|ott|odm)' oowriter
@@ -113,22 +114,22 @@ complete -f -X '!*.@(sxc|stc|xls?([bmx])|xlw|xlt?([mx])|[ct]sv|ods|ots)' oocalc
complete -f -X '!*.@(sxd|std|sda|sdd|odg|otg)' oodraw
complete -f -X '!*.@(sxm|smf|mml|odf)' oomath
complete -f -X '!*.odb' oobase
-complete -f -X '!*.rpm' rpm2cpio
-complete -f -X '!*.s@(qlite?(3)|?(3)db)' sqlite3
+complete -f -X '!*.[rs]pm' rpm2cpio
complete -f -X '!*.aux' bibtex
complete -f -X '!*.po' poedit gtranslator kbabel lokalize
complete -f -X '!*.@([Pp][Rr][Gg]|[Cc][Ll][Pp])' harbour gharbour hbpp
complete -f -X '!*.[Hh][Rr][Bb]' hbrun
complete -f -X '!*.ly' lilypond ly2dvi
complete -f -X '!*.@(dif?(f)|?(d)patch)?(.@([gx]z|bz2|lzma))' cdiff
-complete -f -X '!*.@(dif?(f)|?(d)patch)' kompare
complete -f -X '!*.lyx' lyx
+complete -f -X '!@(*.@(ks|jks|jceks|p12|pfx|bks|ubr|gkr|cer|crt|cert|p7b|pkipath|pem|p10|csr|crl)|cacerts)' portecle
+complete -f -X '!*.@(mp[234c]|og[ag]|@(fl|a)ac|m4[abp]|spx|tta|w?(a)v|wma|aif?(f)|asf|ape)' kid3 kid3-qt
# FINISH exclude -- do not remove this line
# start of section containing compspecs that can be handled within bash
# user commands see only users
-complete -u su passwd write chfn groups slay w sux
+complete -u su write chfn groups slay w sux runuser
# bg completes with stopped jobs
complete -A stopped -P '"%' -S '"' bg
@@ -310,7 +311,7 @@ __reassemble_comp_words_by_ref() {
ref="$2[$j]"
eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
# Indicate new cword
- [ $i = $COMP_CWORD ] && [[ ${COMP_WORDS[i]} ]] && eval $3=$j
+ [[ $i == $COMP_CWORD ]] && eval $3=$j
done
else
# No, list of word completions separators hasn't changed;
@@ -464,7 +465,7 @@ _get_cword()
# return previous word offset by $2
if [[ ${2//[^0-9]/} ]]; then
printf "%s" "${words[cword-$2]}"
- elif [[ "${#words[cword]}" -eq 0 ]] || [[ "$COMP_POINT" == "${#COMP_LINE}" ]]; then
+ elif [[ "${#words[cword]}" -eq 0 || "$COMP_POINT" == "${#COMP_LINE}" ]]; then
printf "%s" "${words[cword]}"
else
local i
@@ -568,16 +569,32 @@ __ltrim_colon_completions() {
# $ compgen -f "a\\\\\'b/" # Good (bash-3)
# a\'b/c
#
-# See also: http://lists.gnu.org/archive/html/bug-bash/2009-03/msg00155.html
+# On bash-3, special characters need to be escaped extra. This is
+# unless the first character is a single quote ('). If the single
+# quote appears further down the string, bash default completion also
+# fails, e.g.:
+#
+# $ ls 'a&b/'
+# f
+# $ foo 'a&b/<TAB> # Becomes: foo 'a&b/f'
+# $ foo a'&b/<TAB> # Nothing happens
+#
+# See also:
+# - http://lists.gnu.org/archive/html/bug-bash/2009-03/msg00155.html
+# - http://www.mail-archive.com/bash-completion-devel@lists.alioth.\
+# debian.org/msg01944.html
# @param $1 Argument to quote
# @param $2 Name of variable to return result to
_quote_readline_by_ref()
{
if [[ ${1:0:1} == "'" ]]; then
- # Quote word, leaving out first character
- printf -v $2 %q "${1:1}"
- if [[ ${BASH_VERSINFO[0]} -le 3 ]]; then
- # Double-quote word on bash-3
+ if [[ ${BASH_VERSINFO[0]} -ge 4 ]]; then
+ # Leave out first character
+ printf -v $2 %s "${1:1}"
+ else
+ # Quote word, leaving out first character
+ printf -v $2 %q "${1:1}"
+ # Double-quote word (bash-3)
printf -v $2 %q ${!2}
fi
elif [[ ${BASH_VERSINFO[0]} -le 3 && ${1:0:1} == '"' ]]; then
@@ -593,16 +610,30 @@ _quote_readline_by_ref()
} # _quote_readline_by_ref()
+# This function turns on "-o filenames" behavior dynamically. It is present
+# for bash < 4 reasons. See http://bugs.debian.org/272660#64 for info about
+# the bash < 4 compgen hack.
+_compopt_o_filenames()
+{
+ # We test for compopt availability first because directly invoking it on
+ # bash < 4 at this point may cause terminal echo to be turned off for some
+ # reason, see https://bugzilla.redhat.com/653669 for more info.
+ type compopt &>/dev/null && compopt -o filenames 2>/dev/null || \
+ compgen -f /non-existing-dir/ >/dev/null
+}
+
+
# This function performs file and directory completion. It's better than
# simply using 'compgen -f', because it honours spaces in filenames.
# @param $1 If `-d', complete only on directories. Otherwise filter/pick only
-# completions with `.$1' as file extension.
+# completions with `.$1' and the uppercase version of it as file
+# extension.
#
_filedir()
{
- local i IFS=$'\t\n' xspec
+ local i IFS=$'\n' xspec
- __expand_tilde_by_ref cur
+ _tilde "$cur" || return 0
local -a toks
local quoted tmp
@@ -621,68 +652,14 @@ _filedir()
}
))
- # On bash-3, special characters need to be escaped extra. This is
- # unless the first character is a single quote ('). If the single
- # quote appears further down the string, bash default completion also
- # fails, e.g.:
- #
- # $ ls 'a&b/'
- # f
- # $ foo 'a&b/<TAB> # Becomes: foo 'a&b/f'
- # $ foo a'&b/<TAB> # Nothing happens
- #
if [[ "$1" != -d ]]; then
- xspec=${1:+"!*.$1"}
- if [[ ${cur:0:1} == "'" && ${BASH_VERSINFO[0]} -ge 4 ]]; then
- toks=( ${toks[@]-} $(
- eval compgen -f -X \"\$xspec\" -- $quoted
- ) )
- else
- toks=( ${toks[@]-} $(
- compgen -f -X "$xspec" -- $quoted
- ) )
- fi
- if [ ${#toks[@]} -ne 0 ]; then
- # If `compopt' is available, set `-o filenames'
- compopt &>/dev/null && compopt -o filenames ||
- # No, `compopt' isn't available;
- # Is `-o filenames' set?
- [[ (
- ${COMP_WORDS[0]} &&
- "$(complete -p ${COMP_WORDS[0]})" == *"-o filenames"*
- ) ]] || {
- # No, `-o filenames' isn't set;
- # Emulate `-o filenames'
- # NOTE: A side-effect of emulating `-o filenames' is that
- # backslash escape characters are visible within the list
- # of presented completions, e.g. the completions look
- # like:
- #
- # $ foo a<TAB>
- # a\ b/ a\$b/
- #
- # whereas with `-o filenames' active the completions look
- # like:
- #
- # $ ls a<TAB>
- # a b/ a$b/
- #
- for ((i=0; i < ${#toks[@]}; i++)); do
- # If directory exists, append slash (/)
- if [[ ${cur:0:1} != "'" ]]; then
- [[ -d ${toks[i]} ]] && toks[i]="${toks[i]}"/
- if [[ ${cur:0:1} == '"' ]]; then
- toks[i]=${toks[i]//\\/\\\\}
- toks[i]=${toks[i]//\"/\\\"}
- toks[i]=${toks[i]//\$/\\\$}
- else
- toks[i]=$(printf %q ${toks[i]})
- fi
- fi
- done
- }
- fi
+ # Munge xspec to contain uppercase version too
+ [[ ${BASH_VERSINFO[0]} -ge 4 ]] && \
+ xspec=${1:+"!*.@($1|${1^^})"} || \
+ xspec=${1:+"!*.@($1|$(printf %s $1 | tr '[:lower:]' '[:upper:]'))"}
+ toks=( ${toks[@]-} $( compgen -f -X "$xspec" -- $quoted) )
fi
+ [ ${#toks[@]} -ne 0 ] && _compopt_o_filenames
COMPREPLY=( "${COMPREPLY[@]}" "${toks[@]}" )
} # _filedir()
@@ -705,13 +682,13 @@ _split_longopt()
return 1
}
-# This function tries to parse the output of $command --help
+# This function tries to parse the help output of the given command.
+# @param $1 command
+# @param $2 command options (default: --help)
#
_parse_help() {
- local cmd
- cmd=$1
- $cmd --help 2>&1 | command grep -- "^[[:space:]]*-" | tr "," " " | \
- awk '{print $1; if ($2 ~ /-.*/) { print $2 } }' | sed -e "s:=.*::g"
+ $1 ${2:---help} 2>&1 | sed -e '/^[[:space:]]*-/!d' -e 's|[,/]| |g' | \
+ awk '{ print $1; if ($2 ~ /^-/) { print $2 } }' | sed -e 's|[<=].*||'
}
# This function completes on signal names
@@ -746,6 +723,10 @@ _mac_addresses()
"s/.*[[:space:]]\($re\)[[:space:]].*/\1/p" -ne \
"s/.*[[:space:]]\($re\)[[:space:]]*$/\1/p" ) )
+ # /etc/ethers
+ COMPREPLY=( "${COMPREPLY[@]}" $( sed -ne \
+ "s/^[[:space:]]*\($re\)[[:space:]].*/\1/p" /etc/ethers 2>/dev/null ) )
+
COMPREPLY=( $( compgen -W '${COMPREPLY[@]}' -- "$cur" ) )
__ltrim_colon_completions "$cur"
}
@@ -805,7 +786,27 @@ _available_interfaces()
}
+# Perform tilde (~) completion
+# @return True (0) if completion needs further processing,
+# False (> 0) if tilde is followed by a valid username, completions
+# are put in COMPREPLY and no further processing is necessary.
+_tilde() {
+ local result=0
+ # Does $1 start with tilde (~) and doesn't contain slash (/)?
+ if [[ ${1:0:1} == "~" && $1 == ${1//\/} ]]; then
+ _compopt_o_filenames
+ # Try generate username completions
+ COMPREPLY=( $( compgen -P '~' -u "${1#\~}" ) )
+ result=${#COMPREPLY[@]}
+ fi
+ return $result
+}
+
+
# Expand variable starting with tilde (~)
+# We want to expand ~foo/... to /home/foo/... to avoid problems when
+# word-to-complete starting with a tilde is fed to commands and ending up
+# quoted instead of expanded.
# Only the first portion of the variable from the tilde up to the first slash
# (~../) is expanded. The remainder of the variable, containing for example
# a dollar sign variable ($) or asterisk (*) is not expanded.
@@ -834,7 +835,7 @@ __expand_tilde_by_ref() {
# becomes "~a". Double quotes allow eval.
# 2: Remove * before the first slash (/), i.e. "~a/b"
# becomes "b". Single quotes prevent eval.
- # +-----1----+ +---2----+
+ # +-----1----+ +---2----+
eval $1="${!1/%\/*}"/'${!1#*/}'
else
# No, $1 doesn't contain slash
@@ -982,10 +983,10 @@ _installed_modules()
# The : must be added manually; it will only complete usernames initially.
# The legacy user.group format is not supported.
#
-# It assumes compopt -o filenames; but doesn't touch it.
+# @param $1 If -u, only return users/groups the user has access to in
+# context of current completion.
_usergroup()
{
- local IFS=$'\n'
if [[ $cur = *\\\\* || $cur = *:*:* ]]; then
# Give up early on if something seems horribly wrong.
return
@@ -996,19 +997,61 @@ _usergroup()
local prefix
prefix=${cur%%*([^:])}
prefix=${prefix//\\}
- COMPREPLY=( $( compgen -P "$prefix" -g -- "${cur#*[:]}" ) )
+ local mycur="${cur#*[:]}"
+ if [[ $1 == -u ]]; then
+ _allowed_groups "$mycur"
+ else
+ local IFS=$'\n'
+ COMPREPLY=( $( compgen -g -- "$mycur" ) )
+ fi
+ COMPREPLY=( $( compgen -P "$prefix" -W "${COMPREPLY[@]}" ) )
elif [[ $cur = *:* ]]; then
# Completing group after 'user:gr<TAB>'.
# Reply with a list of unprefixed groups since readline with split on :
# and only replace the 'gr' part
- COMPREPLY=( $( compgen -g -- "${cur#*:}" ) )
+ local mycur="${cur#*:}"
+ if [[ $1 == -u ]]; then
+ _allowed_groups "$mycur"
+ else
+ local IFS=$'\n'
+ COMPREPLY=( $( compgen -g -- "$mycur" ) )
+ fi
else
# Completing a partial 'usernam<TAB>'.
#
# Don't suffix with a : because readline will escape it and add a
# slash. It's better to complete into 'chown username ' than 'chown
# username\:'.
- COMPREPLY=( $( compgen -u -- "$cur" ) )
+ if [[ $1 == -u ]]; then
+ _allowed_users "$cur"
+ else
+ local IFS=$'\n'
+ COMPREPLY=( $( compgen -u -- "$cur" ) )
+ fi
+ fi
+}
+
+_allowed_users()
+{
+ if _complete_as_root; then
+ local IFS=$'\n'
+ COMPREPLY=( $( compgen -u -- "${1:-$cur}" ) )
+ else
+ local IFS=$'\n '
+ COMPREPLY=( $( compgen -W \
+ "$( id -un 2>/dev/null || whoami 2>/dev/null )" -- "${1:-$cur}" ) )
+ fi
+}
+
+_allowed_groups()
+{
+ if _complete_as_root; then
+ local IFS=$'\n'
+ COMPREPLY=( $( compgen -g -- "$1" ) )
+ else
+ local IFS=$'\n '
+ COMPREPLY=( $( compgen -W \
+ "$( id -Gn 2>/dev/null || groups 2>/dev/null )" -- "$1" ) )
fi
}
@@ -1164,7 +1207,8 @@ _known_hosts()
# Helper function for completing _known_hosts.
# This function performs host completion based on ssh's config and known_hosts
-# files, as well as hostnames reported by avahi-browse. Also hosts from
+# files, as well as hostnames reported by avahi-browse if
+# COMP_KNOWN_HOSTS_WITH_AVAHI is set to a non-empty value. Also hosts from
# HOSTFILE (compgen -A hostname) are added, unless
# COMP_KNOWN_HOSTS_WITH_HOSTFILE is set to an empty value.
# Usage: _known_hosts_real [OPTIONS] CWORD
@@ -1201,12 +1245,10 @@ _known_hosts_real()
[ -r "$configfile" ] &&
config=( "${config[@]}" "$configfile" )
else
- [ -r /etc/ssh/ssh_config ] &&
- config=( "${config[@]}" "/etc/ssh/ssh_config" )
- [ -r "${HOME}/.ssh/config" ] &&
- config=( "${config[@]}" "${HOME}/.ssh/config" )
- [ -r "${HOME}/.ssh2/config" ] &&
- config=( "${config[@]}" "${HOME}/.ssh2/config" )
+ for i in /etc/ssh/ssh_config "${HOME}/.ssh/config" \
+ "${HOME}/.ssh2/config"; do
+ [ -r $i ] && config=( "${config[@]}" "$i" )
+ done
fi
# Known hosts files from configs
@@ -1228,28 +1270,16 @@ _known_hosts_real()
IFS=$OIFS
fi
- # Global known_hosts files
- if [ -z "$configfile" ]; then
- [ -r /etc/ssh/ssh_known_hosts ] &&
- kh=( "${kh[@]}" /etc/ssh/ssh_known_hosts )
- [ -r /etc/ssh/ssh_known_hosts2 ] &&
- kh=( "${kh[@]}" /etc/ssh/ssh_known_hosts2 )
- [ -r /etc/known_hosts ] &&
- kh=( "${kh[@]}" /etc/known_hosts )
- [ -r /etc/known_hosts2 ] &&
- kh=( "${kh[@]}" /etc/known_hosts2 )
- [ -d /etc/ssh2/knownhosts ] &&
- khd=( "${khd[@]}" /etc/ssh2/knownhosts/*pub )
- fi
-
- # User known_hosts files
if [ -z "$configfile" ]; then
- [ -r ~/.ssh/known_hosts ] &&
- kh=( "${kh[@]}" ~/.ssh/known_hosts )
- [ -r ~/.ssh/known_hosts2 ] &&
- kh=( "${kh[@]}" ~/.ssh/known_hosts2 )
- [ -d ~/.ssh2/hostkeys ] &&
- khd=( "${khd[@]}" ~/.ssh2/hostkeys/*pub )
+ # 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=( "${kh[@]}" $i )
+ done
+ for i in /etc/ssh2/knownhosts ~/.ssh2/hostkeys; do
+ [ -d $i ] && khd=( "${khd[@]}" $i/*pub )
+ done
fi
# If we have known_hosts files to use
@@ -1259,16 +1289,16 @@ _known_hosts_real()
awkcur=${awkcur//\./\\\.}
curd=$awkcur
- if [[ "$awkcur" == [0-9]*.* ]]; then
- # Digits followed by a dot - just search for that
- awkcur="^$awkcur.*"
+ if [[ "$awkcur" == [0-9]*[.:]* ]]; then
+ # Digits followed by a dot or a colon - just search for that
+ awkcur="^$awkcur[.:]*"
elif [[ "$awkcur" == [0-9]* ]]; then
- # Digits followed by no dot - search for digits followed
- # by a dot
- awkcur="^$awkcur.*\."
+ # Digits followed by no dot or colon - search for digits followed
+ # by a dot or a colon
+ awkcur="^$awkcur.*[.:]"
elif [ -z "$awkcur" ]; then
- # A blank - search for a dot or an alpha character
- awkcur="[a-z.]"
+ # A blank - search for a dot, a colon, or an alpha character
+ awkcur="[a-z.:]"
else
awkcur="^$awkcur"
fi
@@ -1277,9 +1307,8 @@ _known_hosts_real()
# FS needs to look for a comma separated list
COMPREPLY=( "${COMPREPLY[@]}" $( awk 'BEGIN {FS=","}
/^\s*[^|\#]/ {for (i=1; i<=2; ++i) { \
- gsub(" .*$", "", $i); \
- gsub("[\\[\\]]", "", $i); \
- gsub(":[0-9]+$", "", $i); \
+ sub(" .*$", "", $i); \
+ sub("^\\[", "", $i); sub("\\](:[0-9]+)?$", "", $i); \
if ($i ~ /'"$awkcur"'/) {print $i} \
}}' "${kh[@]}" 2>/dev/null ) )
fi
@@ -1310,12 +1339,14 @@ _known_hosts_real()
-S "$suffix" -W "$hosts" -- "$cur" ) )
fi
- # Add hosts reported by avahi-browse, if it's available.
- # The original call to avahi-browse also had "-k", to avoid lookups into
- # avahi's services DB. We don't need the name of the service, and if it
- # contains ";", it may mistify the result. But on Gentoo (at least),
- # -k isn't available (even if mentioned in the manpage), so...
- if type avahi-browse >&/dev/null; then
+ # Add hosts reported by avahi-browse, if desired and it's available.
+ if [[ ${COMP_KNOWN_HOSTS_WITH_AVAHI:-} ]] && \
+ type avahi-browse &>/dev/null; then
+ # The original call to avahi-browse also had "-k", to avoid lookups
+ # into avahi's services DB. We don't need the name of the service, and
+ # if it contains ";", it may mistify the result. But on Gentoo (at
+ # least), -k wasn't available (even if mentioned in the manpage) some
+ # time ago, so...
COMPREPLY=( "${COMPREPLY[@]}" $( \
compgen -P "$prefix$user" -S "$suffix" -W \
"$( avahi-browse -cpr _workstation._tcp 2>/dev/null | \
@@ -1342,7 +1373,7 @@ complete -F _known_hosts traceroute traceroute6 tracepath tracepath6 ping \
#
_cd()
{
- local cur IFS=$'\t\n' i j k
+ local cur IFS=$'\n' i j k
_get_comp_words_by_ref cur
# try to allow variable completion
@@ -1351,8 +1382,7 @@ _cd()
return 0
fi
- # Enable -o filenames option, see Debian bug #272660
- compgen -f /non-existing-dir/ >/dev/null
+ _compopt_o_filenames
# Use standard dir completion if no CDPATH or parameter starts with /,
# ./ or ../
@@ -1365,7 +1395,7 @@ _cd()
local -r mark_symdirs=$(_rl_enabled mark-symlinked-directories && echo y)
# we have a CDPATH, so loop on its contents
- for i in ${CDPATH//:/$'\t'}; do
+ for i in ${CDPATH//:/$'\n'}; do
# create an array of matched subdirs
k="${#COMPREPLY[@]}"
for j in $( compgen -d $i/$cur ); do
@@ -1449,11 +1479,12 @@ _command_offset()
_get_comp_words_by_ref cur
if [[ $COMP_CWORD -eq 0 ]]; then
+ _compopt_o_filenames
COMPREPLY=( $( compgen -c -- "$cur" ) )
else
cmd=${COMP_WORDS[0]}
- if complete -p $cmd &>/dev/null; then
- cspec=$( complete -p $cmd )
+ if complete -p ${cmd##*/} &>/dev/null; then
+ cspec=$( complete -p ${cmd##*/} )
if [ "${cspec#* -F }" != "$cspec" ]; then
# complete -F <function>
@@ -1475,68 +1506,74 @@ _command_offset()
cspec=${cspec%% *}
if [[ "$cspec" != @(dir|file)names ]]; then
COMPREPLY=("${COMPREPLY[@]//\\\\:/:}")
+ else
+ _compopt_o_filenames
fi
fi
elif [ -n "$cspec" ]; then
cspec=${cspec#complete};
- cspec=${cspec%%$cmd};
+ cspec=${cspec%%${cmd##*/}};
COMPREPLY=( $( eval compgen "$cspec" -- "$cur" ) );
fi
+ elif [ ${#COMPREPLY[@]} -eq 0 ]; then
+ _filedir
fi
fi
-
- [ ${#COMPREPLY[@]} -eq 0 ] && _filedir
}
-complete -F _command -o filenames nohup exec nice eval time ltrace then \
- else do vsound command xargs tsocks aoss padsp
+complete -F _command aoss command do else eval exec ltrace nice nohup padsp \
+ then time tsocks vsound xargs
_root_command()
{
local PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin
+ local root_command=$1
_command $1 $2 $3
}
-complete -F _root_command -o filenames sudo fakeroot really gksudo gksu kdesudo
+complete -F _root_command fakeroot gksu gksudo kdesudo really sudo
+
+# Return true if the completion should be treated as running as root
+_complete_as_root()
+{
+ [[ $EUID -eq 0 || ${root_command:-} ]]
+}
_longopt()
{
- local cur prev
+ local cur prev split=false
+ _get_comp_words_by_ref -n = cur prev
- _get_comp_words_by_ref cur prev
+ _split_longopt && split=true
- if _split_longopt; then
- case "$prev" in
- *[Dd][Ii][Rr]*)
- _filedir -d
- ;;
- *[Ff][Ii][Ll][Ee]*)
- _filedir
- ;;
- esac
- return 0
- fi
+ case "$prev" in
+ --*[Dd][Ii][Rr]*)
+ _filedir -d
+ return 0
+ ;;
+ --*[Ff][Ii][Ll][Ee]*|--*[Pp][Aa][Tt][Hh]*)
+ _filedir
+ return 0
+ ;;
+ esac
+
+ $split && return 0
if [[ "$cur" == -* ]]; then
COMPREPLY=( $( compgen -W "$( $1 --help 2>&1 | \
sed -ne 's/.*\(--[-A-Za-z0-9]\{1,\}\).*/\1/p' | sort -u )" \
-- "$cur" ) )
- elif [[ "$1" == rmdir ]]; then
+ elif [[ "$1" == @(mk|rm)dir ]]; then
_filedir -d
else
_filedir
fi
}
# makeinfo and texi2dvi are defined elsewhere.
-for i in a2ps autoconf automake bc gprof ld nm objcopy objdump readelf strip \
- bison colordiff diff patch enscript cp df dir du ln ls mkfifo mknod mv rm \
- touch vdir awk gperf grep grub indent less m4 sed shar date \
- tee who texindex cat csplit cut expand fmt fold head \
- md5sum nl od paste pr ptx sha1sum sort split tac tail tr unexpand \
- uniq wc ldd bash id irb mkdir rmdir wget curl; do
- have $i && complete -F _longopt -o filenames $i
-done
-
-# These commands do not use filenames, so '-o filenames' is not needed.
-for i in env netstat seq uname units; do
+for i in a2ps awk bash bc bison cat colordiff cp csplit \
+ curl cut date df diff dir du enscript env expand fmt fold gperf gprof \
+ grep grub head indent irb ld ldd less ln ls m4 md5sum mkdir mkfifo mknod \
+ mv netstat nl nm objcopy objdump od paste patch pr ptx readelf rm rmdir \
+ sed seq sha{,1,224,256,384,512}sum shar sort split strip tac tail tee \
+ texindex touch tr uname unexpand uniq units vdir wc wget who; do
have $i && complete -F _longopt -o default $i
done
unset i
@@ -1545,7 +1582,7 @@ _filedir_xspec()
{
local IFS cur xspec
- IFS=$'\t\n'
+ IFS=$'\n'
COMPREPLY=()
_get_comp_words_by_ref cur
@@ -1570,14 +1607,26 @@ _filedir_xspec()
}
))
+ # Munge xspec to contain uppercase version too
+ eval xspec="${xspec}"
+ local matchop=!
+ if [[ $xspec == !* ]]; then
+ xspec=${xspec#!}
+ matchop=@
+ fi
+ [[ ${BASH_VERSINFO[0]} -ge 4 ]] && \
+ xspec="$matchop($xspec|${xspec^^})" || \
+ xspec="$matchop($xspec|$(printf %s $xspec | tr '[:lower:]' '[:upper:]'))"
+
toks=( ${toks[@]-} $(
- eval compgen -f -X "$xspec" -- "\$(quote_readline "\$cur")" | {
+ eval compgen -f -X "!$xspec" -- "\$(quote_readline "\$cur")" | {
while read -r tmp; do
[ -n $tmp ] && printf '%s\n' $tmp
done
}
))
+ [ ${#toks[@]} -ne 0 ] && _compopt_o_filenames
COMPREPLY=( "${toks[@]}" )
}
list=( $( sed -ne '/^# START exclude/,/^# FINISH exclude/p' "$BASH_COMPLETION" | \
@@ -1599,7 +1648,7 @@ list=( $( sed -ne '/^# START exclude/,/^# FINISH exclude/p' "$BASH_COMPLETION" |
if [ ${#list[@]} -gt 0 ]; then
eval complete -r ${list[@]}
# install new compspecs
- eval complete -F _filedir_xspec -o filenames "${list[@]}"
+ eval complete -F _filedir_xspec "${list[@]}"
fi
unset list
@@ -1608,8 +1657,8 @@ if [[ -d $BASH_COMPLETION_COMPAT_DIR && -r $BASH_COMPLETION_COMPAT_DIR && \
-x $BASH_COMPLETION_COMPAT_DIR ]]; then
for i in $(LC_ALL=C command ls "$BASH_COMPLETION_COMPAT_DIR"); do
i=$BASH_COMPLETION_COMPAT_DIR/$i
- [[ ${i##*/} != @(*~|*.bak|*.swp|\#*\#|*.dpkg*|*.rpm@(orig|new|save)) \
- && ( -f $i || -h $i ) && -r $i ]] && . "$i"
+ [[ ${i##*/} != @(*~|*.bak|*.swp|\#*\#|*.dpkg*|*.rpm@(orig|new|save)|Makefile*) \
+ && -f $i && -r $i ]] && . "$i"
done
fi
if [[ $BASH_COMPLETION_DIR != $BASH_COMPLETION_COMPAT_DIR && \
@@ -1617,8 +1666,8 @@ if [[ $BASH_COMPLETION_DIR != $BASH_COMPLETION_COMPAT_DIR && \
-x $BASH_COMPLETION_DIR ]]; then
for i in $(LC_ALL=C command ls "$BASH_COMPLETION_DIR"); do
i=$BASH_COMPLETION_DIR/$i
- [[ ${i##*/} != @(*~|*.bak|*.swp|\#*\#|*.dpkg*|*.rpm@(orig|new|save)) \
- && ( -f $i || -h $i ) && -r $i ]] && . "$i"
+ [[ ${i##*/} != @(*~|*.bak|*.swp|\#*\#|*.dpkg*|*.rpm@(orig|new|save)|Makefile*) \
+ && -f $i && -r $i ]] && . "$i"
done
fi
unset i